csrd-utils 0.3.73__tar.gz → 0.3.75__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.73 → csrd_utils-0.3.75}/PKG-INFO +1 -1
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/pyproject.toml +1 -1
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/__main__.py +2 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/cluster.py +34 -4
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/cookiecutter.json +1 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/README.md +4 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +3 -0
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/dependencies/item_repository.py +25 -0
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/models/__init__.py +22 -0
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/models/auth_service.py +11 -0
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/models/items.py +36 -0
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +3 -0
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/repositories/item_repository.py +71 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/requirements.txt +2 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/settings.py +1 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/auth_service_view.py +1 -12
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/items_view.py +68 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/cookiecutter.json +1 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/README.md +1 -1
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/models/__init__.py +9 -0
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/models/auth.py +34 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/settings.py +1 -1
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/views/unversioned/auth_view.py +1 -35
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/cookiecutter.json +1 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/README.md +1 -1
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/models/__init__.py +17 -0
- csrd_utils-0.3.75/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/models/users.py +37 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/settings.py +1 -1
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/unversioned/users_view.py +8 -38
- csrd_utils-0.3.73/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/items_view.py +0 -106
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/.gitignore +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/README.md +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/audit.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/augmentor.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/doctor.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/caching/conftest.fragment.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/caching/docker-compose.fragment.yaml +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/caching/manifest.yaml +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/caching/requirements.fragment +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/caching/settings.fragment.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/caching/src/app/cache.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/caching/tests/test_cache.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/logging/conftest.fragment.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/logging/manifest.yaml +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/logging/requirements.fragment +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/logging/settings.fragment.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/logging/src/app/middleware/logging.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/logging/tests/test_logging_middleware.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/metrics/conftest.fragment.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/metrics/docker-compose.fragment.yaml +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/metrics/manifest.yaml +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/metrics/requirements.fragment +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/metrics/settings.fragment.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/metrics/src/app/middleware/metrics.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/metrics/tests/test_metrics_middleware.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/tracing/conftest.fragment.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/tracing/manifest.yaml +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/tracing/requirements.fragment +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/tracing/settings.fragment.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/tracing/src/app/middleware/tracing.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/tracing/tests/test_tracing_middleware.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/workers/conftest.fragment.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/workers/docker-compose.fragment.yaml +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/workers/manifest.yaml +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/workers/requirements.fragment +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/workers/settings.fragment.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/workers/src/app/workers/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/workers/src/app/workers/celery_app.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/workers/src/app/workers/tasks.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/features/workers/tests/test_workers.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/fragments.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/generator.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/resources.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/README.md +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/cookiecutter.json +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/hooks/post_gen_project.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/.cookiecutterignore +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/cache.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/delegates/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/delegates/upstreams.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/auth_service.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/delegates.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/item_repository.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/worker_broker.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/docker-compose.yml +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/middleware/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/middleware/logging.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/repositories/item_repository.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/acceptance/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/acceptance/test_logging_middleware.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/conftest.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/test_items.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_cache.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_database_settings.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_delegates.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_settings_contracts.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_worker_broker.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/items_view.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/workers/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/workers/tasks.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/delegates/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/delegates/auth_delegate.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/delegates/identity_delegate.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/dependencies/auth_passthrough.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/dependencies/auth_service.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/repositories/token_repository.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/repositories/user_repository.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
- {csrd_utils-0.3.73 → csrd_utils-0.3.75}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.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.75
|
|
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
|
|
@@ -485,6 +485,8 @@ def _generate_services_from_cluster_spec(
|
|
|
485
485
|
role = str(service.get("role", "custom")).strip()
|
|
486
486
|
# Build extra_context for platform templates that have additional variables
|
|
487
487
|
extra: dict[str, str] = {}
|
|
488
|
+
if role in {"app", "auth", "identity"}:
|
|
489
|
+
extra["db_path"] = "./platform.db"
|
|
488
490
|
if role == "auth":
|
|
489
491
|
# Resolve the identity-service URL from the port map if present
|
|
490
492
|
identity_port = next(
|
|
@@ -35,15 +35,21 @@ PRESETS: dict[str, list[ServiceSpec]] = {
|
|
|
35
35
|
"type": "platform",
|
|
36
36
|
"role": "app",
|
|
37
37
|
"port": 8080,
|
|
38
|
-
"requires": ["auth-service"],
|
|
38
|
+
"requires": ["auth-service", "postgres"],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "auth-service",
|
|
42
|
+
"type": "platform",
|
|
43
|
+
"role": "auth",
|
|
44
|
+
"port": 8081,
|
|
45
|
+
"requires": ["postgres"],
|
|
39
46
|
},
|
|
40
|
-
{"name": "auth-service", "type": "platform", "role": "auth", "port": 8081, "requires": []},
|
|
41
47
|
{
|
|
42
48
|
"name": "identity-service",
|
|
43
49
|
"type": "platform",
|
|
44
50
|
"role": "identity",
|
|
45
51
|
"port": 8082,
|
|
46
|
-
"requires": ["auth-service"],
|
|
52
|
+
"requires": ["auth-service", "postgres"],
|
|
47
53
|
},
|
|
48
54
|
],
|
|
49
55
|
# "minimal-cluster": [
|
|
@@ -257,7 +263,7 @@ def _service_environment(service: ServiceSpec, services: list[ServiceSpec]) -> d
|
|
|
257
263
|
if service["type"] == "db":
|
|
258
264
|
db = service.get("database")
|
|
259
265
|
if db == "sqlite":
|
|
260
|
-
env["DB_PATH"] = "
|
|
266
|
+
env["DB_PATH"] = "/data/service.db"
|
|
261
267
|
elif db == "maria":
|
|
262
268
|
env["DB_HOST"] = "mariadb"
|
|
263
269
|
env["DB_PORT"] = "3306"
|
|
@@ -292,6 +298,14 @@ def _service_environment(service: ServiceSpec, services: list[ServiceSpec]) -> d
|
|
|
292
298
|
if auth_service and name != auth_service["name"]:
|
|
293
299
|
env["AUTH_SERVICE_URL"] = f"http://{auth_service['name']}:{auth_service['port']}"
|
|
294
300
|
|
|
301
|
+
role = str(service.get("role", "")).strip()
|
|
302
|
+
if service["type"] == "platform" and role in {"app", "auth", "identity"}:
|
|
303
|
+
env["DB_HOST"] = "postgres"
|
|
304
|
+
env["DB_PORT"] = "5432"
|
|
305
|
+
env["DB_USER"] = "${DB_USER:-service_user}"
|
|
306
|
+
env["DB_PASSWORD"] = "${DB_PASSWORD:-change_me}"
|
|
307
|
+
env["DB_NAME"] = "${DB_NAME:-service_db}"
|
|
308
|
+
|
|
295
309
|
return env
|
|
296
310
|
|
|
297
311
|
|
|
@@ -299,6 +313,7 @@ def render_compose(spec: ClusterSpec) -> dict[str, Any]:
|
|
|
299
313
|
services = spec["services"]
|
|
300
314
|
infra = _infer_infra(services)
|
|
301
315
|
compose: dict[str, Any] = {"services": {}}
|
|
316
|
+
compose_volumes: dict[str, dict[str, str]] = {}
|
|
302
317
|
|
|
303
318
|
for service in services:
|
|
304
319
|
name = str(service["name"])
|
|
@@ -341,6 +356,18 @@ def render_compose(spec: ClusterSpec) -> dict[str, Any]:
|
|
|
341
356
|
"ports": [f"{service['port']}:{service['port']}"],
|
|
342
357
|
"environment": _service_environment(service, services),
|
|
343
358
|
}
|
|
359
|
+
|
|
360
|
+
role = str(service.get("role", "")).strip()
|
|
361
|
+
volume_name: str | None = None
|
|
362
|
+
if service["type"] == "db" and service.get("database") == "sqlite":
|
|
363
|
+
volume_name = f"{name}-data"
|
|
364
|
+
elif service["type"] == "platform" and role in {"app", "auth", "identity"}:
|
|
365
|
+
volume_name = None
|
|
366
|
+
|
|
367
|
+
if volume_name is not None:
|
|
368
|
+
app_service["volumes"] = [f"{volume_name}:/data"]
|
|
369
|
+
compose_volumes[volume_name] = {}
|
|
370
|
+
|
|
344
371
|
if depends_on:
|
|
345
372
|
app_service["depends_on"] = depends_on
|
|
346
373
|
compose["services"][name] = app_service
|
|
@@ -408,6 +435,9 @@ def render_compose(spec: ClusterSpec) -> dict[str, Any]:
|
|
|
408
435
|
},
|
|
409
436
|
}
|
|
410
437
|
|
|
438
|
+
if compose_volumes:
|
|
439
|
+
compose["volumes"] = compose_volumes
|
|
440
|
+
|
|
411
441
|
return compose
|
|
412
442
|
|
|
413
443
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"service_name": "app-service",
|
|
3
3
|
"port": "8080",
|
|
4
|
+
"db_path": "./platform.db",
|
|
4
5
|
"auth_service_url": "http://auth-service:8081",
|
|
5
6
|
"identity_service_url": "http://identity-service:8082",
|
|
6
7
|
"__service_name_snake": "{{ cookiecutter.service_name | replace('-', '_') }}"
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Platform app service with auth-guarded item endpoints.
|
|
4
4
|
|
|
5
|
+
Items are persisted in SQLite so this service can share the same DB file
|
|
6
|
+
as platform auth and identity services.
|
|
7
|
+
|
|
5
8
|
## Endpoints
|
|
6
9
|
|
|
7
10
|
- `GET /health` - liveness probe
|
|
@@ -18,6 +21,7 @@ Platform app service with auth-guarded item endpoints.
|
|
|
18
21
|
|
|
19
22
|
| Variable | Default | Description |
|
|
20
23
|
|---|---|---|
|
|
24
|
+
| `DB_PATH` | `{{ cookiecutter.db_path }}` | Shared SQLite database file path |
|
|
21
25
|
| `AUTH_SERVICE_URL` | `{{ cookiecutter.auth_service_url }}` | Auth service verify endpoint base URL |
|
|
22
26
|
| `IDENTITY_SERVICE_URL` | `{{ cookiecutter.identity_service_url }}` | Identity service base URL for signup passthrough |
|
|
23
27
|
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
from .auth_passthrough import AuthDelegateDep, IdentityDelegateDep
|
|
2
2
|
from .auth_service import VerifiedTokenDep, router_auth
|
|
3
|
+
from .item_repository import ItemRepositoryDep, item_repository_factory
|
|
3
4
|
|
|
4
5
|
__all__ = (
|
|
5
6
|
"AuthDelegateDep",
|
|
6
7
|
"IdentityDelegateDep",
|
|
8
|
+
"ItemRepositoryDep",
|
|
7
9
|
"VerifiedTokenDep",
|
|
10
|
+
"item_repository_factory",
|
|
8
11
|
"router_auth",
|
|
9
12
|
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from collections.abc import AsyncIterator
|
|
2
|
+
from typing import Annotated
|
|
3
|
+
|
|
4
|
+
from fastapi import Depends
|
|
5
|
+
|
|
6
|
+
from csrd.repository import SQLiteAdapter
|
|
7
|
+
|
|
8
|
+
from ..repositories import ItemRepository
|
|
9
|
+
from ..settings import settings
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def item_repository_factory() -> AsyncIterator[ItemRepository]:
|
|
13
|
+
adapter = SQLiteAdapter(settings.db_path)
|
|
14
|
+
await adapter.connect()
|
|
15
|
+
repo = ItemRepository(adapter)
|
|
16
|
+
await repo._init_schema()
|
|
17
|
+
try:
|
|
18
|
+
yield repo
|
|
19
|
+
finally:
|
|
20
|
+
await adapter.close()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
ItemRepositoryDep = Annotated[ItemRepository, Depends(item_repository_factory)]
|
|
24
|
+
|
|
25
|
+
__all__ = ("ItemRepositoryDep", "item_repository_factory")
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .auth_service import LoginRequest, SignupRequest
|
|
2
|
+
from .items import (
|
|
3
|
+
CreateItemRequest,
|
|
4
|
+
ItemDeleteResponse,
|
|
5
|
+
ItemListResponse,
|
|
6
|
+
ItemResponse,
|
|
7
|
+
ItemUpdateResponse,
|
|
8
|
+
ItemUpsertResponse,
|
|
9
|
+
UpdateItemRequest,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = (
|
|
13
|
+
"CreateItemRequest",
|
|
14
|
+
"ItemDeleteResponse",
|
|
15
|
+
"ItemListResponse",
|
|
16
|
+
"ItemResponse",
|
|
17
|
+
"ItemUpdateResponse",
|
|
18
|
+
"ItemUpsertResponse",
|
|
19
|
+
"LoginRequest",
|
|
20
|
+
"SignupRequest",
|
|
21
|
+
"UpdateItemRequest",
|
|
22
|
+
)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class CreateItemRequest(BaseModel):
|
|
5
|
+
name: str
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class UpdateItemRequest(BaseModel):
|
|
9
|
+
name: str
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ItemResponse(BaseModel):
|
|
13
|
+
id: str
|
|
14
|
+
name: str
|
|
15
|
+
created_at: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ItemListResponse(BaseModel):
|
|
19
|
+
items: list[ItemResponse]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ItemUpdateResponse(BaseModel):
|
|
23
|
+
id: str
|
|
24
|
+
name: str
|
|
25
|
+
updated: bool
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ItemUpsertResponse(BaseModel):
|
|
29
|
+
id: str
|
|
30
|
+
name: str
|
|
31
|
+
rows_affected: int
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ItemDeleteResponse(BaseModel):
|
|
35
|
+
id: str
|
|
36
|
+
deleted: bool
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from datetime import UTC, datetime
|
|
3
|
+
|
|
4
|
+
from csrd.repository import BaseRepository, DBProtocol
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
_CREATE_ITEMS_TABLE_SQL = """
|
|
8
|
+
CREATE TABLE IF NOT EXISTS items (
|
|
9
|
+
id TEXT PRIMARY KEY,
|
|
10
|
+
name TEXT NOT NULL,
|
|
11
|
+
created_at TEXT NOT NULL
|
|
12
|
+
)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ItemRepository(BaseRepository):
|
|
17
|
+
def __init__(self, adapter: DBProtocol) -> None:
|
|
18
|
+
super().__init__(adapter)
|
|
19
|
+
|
|
20
|
+
async def _init_schema(self) -> None:
|
|
21
|
+
await self.execute(_CREATE_ITEMS_TABLE_SQL)
|
|
22
|
+
|
|
23
|
+
async def create_item(self, name: str) -> dict[str, str]:
|
|
24
|
+
item_id = str(uuid.uuid4())
|
|
25
|
+
created_at = datetime.now(UTC).isoformat()
|
|
26
|
+
await self._init_schema()
|
|
27
|
+
await self.insert("items", {"id": item_id, "name": name, "created_at": created_at})
|
|
28
|
+
return {"id": item_id, "name": name, "created_at": created_at}
|
|
29
|
+
|
|
30
|
+
async def list_items(self) -> list[dict[str, str]]:
|
|
31
|
+
await self._init_schema()
|
|
32
|
+
rows = await self.fetch_all("SELECT id, name, created_at FROM items ORDER BY created_at DESC")
|
|
33
|
+
return [
|
|
34
|
+
{
|
|
35
|
+
"id": str(row.get("id", "")),
|
|
36
|
+
"name": str(row.get("name", "")),
|
|
37
|
+
"created_at": str(row.get("created_at", "")),
|
|
38
|
+
}
|
|
39
|
+
for row in rows
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
async def get_item(self, item_id: str) -> dict[str, str] | None:
|
|
43
|
+
await self._init_schema()
|
|
44
|
+
row = await self.fetch_one(
|
|
45
|
+
"SELECT id, name, created_at FROM items WHERE id = :id",
|
|
46
|
+
{"id": item_id},
|
|
47
|
+
)
|
|
48
|
+
if row is None:
|
|
49
|
+
return None
|
|
50
|
+
return {
|
|
51
|
+
"id": str(row.get("id", "")),
|
|
52
|
+
"name": str(row.get("name", "")),
|
|
53
|
+
"created_at": str(row.get("created_at", "")),
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async def update_item(self, item_id: str, name: str) -> int:
|
|
57
|
+
await self._init_schema()
|
|
58
|
+
return await super().update("items", {"name": name}, {"id": item_id})
|
|
59
|
+
|
|
60
|
+
async def delete_item(self, item_id: str) -> int:
|
|
61
|
+
await self._init_schema()
|
|
62
|
+
return await super().delete("items", {"id": item_id})
|
|
63
|
+
|
|
64
|
+
async def upsert_item(self, item_id: str, name: str) -> int:
|
|
65
|
+
await self._init_schema()
|
|
66
|
+
created_at = datetime.now(UTC).isoformat()
|
|
67
|
+
return await super().upsert(
|
|
68
|
+
"items",
|
|
69
|
+
{"name": name, "created_at": created_at},
|
|
70
|
+
{"id": item_id},
|
|
71
|
+
)
|
|
@@ -6,6 +6,7 @@ class Settings(BaseSettings):
|
|
|
6
6
|
|
|
7
7
|
app_name: str = "{{ cookiecutter.service_name }}"
|
|
8
8
|
port: int = {{ cookiecutter.port }}
|
|
9
|
+
db_path: str = "{{ cookiecutter.db_path }}"
|
|
9
10
|
auth_service_url: str = "{{ cookiecutter.auth_service_url }}"
|
|
10
11
|
identity_service_url: str = "{{ cookiecutter.identity_service_url }}"
|
|
11
12
|
|
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
from fastapi import APIRouter
|
|
2
|
-
from pydantic import BaseModel
|
|
3
2
|
|
|
4
3
|
from ...dependencies import AuthDelegateDep, IdentityDelegateDep
|
|
4
|
+
from ...models import LoginRequest, SignupRequest
|
|
5
5
|
|
|
6
6
|
router = APIRouter(tags=["Auth Service"])
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
class SignupRequest(BaseModel):
|
|
10
|
-
username: str
|
|
11
|
-
password: str
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class LoginRequest(BaseModel):
|
|
15
|
-
username: str
|
|
16
|
-
password: str
|
|
17
|
-
|
|
18
|
-
|
|
19
8
|
@router.post("/signup")
|
|
20
9
|
async def signup(payload: SignupRequest, delegate: IdentityDelegateDep) -> dict[str, object]:
|
|
21
10
|
async with delegate:
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from fastapi import APIRouter, HTTPException
|
|
2
|
+
|
|
3
|
+
from ...dependencies import ItemRepositoryDep, router_auth
|
|
4
|
+
from ...models import (
|
|
5
|
+
CreateItemRequest,
|
|
6
|
+
ItemDeleteResponse,
|
|
7
|
+
ItemListResponse,
|
|
8
|
+
ItemResponse,
|
|
9
|
+
ItemUpdateResponse,
|
|
10
|
+
ItemUpsertResponse,
|
|
11
|
+
UpdateItemRequest,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
router = APIRouter(prefix="/api", tags=["Items Endpoints"], dependencies=[router_auth])
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@router.post("/items", response_model=ItemResponse)
|
|
18
|
+
async def create_item(
|
|
19
|
+
payload: CreateItemRequest,
|
|
20
|
+
repo: ItemRepositoryDep,
|
|
21
|
+
) -> ItemResponse:
|
|
22
|
+
return await repo.create_item(payload.name)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@router.get("/items", response_model=ItemListResponse)
|
|
26
|
+
async def list_items(repo: ItemRepositoryDep) -> ItemListResponse:
|
|
27
|
+
return {"items": await repo.list_items()}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@router.get("/items/{entity_id}", response_model=ItemResponse)
|
|
31
|
+
async def get_item(entity_id: str, repo: ItemRepositoryDep) -> ItemResponse:
|
|
32
|
+
item = await repo.get_item(entity_id)
|
|
33
|
+
if item is None:
|
|
34
|
+
raise HTTPException(status_code=404, detail="item not found")
|
|
35
|
+
return item
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@router.put("/items/{entity_id}", response_model=ItemUpdateResponse)
|
|
39
|
+
async def update_item(
|
|
40
|
+
entity_id: str,
|
|
41
|
+
payload: UpdateItemRequest,
|
|
42
|
+
repo: ItemRepositoryDep,
|
|
43
|
+
) -> ItemUpdateResponse:
|
|
44
|
+
rows = await repo.update_item(entity_id, payload.name)
|
|
45
|
+
if rows == 0:
|
|
46
|
+
raise HTTPException(status_code=404, detail="item not found")
|
|
47
|
+
return {"id": entity_id, "name": payload.name, "updated": True}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@router.put("/items/{entity_id}/upsert", response_model=ItemUpsertResponse)
|
|
51
|
+
async def upsert_item(
|
|
52
|
+
entity_id: str,
|
|
53
|
+
payload: UpdateItemRequest,
|
|
54
|
+
repo: ItemRepositoryDep,
|
|
55
|
+
) -> ItemUpsertResponse:
|
|
56
|
+
rows = await repo.upsert_item(entity_id, payload.name)
|
|
57
|
+
return {"id": entity_id, "name": payload.name, "rows_affected": rows}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@router.delete("/items/{entity_id}", response_model=ItemDeleteResponse)
|
|
61
|
+
async def delete_item(
|
|
62
|
+
entity_id: str,
|
|
63
|
+
repo: ItemRepositoryDep,
|
|
64
|
+
) -> ItemDeleteResponse:
|
|
65
|
+
rows = await repo.delete_item(entity_id)
|
|
66
|
+
if rows == 0:
|
|
67
|
+
raise HTTPException(status_code=404, detail="item not found")
|
|
68
|
+
return {"id": entity_id, "deleted": True}
|
|
@@ -17,7 +17,7 @@ Platform auth service — issues and verifies JWT tokens.
|
|
|
17
17
|
| `JWT_ISSUER` | `{{ cookiecutter.service_name }}` | Token issuer |
|
|
18
18
|
| `JWT_AUDIENCE` | `cluster` | Token audience |
|
|
19
19
|
| `JWT_TTL_SECONDS` | `3600` | Token TTL |
|
|
20
|
-
| `DB_PATH` |
|
|
20
|
+
| `DB_PATH` | `{{ cookiecutter.db_path }}` | SQLite database path |
|
|
21
21
|
| `IDENTITY_SERVICE_URL` | `{{ cookiecutter.identity_service_url }}` | Identity service URL |
|
|
22
22
|
|
|
23
23
|
## Run
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TokenRequest(BaseModel):
|
|
5
|
+
username: str
|
|
6
|
+
password: str
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class VerifyRequest(BaseModel):
|
|
10
|
+
token: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TokenResponse(BaseModel):
|
|
14
|
+
"""JWT token issuance response."""
|
|
15
|
+
|
|
16
|
+
access_token: str
|
|
17
|
+
token_type: str
|
|
18
|
+
expires_in: int
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class VerifyClaims(BaseModel):
|
|
22
|
+
"""JWT claim fields returned by verify endpoint."""
|
|
23
|
+
|
|
24
|
+
sub: str
|
|
25
|
+
user_name: str
|
|
26
|
+
authorities: list[str]
|
|
27
|
+
roles: list[str]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class TokenVerifyResponse(BaseModel):
|
|
31
|
+
"""Token verification response."""
|
|
32
|
+
|
|
33
|
+
valid: bool
|
|
34
|
+
claims: VerifyClaims
|
|
@@ -13,7 +13,7 @@ class Settings(BaseSettings):
|
|
|
13
13
|
jwt_audience: str = "cluster"
|
|
14
14
|
jwt_ttl_seconds: int = 3600
|
|
15
15
|
|
|
16
|
-
db_path: str = "
|
|
16
|
+
db_path: str = "{{ cookiecutter.db_path }}"
|
|
17
17
|
identity_service_url: str = "{{ cookiecutter.identity_service_url }}"
|
|
18
18
|
|
|
19
19
|
|
|
@@ -3,49 +3,15 @@ from datetime import UTC, datetime, timedelta
|
|
|
3
3
|
import httpx
|
|
4
4
|
import jwt
|
|
5
5
|
from fastapi import APIRouter, HTTPException, Request
|
|
6
|
-
from pydantic import BaseModel
|
|
7
6
|
|
|
8
7
|
from csrd.auth import JWTAuthenticator, StaticKeyProvider
|
|
9
8
|
|
|
10
9
|
from ...dependencies import TokenRepositoryDep
|
|
10
|
+
from ...models import TokenRequest, TokenResponse, TokenVerifyResponse, VerifyClaims, VerifyRequest
|
|
11
11
|
from ...settings import settings
|
|
12
12
|
|
|
13
13
|
router = APIRouter(prefix="/api", tags=["Auth Endpoints"])
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
class TokenRequest(BaseModel):
|
|
17
|
-
username: str
|
|
18
|
-
password: str
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class VerifyRequest(BaseModel):
|
|
22
|
-
token: str
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class TokenResponse(BaseModel):
|
|
26
|
-
"""JWT token issuance response."""
|
|
27
|
-
|
|
28
|
-
access_token: str
|
|
29
|
-
token_type: str
|
|
30
|
-
expires_in: int
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class VerifyClaims(BaseModel):
|
|
34
|
-
"""JWT claim fields returned by verify endpoint."""
|
|
35
|
-
|
|
36
|
-
sub: str
|
|
37
|
-
user_name: str
|
|
38
|
-
authorities: list[str]
|
|
39
|
-
roles: list[str]
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class TokenVerifyResponse(BaseModel):
|
|
43
|
-
"""Token verification response."""
|
|
44
|
-
|
|
45
|
-
valid: bool
|
|
46
|
-
claims: VerifyClaims
|
|
47
|
-
|
|
48
|
-
|
|
49
15
|
def _make_verifier() -> JWTAuthenticator:
|
|
50
16
|
return JWTAuthenticator(
|
|
51
17
|
key=StaticKeyProvider(settings.jwt_secret),
|
|
@@ -15,7 +15,7 @@ Platform identity service — manages users and credentials.
|
|
|
15
15
|
|
|
16
16
|
| Variable | Default | Description |
|
|
17
17
|
|---|---|---|
|
|
18
|
-
| `DB_PATH` |
|
|
18
|
+
| `DB_PATH` | `{{ cookiecutter.db_path }}` | SQLite database path |
|
|
19
19
|
|
|
20
20
|
## Run
|
|
21
21
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from .users import (
|
|
2
|
+
AssignRoleRequest,
|
|
3
|
+
SignupRequest,
|
|
4
|
+
UserInfo,
|
|
5
|
+
UserRolesResponse,
|
|
6
|
+
VerifyCredentialsRequest,
|
|
7
|
+
VerifyCredentialsResponse,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
__all__ = (
|
|
11
|
+
"AssignRoleRequest",
|
|
12
|
+
"SignupRequest",
|
|
13
|
+
"UserInfo",
|
|
14
|
+
"UserRolesResponse",
|
|
15
|
+
"VerifyCredentialsRequest",
|
|
16
|
+
"VerifyCredentialsResponse",
|
|
17
|
+
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SignupRequest(BaseModel):
|
|
5
|
+
username: str
|
|
6
|
+
password: str
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class VerifyCredentialsRequest(BaseModel):
|
|
10
|
+
username: str
|
|
11
|
+
password: str
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AssignRoleRequest(BaseModel):
|
|
15
|
+
role: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class UserInfo(BaseModel):
|
|
19
|
+
"""User information."""
|
|
20
|
+
|
|
21
|
+
id: str
|
|
22
|
+
username: str
|
|
23
|
+
created_at: str
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class UserRolesResponse(BaseModel):
|
|
27
|
+
"""User roles response."""
|
|
28
|
+
|
|
29
|
+
user_id: str
|
|
30
|
+
roles: list[str]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class VerifyCredentialsResponse(BaseModel):
|
|
34
|
+
"""Credentials verification response."""
|
|
35
|
+
|
|
36
|
+
valid: bool
|
|
37
|
+
user: UserInfo
|