Skip to content

Commit 7f70ca2

Browse files
authored
Add black formatter (#10)
* improve database setup & tests * improve session manager & tests * improve integration tests * add type checking for session manager database uri * adjust readme * python3.9 compliant types * add postgres integration tests * cleanup * extend readme * integration test setup in workflow * adjust stuff * add black formatter * configure black as default formatter for vscode * remove unused dev dependencies
1 parent 5a38d96 commit 7f70ca2

File tree

10 files changed

+150
-43
lines changed

10 files changed

+150
-43
lines changed

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@
33
"."
44
],
55
"python.testing.unittestEnabled": false,
6-
"python.testing.pytestEnabled": true
6+
"python.testing.pytestEnabled": true,
7+
"[python]": {
8+
"editor.defaultFormatter": "ms-python.black-formatter"
9+
}
710
}

database_setup_tools/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__='1.0.1'
1+
__version__ = "1.0.1"
22

33
from .session_manager import SessionManager
44
from .setup import DatabaseSetup

database_setup_tools/session_manager.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010

1111
class SessionManager:
12-
""" Manages engines, sessions and connection pools. Thread-safe singleton """
12+
"""Manages engines, sessions and connection pools. Thread-safe singleton"""
13+
1314
_instances = []
1415
_lock = threading.Lock()
1516

@@ -21,7 +22,7 @@ def __new__(cls, *args, **kwargs):
2122
return cls._get_cached_instance(args, kwargs)
2223

2324
def __init__(self, database_uri: str, **kwargs):
24-
""" Session Manager constructor
25+
"""Session Manager constructor
2526
2627
Args:
2728
database_uri (str): The URI of the database to manage sessions for
@@ -44,26 +45,26 @@ def __init__(self, database_uri: str, **kwargs):
4445

4546
@cached_property
4647
def database_uri(self) -> str:
47-
""" Getter for the database URI """
48+
"""Getter for the database URI"""
4849
return self._database_uri
4950

5051
@property
5152
def engine(self) -> Engine:
52-
""" Getter for the engine """
53+
"""Getter for the engine"""
5354
return self._engine
5455

5556
def get_session(self) -> Generator[Session, None, None]:
56-
""" Provides a (thread safe) scoped session that is wrapped in a context manager """
57+
"""Provides a (thread safe) scoped session that is wrapped in a context manager"""
5758
with self._Session() as session:
5859
yield session
5960

6061
def _get_engine(self, **kwargs) -> Engine:
61-
""" Provides a database engine """
62+
"""Provides a database engine"""
6263
return create_engine(self.database_uri, **kwargs)
6364

6465
@classmethod
6566
def _get_cached_instance(cls, args: tuple, kwargs: dict) -> Optional[object]:
66-
""" Provides a cached instance of the SessionManager class if existing """
67+
"""Provides a cached instance of the SessionManager class if existing"""
6768
for instance, arguments in cls._instances:
6869
if arguments == (args, kwargs):
6970
return instance

database_setup_tools/setup.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99

1010
class DatabaseSetup:
11-
""" Create the database and the tables if not done yet """
11+
"""Create the database and the tables if not done yet"""
12+
1213
_instances = []
1314
_lock = threading.Lock()
1415

@@ -20,7 +21,7 @@ def __new__(cls, *args, **kwargs):
2021
return cls._get_cached_instance(args, kwargs)
2122

2223
def __init__(self, model_metadata: MetaData, database_uri: str):
23-
""" Set up a database based on its URI and metadata. Will not overwrite existing data.
24+
"""Set up a database based on its URI and metadata. Will not overwrite existing data.
2425
2526
Args:
2627
model_metadata (Metadata): The metadata of the models to create the tables for
@@ -39,7 +40,7 @@ def __init__(self, model_metadata: MetaData, database_uri: str):
3940

4041
@property
4142
def model_metadata(self) -> MetaData:
42-
""" Getter for the model metadata
43+
"""Getter for the model metadata
4344
4445
Returns:
4546
MetaData: The model metadata
@@ -48,15 +49,15 @@ def model_metadata(self) -> MetaData:
4849

4950
@property
5051
def database_uri(self) -> str:
51-
""" Getter for the database URI
52+
"""Getter for the database URI
5253
5354
Returns:
5455
str: The database URI
5556
"""
5657
return self._database_uri
5758

5859
def drop_database(self) -> bool:
59-
""" Drop the database and the tables if possible
60+
"""Drop the database and the tables if possible
6061
6162
Returns:
6263
bool: True if the database was dropped, False otherwise
@@ -67,7 +68,7 @@ def drop_database(self) -> bool:
6768
return False
6869

6970
def create_database(self) -> bool:
70-
""" Create the database and the tables if not done yet """
71+
"""Create the database and the tables if not done yet"""
7172
if not sqlalchemy_utils.database_exists(self.database_uri):
7273
sqlalchemy_utils.create_database(self.database_uri)
7374
session_manager = SessionManager(self.database_uri)
@@ -77,7 +78,7 @@ def create_database(self) -> bool:
7778

7879
@classmethod
7980
def _get_cached_instance(cls, args: tuple, kwargs: dict) -> Optional[object]:
80-
""" Provides a cached instance of the SessionManager class if existing """
81+
"""Provides a cached instance of the SessionManager class if existing"""
8182
for instance, arguments in cls._instances:
8283
if arguments == (args, kwargs):
8384
return instance

poetry.lock

Lines changed: 106 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ sqlalchemy = "^1.4.41"
1313
sqlalchemy-utils = "^0.38.3"
1414

1515
[tool.poetry.dev-dependencies]
16+
black = "23.1.0"
1617
sqlmodel = "0.0.8"
1718
psycopg2-binary = "^2.9.5"
1819
pytest-cov = "^4.0.0"
@@ -27,3 +28,7 @@ build-backend = "poetry.core.masonry.api"
2728

2829
[tool.pytest.ini_options]
2930
addopts = "-x -p no:warnings --cov-report=term --cov-report=term-missing --no-cov-on-fail --cov=database_setup_tools"
31+
32+
[tool.black]
33+
line-length = 180
34+
target-version = ['py311']

tests/integration/test_database_integration.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@
1010
from tests.sample_model import User, model_metadata
1111

1212

13-
@pytest.mark.parametrize('database_uri', DATABASE_URIS)
13+
@pytest.mark.parametrize("database_uri", DATABASE_URIS)
1414
class TestDatabaseIntegration:
15-
1615
@pytest.fixture
1716
def database_setup(self, database_uri: str) -> DatabaseSetup:
1817
setup = DatabaseSetup(model_metadata=model_metadata, database_uri=database_uri)
@@ -21,28 +20,28 @@ def database_setup(self, database_uri: str) -> DatabaseSetup:
2120

2221
@pytest.fixture
2322
def database_session(self, database_uri: str) -> Iterator[ScopedSession]:
24-
""" Get a database session """
23+
"""Get a database session"""
2524
session_manager = SessionManager(database_uri)
2625
return next(session_manager.get_session())
2726

2827
def test_create_database_and_tables(self, database_setup: DatabaseSetup, database_session: ScopedSession):
29-
""" Test that the tables are created correctly """
28+
"""Test that the tables are created correctly"""
3029
# noinspection SqlInjection,SqlDialectInspection
31-
database_session.execute(f'SELECT * FROM {User.__tablename__}')
30+
database_session.execute(f"SELECT * FROM {User.__tablename__}")
3231

3332
def test_create_database_multiple_times(self, database_setup: DatabaseSetup, database_session: ScopedSession):
34-
""" Test that creating the database multiple times does not cause problems """
33+
"""Test that creating the database multiple times does not cause problems"""
3534
database_setup.create_database()
3635
# noinspection SqlInjection,SqlDialectInspection
37-
database_session.execute(f'SELECT * FROM {User.__tablename__}')
36+
database_session.execute(f"SELECT * FROM {User.__tablename__}")
3837

3938
def test_drop_database(self, database_setup: DatabaseSetup, database_session: ScopedSession):
40-
""" Test that the database is dropped correctly """
39+
"""Test that the database is dropped correctly"""
4140
database_setup.create_database()
4241
assert database_setup.drop_database() is True
4342

4443
with pytest.raises(OperationalError):
4544
# noinspection SqlDialectInspection
46-
database_session.execute(f'SELECT * FROM {User.__tablename__}')
45+
database_session.execute(f"SELECT * FROM {User.__tablename__}")
4746

4847
assert database_setup.drop_database() is False

tests/sample_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
class User(SQLModel, table=True):
5-
""" User model """
5+
"""User model"""
66

77
id: int = Field(index=True, primary_key=True)
88
name: str

tests/unit/test_session_manager.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@
88

99

1010
class TestSessionManager:
11-
1211
@pytest.fixture
1312
def database_uri(self) -> str:
14-
return 'sqlite://'
13+
return "sqlite://"
1514

1615
@pytest.fixture
1716
def session_manager(self, database_uri: str) -> SessionManager:
1817
yield SessionManager(database_uri=database_uri)
1918

20-
@pytest.mark.parametrize('invalid_database_uri', [None, (), 42, False])
19+
@pytest.mark.parametrize("invalid_database_uri", [None, (), 42, False])
2120
def test_create_session_manager_fail_invalid_database_uri_type(self, invalid_database_uri: Any):
2221
with pytest.raises(TypeError):
2322
SessionManager(database_uri=invalid_database_uri)
@@ -27,16 +26,13 @@ def test_session_manager_is_singleton_with_same_arguments(self, database_uri: st
2726
assert SessionManager(database_uri=database_uri) is SessionManager(database_uri=database_uri)
2827

2928
def test_session_manager_singletons_with_different_arguments(self):
30-
database_uri_1, database_uri_2 = 'sqlite://', 'postgresql://'
29+
database_uri_1, database_uri_2 = "sqlite://", "postgresql://"
3130
assert SessionManager(database_uri=database_uri_1) is not SessionManager(database_uri=database_uri_2)
3231

3332
def test_database_uri(self, session_manager: SessionManager, database_uri: str):
3433
assert session_manager.database_uri == database_uri
3534

36-
@pytest.mark.parametrize('database_uri, name, driver', [
37-
('sqlite://', 'sqlite', 'pysqlite'),
38-
('postgresql+psycopg2://', 'postgresql', 'psycopg2')
39-
])
35+
@pytest.mark.parametrize("database_uri, name, driver", [("sqlite://", "sqlite", "pysqlite"), ("postgresql+psycopg2://", "postgresql", "psycopg2")])
4036
def test_engine(self, database_uri: str, name: str, driver: str):
4137
session_manager = SessionManager(database_uri)
4238
assert isinstance(session_manager.engine, Engine)

0 commit comments

Comments
 (0)