Skip to content

Commit 882beb8

Browse files
(clean) strict project.toml, cleaned pylint issues and refactored and clean code
1 parent 504fd6a commit 882beb8

18 files changed

Lines changed: 411 additions & 135 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ __pycache__/
99
.ruff_cache
1010
.coverage
1111
.vscode/
12-
.hypothesis/
12+
.hypothesis/
13+
.venv/

.pre-commit-config.yaml

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ repos:
44
- id: resolver-unit-tests
55
name: Resolver unit tests
66
language: system
7-
entry: bash -lc 'python -m pytest -q'
7+
entry: >-
8+
bash -lc 'R="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")";
9+
cd "$R" || exit 1;
10+
P=""; for c in "$PWD/.venv/bin/python" "$PWD/venv/bin/python" "$(command -v python3)" "$(command -v python)"; do
11+
[[ -n "$c" && -x "$c" ]] || continue;
12+
"$c" -c "import pytest" 2>/dev/null && { P="$c"; break; }; done;
13+
[[ -n "$P" ]] || { echo "error: no Python with pytest; use .venv and pip install -e .[dev]" >&2; exit 1; };
14+
"$P" -m pytest -q'
815
pass_filenames: false
916
files: \.py$
1017
exclude: (^|/)tests/
@@ -14,13 +21,14 @@ repos:
1421
name: Resolver mypy
1522
language: system
1623
entry: >-
17-
bash -lc 'APP_ENV=development
18-
ENVIRONMENT=development
19-
RESOLVER_DATABASE_URL=postgresql://ci_user:ci_password_123@localhost:5432/resolver
20-
RESOLVER_EXPECTED_SERVICE_TOKEN=ci_resolver_expected_service_token_123456789
21-
RESOLVER_CONTEXT_VERIFY_KEY=ci_resolver_context_verify_key_12345678901234567890
22-
PYTHONPATH=$PWD
23-
mypy --config-file "$PWD/pyproject.toml" "$@"' --
24+
bash -lc 'R="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")";
25+
cd "$R" || exit 1;
26+
P=""; for c in "$PWD/.venv/bin/python" "$PWD/venv/bin/python" "$(command -v python3)" "$(command -v python)"; do
27+
[[ -n "$c" && -x "$c" ]] || continue;
28+
"$c" -c "import mypy, numpy, sqlalchemy, pydantic, httpx" 2>/dev/null && { P="$c"; break; }; done;
29+
[[ -n "$P" ]] || { echo "error: no Python with mypy + resolver deps; pip install -e .[dev] in resolver/" >&2; exit 1; };
30+
APP_ENV=development ENVIRONMENT=development RESOLVER_DATABASE_URL=postgresql://ci_user:ci_password_123@localhost:5432/resolver RESOLVER_EXPECTED_SERVICE_TOKEN=ci_resolver_expected_service_token_123456789 RESOLVER_CONTEXT_VERIFY_KEY=ci_resolver_context_verify_key_12345678901234567890 PYTHONPATH="$PWD" "$P" -m mypy --python-executable "$P" --cache-dir /tmp/resolver-mypy-cache --config-file "$PWD/pyproject.toml" .'
31+
pass_filenames: false
2432
files: \.py$
2533
exclude: (^|/)tests/
2634
types: [python]
@@ -29,13 +37,14 @@ repos:
2937
name: Resolver pylint
3038
language: system
3139
entry: >-
32-
bash -lc 'APP_ENV=development
33-
ENVIRONMENT=development
34-
RESOLVER_DATABASE_URL=postgresql://ci_user:ci_password_123@localhost:5432/resolver
35-
RESOLVER_EXPECTED_SERVICE_TOKEN=ci_resolver_expected_service_token_123456789
36-
RESOLVER_CONTEXT_VERIFY_KEY=ci_resolver_context_verify_key_12345678901234567890
37-
PYTHONPATH=$PWD
38-
pylint --rcfile "$PWD/pyproject.toml" "$@"' --
40+
bash -lc 'R="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")";
41+
cd "$R" || exit 1;
42+
P=""; for c in "$PWD/.venv/bin/python" "$PWD/venv/bin/python" "$(command -v python3)" "$(command -v python)"; do
43+
[[ -n "$c" && -x "$c" ]] || continue;
44+
"$c" -c "import pylint, numpy, sqlalchemy, pydantic, httpx" 2>/dev/null && { P="$c"; break; }; done;
45+
[[ -n "$P" ]] || { echo "error: no Python with pylint + resolver deps; pip install -e .[dev] in resolver/" >&2; exit 1; };
46+
APP_ENV=development ENVIRONMENT=development RESOLVER_DATABASE_URL=postgresql://ci_user:ci_password_123@localhost:5432/resolver RESOLVER_EXPECTED_SERVICE_TOKEN=ci_resolver_expected_service_token_123456789 RESOLVER_CONTEXT_VERIFY_KEY=ci_resolver_context_verify_key_12345678901234567890 PYTHONPATH="$PWD" "$P" -m pylint --rcfile "$PWD/pyproject.toml" .'
47+
pass_filenames: false
3948
files: \.py$
4049
exclude: (^|/)tests/
4150
types: [python]

database.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import re
1515
import logging
1616
from contextlib import contextmanager
17-
from typing import Callable, Iterator, Optional
17+
from typing import Iterator, Optional, Protocol
1818

1919
from sqlalchemy import create_engine, text
2020
from sqlalchemy.exc import SQLAlchemyError
@@ -25,8 +25,18 @@
2525
from db_models import Base
2626

2727
logger = logging.getLogger(__name__)
28+
29+
30+
class _SessionFactory(Protocol):
31+
def __call__(self) -> Session: ...
32+
33+
34+
def _new_session(factory: _SessionFactory) -> Session:
35+
return factory()
36+
37+
2838
_ENGINE: Optional[Engine] = None
29-
_SESSION_FACTORY: Optional[Callable[[], Session]] = None
39+
_SESSION_FACTORY: Optional[_SessionFactory] = None
3040

3141

3242
def _ensure_postgres_database_exists(database_url: str) -> None:
@@ -68,19 +78,23 @@ def init_database(database_url: str) -> None:
6878
pool_timeout=int(os.getenv("RESOLVER_DB_POOL_TIMEOUT", "30")),
6979
pool_recycle=int(os.getenv("RESOLVER_DB_POOL_RECYCLE", "1800")),
7080
)
71-
session_factory = sessionmaker(bind=engine, autoflush=False, expire_on_commit=False)
81+
factory = sessionmaker(bind=engine, autoflush=False, expire_on_commit=False)
7282
globals()["_ENGINE"] = engine
73-
globals()["_SESSION_FACTORY"] = session_factory
83+
globals()["_SESSION_FACTORY"] = factory
84+
85+
86+
def _require_session_factory() -> _SessionFactory:
87+
factory = _SESSION_FACTORY
88+
if factory is None or not callable(factory):
89+
raise RuntimeError("Database not initialized")
90+
return factory
7491

7592

7693
@contextmanager
7794
def get_db_session() -> Iterator[Session]:
78-
if _ENGINE is None or _SESSION_FACTORY is None:
79-
raise RuntimeError("Database not initialized")
80-
session_factory = _SESSION_FACTORY
81-
if not callable(session_factory):
95+
if _ENGINE is None:
8296
raise RuntimeError("Database not initialized")
83-
session = session_factory()
97+
session = _new_session(_require_session_factory())
8498
try:
8599
yield session
86100
session.commit()

0 commit comments

Comments
 (0)