csrd-utils 0.3.10__tar.gz → 0.3.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/PKG-INFO +1 -1
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/pyproject.toml +1 -1
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/__main__.py +10 -3
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/cluster.py +2 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/hooks/post_gen_project.py +7 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/README.md +11 -0
- csrd_utils-0.3.12/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/acceptance/test_logging_middleware.py +7 -0
- csrd_utils-0.3.12/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/unit/test_cache.py +9 -0
- csrd_utils-0.3.12/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/unit/test_database_settings.py +8 -0
- csrd_utils-0.3.12/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/unit/test_delegates.py +17 -0
- csrd_utils-0.3.12/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/unit/test_worker_broker.py +8 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/.gitignore +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/README.md +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/augmentor.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/doctor.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/conftest.fragment.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/docker-compose.fragment.yaml +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/manifest.yaml +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/requirements.fragment +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/settings.fragment.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/src/app/workers/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/src/app/workers/celery_app.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/src/app/workers/tasks.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/tests/test_workers.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/fragments.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/generator.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/resources.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/README.md +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/cookiecutter.json +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/.dockerignore +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/.env.example +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/Dockerfile +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/docker-compose.yml +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/requirements.txt +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/cache.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/delegates/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/delegates/upstreams.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/dependencies/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/dependencies/delegates.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/dependencies/item_repository.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/dependencies/worker_broker.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/middleware/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/middleware/logging.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/repositories/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/repositories/item_repository.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/settings.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/views/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/views/unversioned/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/views/unversioned/health_view.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/views/unversioned/items_view.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/workers/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/workers/tasks.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/__init__.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/conftest.py +0 -0
- {csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/test_items.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csrd-utils
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.12
|
|
4
4
|
Summary: CLI utilities for csrd service generation and feature augmentation
|
|
5
5
|
Project-URL: Repository, https://github.com/csrd-api/fastapi-common
|
|
6
6
|
Project-URL: Documentation, https://github.com/csrd-api/fastapi-common/tree/main/packages/utils
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import argparse
|
|
6
6
|
import json
|
|
7
|
+
from contextlib import suppress
|
|
7
8
|
from importlib.metadata import version
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
from typing import TypedDict
|
|
@@ -75,6 +76,12 @@ def _prompt_int(label: str, default: int) -> int:
|
|
|
75
76
|
print("ERROR: Enter a valid integer")
|
|
76
77
|
|
|
77
78
|
|
|
79
|
+
def _print_cancelled() -> None:
|
|
80
|
+
# Avoid surfacing a traceback if a second Ctrl-C lands while printing.
|
|
81
|
+
with suppress(KeyboardInterrupt):
|
|
82
|
+
print("\nCancelled.")
|
|
83
|
+
|
|
84
|
+
|
|
78
85
|
def _collect_new_service_config(args: argparse.Namespace) -> GenerateServiceArgs:
|
|
79
86
|
explicit_interactive = getattr(args, "interactive", None)
|
|
80
87
|
is_explicit_interactive = explicit_interactive is True
|
|
@@ -386,7 +393,7 @@ def main() -> int:
|
|
|
386
393
|
print(f"ERROR: {exc}")
|
|
387
394
|
return 1
|
|
388
395
|
except KeyboardInterrupt:
|
|
389
|
-
|
|
396
|
+
_print_cancelled()
|
|
390
397
|
return 1
|
|
391
398
|
print(f"Generated service at: {generated}")
|
|
392
399
|
return 0
|
|
@@ -399,11 +406,11 @@ def main() -> int:
|
|
|
399
406
|
cluster_config["output_dir"],
|
|
400
407
|
force=cluster_config["overwrite_if_exists"],
|
|
401
408
|
)
|
|
402
|
-
except (FileExistsError, ValueError) as exc:
|
|
409
|
+
except (FileExistsError, FileNotFoundError, ValueError) as exc:
|
|
403
410
|
print(f"ERROR: {exc}")
|
|
404
411
|
return 1
|
|
405
412
|
except KeyboardInterrupt:
|
|
406
|
-
|
|
413
|
+
_print_cancelled()
|
|
407
414
|
return 1
|
|
408
415
|
print(f"Generated cluster at: {generated}")
|
|
409
416
|
return 0
|
|
@@ -76,6 +76,8 @@ def _split_csv(raw: str) -> list[str]:
|
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
def load_cluster_spec(spec_path: Path) -> ClusterSpec:
|
|
79
|
+
if not spec_path.is_file():
|
|
80
|
+
raise ValueError(f"Cluster spec file not found: {spec_path}")
|
|
79
81
|
payload = yaml.safe_load(spec_path.read_text(encoding="utf-8"))
|
|
80
82
|
if not isinstance(payload, dict):
|
|
81
83
|
raise ValueError("Cluster spec must be a YAML object")
|
|
@@ -32,25 +32,32 @@ def _prune_disabled_files() -> None:
|
|
|
32
32
|
if not HAS_DATABASE:
|
|
33
33
|
_unlink("src/app/dependencies/item_repository.py")
|
|
34
34
|
_unlink("src/app/repositories/item_repository.py")
|
|
35
|
+
_unlink("tests/unit/test_database_settings.py")
|
|
35
36
|
|
|
36
37
|
if not HAS_DELEGATES:
|
|
37
38
|
_unlink("src/app/dependencies/delegates.py")
|
|
38
39
|
_unlink("src/app/delegates/upstreams.py")
|
|
40
|
+
_unlink("tests/unit/test_delegates.py")
|
|
39
41
|
|
|
40
42
|
if not HAS_WORKERS:
|
|
41
43
|
_unlink("src/app/dependencies/worker_broker.py")
|
|
42
44
|
_unlink("src/app/workers/tasks.py")
|
|
45
|
+
_unlink("tests/unit/test_worker_broker.py")
|
|
43
46
|
|
|
44
47
|
if not HAS_CACHING:
|
|
45
48
|
_unlink("src/app/cache.py")
|
|
49
|
+
_unlink("tests/unit/test_cache.py")
|
|
46
50
|
|
|
47
51
|
if not HAS_STRUCTURED_LOGGING:
|
|
48
52
|
_unlink("src/app/middleware/logging.py")
|
|
53
|
+
_unlink("tests/acceptance/test_logging_middleware.py")
|
|
49
54
|
|
|
50
55
|
_rmdir_if_empty("src/app/repositories")
|
|
51
56
|
_rmdir_if_empty("src/app/delegates")
|
|
52
57
|
_rmdir_if_empty("src/app/workers")
|
|
53
58
|
_rmdir_if_empty("src/app/middleware")
|
|
59
|
+
_rmdir_if_empty("tests/unit")
|
|
60
|
+
_rmdir_if_empty("tests/acceptance")
|
|
54
61
|
|
|
55
62
|
|
|
56
63
|
def main() -> int:
|
|
@@ -44,3 +44,14 @@ docker compose up --build
|
|
|
44
44
|
- `PUT /api/{{ cookiecutter.model_name_plural | lower | replace(' ', '_') }}/{entity_id}`
|
|
45
45
|
- `DELETE /api/{{ cookiecutter.model_name_plural | lower | replace(' ', '_') }}/{entity_id}`
|
|
46
46
|
{%- endif %}
|
|
47
|
+
|
|
48
|
+
## Generated tests
|
|
49
|
+
|
|
50
|
+
- Acceptance tests live under `tests/acceptance/`
|
|
51
|
+
- Unit tests live under `tests/unit/`
|
|
52
|
+
- Feature-dependent tests are generated only when corresponding dependencies are enabled:
|
|
53
|
+
- database -> `tests/unit/test_database_settings.py`
|
|
54
|
+
- delegates -> `tests/unit/test_delegates.py`
|
|
55
|
+
- workers -> `tests/unit/test_worker_broker.py`
|
|
56
|
+
- caching -> `tests/unit/test_cache.py`
|
|
57
|
+
- structured logging -> `tests/acceptance/test_logging_middleware.py`
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Unit tests for cache dependency wiring."""
|
|
2
|
+
|
|
3
|
+
from app.cache import build_cache_client
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_cache_client_uses_configured_host() -> None:
|
|
7
|
+
cache_client = build_cache_client()
|
|
8
|
+
host = cache_client.connection_pool.connection_kwargs.get("host")
|
|
9
|
+
assert host in {"localhost", "redis"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Unit tests for delegate dependency wiring."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
5
|
+
from app.dependencies.delegates import upstream_delegate_factory
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async def _collect_upstreams() -> list[str]:
|
|
9
|
+
async for upstreams in upstream_delegate_factory():
|
|
10
|
+
return upstreams
|
|
11
|
+
return []
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_upstream_delegate_factory_returns_urls() -> None:
|
|
15
|
+
upstreams = asyncio.run(_collect_upstreams())
|
|
16
|
+
assert upstreams
|
|
17
|
+
assert all(url.startswith("http") for url in upstreams)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Unit tests for worker broker dependency wiring."""
|
|
2
|
+
|
|
3
|
+
from app.dependencies.worker_broker import get_worker_broker_url
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_worker_broker_url_uses_expected_scheme() -> None:
|
|
7
|
+
broker_url = get_worker_broker_url()
|
|
8
|
+
assert broker_url.startswith(("redis://", "amqp://"))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/conftest.fragment.py
RENAMED
|
File without changes
|
{csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/docker-compose.fragment.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/requirements.fragment
RENAMED
|
File without changes
|
{csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/settings.fragment.py
RENAMED
|
File without changes
|
{csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/src/app/workers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/src/app/workers/tasks.py
RENAMED
|
File without changes
|
{csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/features/workers/tests/test_workers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{csrd_utils-0.3.10 → csrd_utils-0.3.12}/src/csrd_utils/templates/cookiecutter-service/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|