csrd-utils 0.3.91__tar.gz → 0.3.93__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.
Files changed (193) hide show
  1. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/PKG-INFO +1 -1
  2. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/pyproject.toml +1 -1
  3. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/AGENTS.md +3 -3
  4. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/renderer.py +3 -3
  5. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/scaffolder.py +5 -6
  6. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/service_renderers.py +2 -2
  7. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/augments/jwt-auth-provider/views/auth_view.py +39 -7
  8. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/augments/jwt-auth-provider/views/jwks_view.py +13 -3
  9. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/augments/jwt-auth-provider/views/users_view.py +36 -12
  10. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/Dockerfile +2 -2
  11. csrd_utils-0.3.93/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/views/health_view.py +16 -0
  12. csrd_utils-0.3.91/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/views/health_view.py +0 -8
  13. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/.gitignore +0 -0
  14. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/README.md +0 -0
  15. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/__init__.py +0 -0
  16. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/__main__.py +0 -0
  17. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/audit.py +0 -0
  18. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/augmentor.py +0 -0
  19. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/cluster.py +0 -0
  20. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/doctor.py +0 -0
  21. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/caching/conftest.fragment.py +0 -0
  22. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/caching/docker-compose.fragment.yaml +0 -0
  23. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/caching/manifest.yaml +0 -0
  24. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/caching/requirements.fragment +0 -0
  25. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/caching/settings.fragment.py +0 -0
  26. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/caching/src/app/cache.py +0 -0
  27. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/caching/tests/test_cache.py +0 -0
  28. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/logging/conftest.fragment.py +0 -0
  29. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/logging/manifest.yaml +0 -0
  30. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/logging/requirements.fragment +0 -0
  31. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/logging/settings.fragment.py +0 -0
  32. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/logging/src/app/middleware/logging.py +0 -0
  33. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/logging/tests/test_logging_middleware.py +0 -0
  34. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/metrics/conftest.fragment.py +0 -0
  35. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/metrics/docker-compose.fragment.yaml +0 -0
  36. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/metrics/manifest.yaml +0 -0
  37. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/metrics/requirements.fragment +0 -0
  38. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/metrics/settings.fragment.py +0 -0
  39. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/metrics/src/app/middleware/metrics.py +0 -0
  40. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/metrics/tests/test_metrics_middleware.py +0 -0
  41. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/tracing/conftest.fragment.py +0 -0
  42. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/tracing/manifest.yaml +0 -0
  43. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/tracing/requirements.fragment +0 -0
  44. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/tracing/settings.fragment.py +0 -0
  45. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/tracing/src/app/middleware/tracing.py +0 -0
  46. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/tracing/tests/test_tracing_middleware.py +0 -0
  47. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/workers/conftest.fragment.py +0 -0
  48. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/workers/docker-compose.fragment.yaml +0 -0
  49. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/workers/manifest.yaml +0 -0
  50. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/workers/requirements.fragment +0 -0
  51. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/workers/settings.fragment.py +0 -0
  52. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/workers/src/app/workers/__init__.py +0 -0
  53. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/workers/src/app/workers/celery_app.py +0 -0
  54. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/workers/src/app/workers/tasks.py +0 -0
  55. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/features/workers/tests/test_workers.py +0 -0
  56. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/fragments.py +0 -0
  57. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/generator.py +0 -0
  58. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/resources.py +0 -0
  59. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/README.md +0 -0
  60. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/cookiecutter.json +0 -0
  61. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/hooks/post_gen_project.py +0 -0
  62. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/.cookiecutterignore +0 -0
  63. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
  64. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
  65. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
  66. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
  67. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/cache.py +0 -0
  68. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/delegates/__init__.py +0 -0
  69. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/delegates/upstreams.py +0 -0
  70. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
  71. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/auth_service.py +0 -0
  72. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/delegates.py +0 -0
  73. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/item_repository.py +0 -0
  74. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/worker_broker.py +0 -0
  75. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/docker-compose.yml +0 -0
  76. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/middleware/__init__.py +0 -0
  77. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/middleware/logging.py +0 -0
  78. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
  79. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/repositories/item_repository.py +0 -0
  80. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
  81. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
  82. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/__init__.py +0 -0
  83. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/acceptance/__init__.py +0 -0
  84. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/acceptance/test_logging_middleware.py +0 -0
  85. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/conftest.py +0 -0
  86. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/test_items.py +0 -0
  87. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/__init__.py +0 -0
  88. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_cache.py +0 -0
  89. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_database_settings.py +0 -0
  90. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_delegates.py +0 -0
  91. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_settings_contracts.py +0 -0
  92. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_worker_broker.py +0 -0
  93. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
  94. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
  95. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
  96. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/items_view.py +0 -0
  97. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/workers/__init__.py +0 -0
  98. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/workers/tasks.py +0 -0
  99. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/cookiecutter.json +0 -0
  100. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
  101. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
  102. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
  103. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
  104. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/delegates/__init__.py +0 -0
  105. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/delegates/auth_delegate.py +0 -0
  106. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/delegates/identity_delegate.py +0 -0
  107. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
  108. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/dependencies/auth_passthrough.py +0 -0
  109. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/dependencies/auth_service.py +0 -0
  110. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/dependencies/item_repository.py +0 -0
  111. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/models/__init__.py +0 -0
  112. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/models/auth_service.py +0 -0
  113. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/models/items.py +0 -0
  114. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
  115. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/repositories/item_repository.py +0 -0
  116. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
  117. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
  118. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
  119. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
  120. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/auth_service_view.py +0 -0
  121. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
  122. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/items_view.py +0 -0
  123. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/cookiecutter.json +0 -0
  124. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
  125. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
  126. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
  127. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
  128. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
  129. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/models/__init__.py +0 -0
  130. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/models/auth.py +0 -0
  131. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
  132. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/repositories/token_repository.py +0 -0
  133. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
  134. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
  135. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
  136. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
  137. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/views/unversioned/auth_view.py +0 -0
  138. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
  139. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/cookiecutter.json +0 -0
  140. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
  141. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
  142. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
  143. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
  144. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
  145. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/models/__init__.py +0 -0
  146. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/models/users.py +0 -0
  147. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
  148. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/repositories/user_repository.py +0 -0
  149. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
  150. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
  151. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
  152. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
  153. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
  154. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/unversioned/users_view.py +0 -0
  155. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/__init__.py +0 -0
  156. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/__init__.py +0 -0
  157. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/augments.py +0 -0
  158. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/git.py +0 -0
  159. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/infra.py +0 -0
  160. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/loader.py +0 -0
  161. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/operations.py +0 -0
  162. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/presets.py +0 -0
  163. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/compose/yaml_editor.py +0 -0
  164. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/generate/__init__.py +0 -0
  165. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/generate/handlers.py +0 -0
  166. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/generate/helpers.py +0 -0
  167. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/generate/menu.py +0 -0
  168. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/models/__init__.py +0 -0
  169. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/models/base.py +0 -0
  170. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/models/spec.py +0 -0
  171. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/models/types.py +0 -0
  172. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/augments/db-config/dependencies/db.py +0 -0
  173. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/augments/db-config/migrations.py +0 -0
  174. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/augments/jwt-auth-consumer/dependencies/auth.py +0 -0
  175. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/augments/jwt-auth-provider/dependencies/db.py +0 -0
  176. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/augments/jwt-auth-provider/migrations.py +0 -0
  177. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/augments/jwt-auth-provider/repositories/user_repository.py +0 -0
  178. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/service/cookiecutter.json +0 -0
  179. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
  180. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
  181. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
  182. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
  183. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/tests/__init__.py +0 -0
  184. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/tests/conftest.py +0 -0
  185. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/tests/test_health.py +0 -0
  186. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/csrd_utils/v2/templates/service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
  187. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/tui_wizard/__init__.py +0 -0
  188. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/tui_wizard/exceptions.py +0 -0
  189. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/tui_wizard/menu.py +0 -0
  190. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/tui_wizard/models.py +0 -0
  191. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/tui_wizard/prompts.py +0 -0
  192. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/tui_wizard/terminal.py +0 -0
  193. {csrd_utils-0.3.91 → csrd_utils-0.3.93}/src/tui_wizard/wizard.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csrd-utils
3
- Version: 0.3.91
3
+ Version: 0.3.93
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "csrd-utils"
3
- version = "0.3.91"
3
+ version = "0.3.93"
4
4
  description = "CLI utilities for csrd service generation and feature augmentation"
5
5
  license = { text = "MIT" }
6
6
  requires-python = ">=3.12"
@@ -123,12 +123,12 @@ User edits to scaffolded files are never overwritten on re-render.
123
123
  .gitignore ← rendered from spec
124
124
  .csrd-workspace ← marker file
125
125
  Dockerfile.<service-name> ← one per service, at root
126
- src/<service-name>/ ← service source (kebab-case dir)
126
+ src/<service_snake>/ ← service source (snake_case dir)
127
127
  tests/unit/<service_snake>/ ← unit tests (snake_case dir)
128
128
  tests/acceptance/<service_snake>/ ← acceptance stubs (snake_case dir)
129
129
  ```
130
130
 
131
- - Service source dirs use **kebab-case** (matching `service.name`).
131
+ - Service source dirs use **snake_case** (valid Python package names).
132
132
  - Test dirs use **snake_case** (valid Python package names).
133
133
  - Dockerfiles use kebab-case service name for the suffix, snake_case for the Python module reference in CMD.
134
134
 
@@ -345,5 +345,5 @@ When asked to "audit the menus or compose system", verify each of the following:
345
345
  20. `operations.py` functions load → mutate → save spec — no rendering.
346
346
  21. Workspace finalization uses `_finalize_workspace` — no duplicated create/add/render sequences in handlers.
347
347
  22. `detect_configured_db` is defined once in `infra.py` — not duplicated.
348
- 23. Test dirs use snake_case, source dirs use kebab-case, Dockerfiles use kebab-case suffix.
348
+ 23. Test dirs use snake_case, source dirs use snake_case, Dockerfiles use kebab-case suffix.
349
349
  24. No shim modules or alias re-export files exist (pre-1.0 refactor policy).
@@ -258,7 +258,7 @@ def _render_env_example(spec: ComposeSpec) -> str:
258
258
 
259
259
  lines.append("# JWT Authentication")
260
260
  lines.append("JWT_ISSUER=csrd-auth")
261
- lines.append("JWT_AUDIENCE=csrd-services")
261
+ lines.append(f"JWT_AUDIENCE={spec.workspace.name}")
262
262
  lines.append("JWT_TTL_SECONDS=3600")
263
263
 
264
264
  if signing == "shared-secret":
@@ -310,7 +310,7 @@ def _render_gitignore() -> str:
310
310
  def _render_pyproject(spec: ComposeSpec) -> str:
311
311
  """Build a workspace-level ``pyproject.toml`` with pytest config."""
312
312
 
313
- service_src_paths = [f"src/{svc.name}" for svc in spec.services]
313
+ service_src_paths = [f"src/{svc.name.replace('-', '_')}" for svc in spec.services]
314
314
 
315
315
  lines = [
316
316
  "[project]",
@@ -384,7 +384,7 @@ def render_workspace(output_dir: Path, *, git_init: bool = False) -> Path:
384
384
  # These are deterministic outputs of the spec — like docker-compose.yml.
385
385
  # User customization goes in scaffolded files (views, repositories, etc).
386
386
  for svc in spec.services:
387
- svc_dir = output_dir / "src" / svc.name
387
+ svc_dir = output_dir / "src" / svc.name.replace("-", "_")
388
388
  if not svc_dir.exists():
389
389
  continue
390
390
  svc_dir.mkdir(parents=True, exist_ok=True)
@@ -3,7 +3,7 @@
3
3
  Workspace layout contract::
4
4
 
5
5
  <ws-root>/
6
- src/<service-name>/ ← service source (views, settings, __init__)
6
+ src/<service_name_snake>/ ← service source (views, settings, __init__)
7
7
  tests/unit/<service_name_snake>/ ← unit tests (snake_case)
8
8
  tests/acceptance/<service_name_snake>/ ← acceptance test stub
9
9
  Dockerfile.<service-name> ← per-service Dockerfile
@@ -33,15 +33,14 @@ _AUGMENT_TEMPLATE_DIR = Path(__file__).resolve().parent.parent / "templates" / "
33
33
  def scaffold_service(service: ServiceNode, workspace_root: Path) -> None:
34
34
  """Scaffold a single service into the workspace layout.
35
35
 
36
- Skips silently if ``src/<service.name>/`` already exists (idempotent).
36
+ Skips silently if ``src/<service_name_snake>/`` already exists (idempotent).
37
37
  """
38
38
 
39
- src_dest = workspace_root / "src" / service.name
39
+ service_name_snake = service.name.replace("-", "_")
40
+ src_dest = workspace_root / "src" / service_name_snake
40
41
  if src_dest.exists():
41
42
  return
42
43
 
43
- service_name_snake = service.name.replace("-", "_")
44
-
45
44
  with tempfile.TemporaryDirectory() as tmp:
46
45
  tmp_path = Path(tmp)
47
46
 
@@ -235,7 +234,7 @@ def scaffold_augment(
235
234
  )
236
235
  return
237
236
 
238
- svc_dest = workspace_root / "src" / service.name
237
+ svc_dest = workspace_root / "src" / service.name.replace("-", "_")
239
238
  if not svc_dest.exists():
240
239
  return
241
240
 
@@ -109,7 +109,7 @@ def _augment_settings_fields(
109
109
  if ws_aug.name == "jwt-auth-provider":
110
110
  ws_fields["jwt_algorithm"] = '"RS256"'
111
111
  ws_fields["jwt_issuer"] = '"csrd-auth"'
112
- ws_fields["jwt_audience"] = '"csrd-services"'
112
+ ws_fields["jwt_audience"] = f'"{spec.workspace.name}"'
113
113
  ws_fields["jwt_ttl_seconds"] = "3600"
114
114
  ws_fields["jwt_key_size"] = "2048"
115
115
  ws_fields["jwt_key_rotation_interval"] = "86400"
@@ -152,7 +152,7 @@ def _augment_settings_fields(
152
152
  )
153
153
  augment_fields["jwt_algorithm"] = '"RS256"'
154
154
  augment_fields["jwt_issuer"] = '"csrd-auth"'
155
- augment_fields["jwt_audience"] = '"csrd-services"'
155
+ augment_fields["jwt_audience"] = f'"{spec.workspace.name}"'
156
156
 
157
157
  # Dynamic: delegate-config
158
158
  if augment.name == "delegate-config":
@@ -17,20 +17,52 @@ from ..settings import settings
17
17
  router = APIRouter(tags=["auth"])
18
18
 
19
19
 
20
+ # ---------------------------------------------------------------------------
21
+ # Request / response models
22
+ # ---------------------------------------------------------------------------
23
+
24
+
20
25
  class TokenRequest(BaseModel):
21
26
  username: str
22
27
  password: str
23
28
 
24
29
 
25
30
  class TokenResponse(BaseModel):
31
+ """JWT token issuance response."""
32
+
26
33
  access_token: str
27
34
  token_type: str = "bearer"
35
+ expires_in: int
28
36
 
29
37
 
30
38
  class VerifyRequest(BaseModel):
31
39
  token: str
32
40
 
33
41
 
42
+ class VerifyClaims(BaseModel):
43
+ """JWT claim fields returned by the verify endpoint."""
44
+
45
+ sub: str
46
+ user_name: str
47
+ authorities: list[str]
48
+ iat: int
49
+ exp: int
50
+ iss: str
51
+ aud: str
52
+
53
+
54
+ class VerifyResponse(BaseModel):
55
+ """Token verification response."""
56
+
57
+ active: bool
58
+ claims: VerifyClaims
59
+
60
+
61
+ # ---------------------------------------------------------------------------
62
+ # Endpoints
63
+ # ---------------------------------------------------------------------------
64
+
65
+
34
66
  @router.post("/api/token", response_model=TokenResponse)
35
67
  async def issue_token(body: TokenRequest) -> TokenResponse:
36
68
  """Validate credentials and issue a JWT access token."""
@@ -75,11 +107,11 @@ async def issue_token(body: TokenRequest) -> TokenResponse:
75
107
  headers={"kid": kid},
76
108
  )
77
109
 
78
- return TokenResponse(access_token=token)
110
+ return TokenResponse(access_token=token, expires_in=settings.jwt_ttl_seconds)
79
111
 
80
112
 
81
- @router.post("/api/verify")
82
- async def verify_token(body: VerifyRequest) -> dict:
113
+ @router.post("/api/verify", response_model=VerifyResponse)
114
+ async def verify_token(body: VerifyRequest) -> VerifyResponse:
83
115
  """Verify a JWT and return its claims."""
84
116
  adapter = await get_adapter()
85
117
 
@@ -106,16 +138,16 @@ async def verify_token(body: VerifyRequest) -> dict:
106
138
 
107
139
  public_key = RSAAlgorithm.from_jwk(jwk_data)
108
140
 
109
- payload = pyjwt.decode(
141
+ claims = pyjwt.decode(
110
142
  body.token,
111
143
  public_key,
112
144
  algorithms=[settings.jwt_algorithm],
113
145
  issuer=settings.jwt_issuer,
114
146
  audience=settings.jwt_audience,
115
147
  )
116
- return {"active": True, "claims": payload}
148
+ return VerifyResponse(active=True, claims=VerifyClaims(**claims))
117
149
 
118
150
  except pyjwt.ExpiredSignatureError:
119
- raise HTTPException(status_code=401, detail="Token has expired")
151
+ raise HTTPException(status_code=401, detail="Token has expired") from None
120
152
  except pyjwt.InvalidTokenError as exc:
121
- raise HTTPException(status_code=401, detail=f"Invalid token: {exc}")
153
+ raise HTTPException(status_code=401, detail=f"Invalid token: {exc}") from None
@@ -4,15 +4,24 @@ Consumers use ``JWKSKeyProvider`` to auto-discover keys from this endpoint.
4
4
  This file is scaffolded once and never overwritten.
5
5
  """
6
6
 
7
+ from typing import Any
8
+
7
9
  from fastapi import APIRouter
10
+ from pydantic import BaseModel
8
11
 
9
12
  from ..dependencies.db import get_adapter
10
13
 
11
14
  router = APIRouter(tags=["jwks"])
12
15
 
13
16
 
14
- @router.get("/.well-known/jwks.json")
15
- async def jwks() -> dict:
17
+ class JWKSResponse(BaseModel):
18
+ """JSON Web Key Set response (RFC 7517)."""
19
+
20
+ keys: list[dict[str, Any]]
21
+
22
+
23
+ @router.get("/.well-known/jwks.json", response_model=JWKSResponse)
24
+ async def jwks() -> JWKSResponse:
16
25
  """Return public keys for all active signing keys in JWK format.
17
26
 
18
27
  Consumers cache this response and refresh automatically when
@@ -24,4 +33,5 @@ async def jwks() -> dict:
24
33
 
25
34
  key_ring = KeyRingManager(adapter=adapter)
26
35
  await key_ring.initialize()
27
- return await key_ring.jwks_dict()
36
+ jwks_data = await key_ring.jwks_dict()
37
+ return JWKSResponse(keys=jwks_data["keys"])
@@ -12,17 +12,41 @@ from ..repositories.user_repository import UserRepository
12
12
  router = APIRouter(tags=["users"])
13
13
 
14
14
 
15
+ # ---------------------------------------------------------------------------
16
+ # Request / response models
17
+ # ---------------------------------------------------------------------------
18
+
19
+
15
20
  class SignupRequest(BaseModel):
16
21
  username: str
17
22
  password: str
18
23
 
19
24
 
25
+ class UserResponse(BaseModel):
26
+ """Basic user info returned after signup or lookup."""
27
+
28
+ id: str
29
+ username: str
30
+
31
+
32
+ class UserRolesResponse(BaseModel):
33
+ """User with their assigned roles/authorities."""
34
+
35
+ user_id: str
36
+ roles: list[str]
37
+
38
+
20
39
  class RoleRequest(BaseModel):
21
40
  role: str
22
41
 
23
42
 
24
- @router.post("/api/signup", status_code=201)
25
- async def signup(body: SignupRequest) -> dict:
43
+ # ---------------------------------------------------------------------------
44
+ # Endpoints
45
+ # ---------------------------------------------------------------------------
46
+
47
+
48
+ @router.post("/api/signup", status_code=201, response_model=UserResponse)
49
+ async def signup(body: SignupRequest) -> UserResponse:
26
50
  """Create a new user account."""
27
51
  adapter = await get_adapter()
28
52
  repo = UserRepository(adapter)
@@ -32,11 +56,11 @@ async def signup(body: SignupRequest) -> dict:
32
56
  raise HTTPException(status_code=409, detail="Username already taken")
33
57
 
34
58
  user = await repo.create_user(body.username, body.password)
35
- return {"id": user["id"], "username": user["username"]}
59
+ return UserResponse(id=user["id"], username=user["username"])
36
60
 
37
61
 
38
- @router.get("/api/users/{user_id}")
39
- async def get_user(user_id: str) -> dict:
62
+ @router.get("/api/users/{user_id}", response_model=UserResponse)
63
+ async def get_user(user_id: str) -> UserResponse:
40
64
  """Get user info by ID."""
41
65
  adapter = await get_adapter()
42
66
  repo = UserRepository(adapter)
@@ -45,11 +69,11 @@ async def get_user(user_id: str) -> dict:
45
69
  if user is None:
46
70
  raise HTTPException(status_code=404, detail="User not found")
47
71
 
48
- return dict(user)
72
+ return UserResponse(id=user["id"], username=user["username"])
49
73
 
50
74
 
51
- @router.get("/api/users/{user_id}/roles")
52
- async def get_user_roles(user_id: str) -> dict:
75
+ @router.get("/api/users/{user_id}/roles", response_model=UserRolesResponse)
76
+ async def get_user_roles(user_id: str) -> UserRolesResponse:
53
77
  """List a user's authorities/roles."""
54
78
  adapter = await get_adapter()
55
79
  repo = UserRepository(adapter)
@@ -59,11 +83,11 @@ async def get_user_roles(user_id: str) -> dict:
59
83
  raise HTTPException(status_code=404, detail="User not found")
60
84
 
61
85
  roles = await repo.get_roles(user_id)
62
- return {"user_id": user_id, "roles": roles}
86
+ return UserRolesResponse(user_id=user_id, roles=roles)
63
87
 
64
88
 
65
- @router.post("/api/users/{user_id}/roles", status_code=201)
66
- async def add_user_role(user_id: str, body: RoleRequest) -> dict:
89
+ @router.post("/api/users/{user_id}/roles", status_code=201, response_model=UserRolesResponse)
90
+ async def add_user_role(user_id: str, body: RoleRequest) -> UserRolesResponse:
67
91
  """Assign a role/authority to a user."""
68
92
  adapter = await get_adapter()
69
93
  repo = UserRepository(adapter)
@@ -74,4 +98,4 @@ async def add_user_role(user_id: str, body: RoleRequest) -> dict:
74
98
 
75
99
  await repo.add_role(user_id, body.role)
76
100
  roles = await repo.get_roles(user_id)
77
- return {"user_id": user_id, "roles": roles}
101
+ return UserRolesResponse(user_id=user_id, roles=roles)
@@ -2,10 +2,10 @@ FROM python:3.12-slim
2
2
 
3
3
  WORKDIR /app
4
4
 
5
- COPY ./src/{{cookiecutter.service_name}}/requirements.txt /app/requirements.txt
5
+ COPY ./src/{{cookiecutter.__service_name_snake}}/requirements.txt /app/requirements.txt
6
6
  RUN pip install --no-cache-dir -r /app/requirements.txt
7
7
 
8
- COPY ./src/{{cookiecutter.service_name}} /app/{{cookiecutter.__service_name_snake}}
8
+ COPY ./src/{{cookiecutter.__service_name_snake}} /app/{{cookiecutter.__service_name_snake}}
9
9
 
10
10
  ENV PORT={{ cookiecutter.port }}
11
11
 
@@ -0,0 +1,16 @@
1
+ from fastapi import APIRouter
2
+ from pydantic import BaseModel
3
+
4
+ router = APIRouter(tags=["Health"])
5
+
6
+
7
+ class HealthResponse(BaseModel):
8
+ """Health check response."""
9
+
10
+ status: str
11
+ service: str
12
+
13
+
14
+ @router.get("/health", response_model=HealthResponse)
15
+ def health() -> HealthResponse:
16
+ return HealthResponse(status="ok", service="{{ cookiecutter.service_name }}")
@@ -1,8 +0,0 @@
1
- from fastapi import APIRouter
2
-
3
- router = APIRouter(tags=["Health"])
4
-
5
-
6
- @router.get("/health")
7
- def health() -> dict[str, str]:
8
- return {"status": "ok", "service": "{{ cookiecutter.service_name }}"}
File without changes
File without changes