csrd-utils 0.3.62__tar.gz → 0.3.63__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 (129) hide show
  1. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/PKG-INFO +1 -1
  2. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/pyproject.toml +1 -1
  3. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/__main__.py +4 -0
  4. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/cluster.py +7 -1
  5. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/generator.py +1 -0
  6. csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service/cookiecutter.json +6 -0
  7. csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/README.md +26 -0
  8. csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +3 -0
  9. csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/dependencies/auth_service.py +55 -0
  10. csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/requirements.txt +6 -0
  11. csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/settings.py +12 -0
  12. csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +10 -0
  13. csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service/{{cookiecutter.__service_name_snake}}/views/unversioned/items_view.py +100 -0
  14. csrd_utils-0.3.63/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/.dockerignore +7 -0
  15. csrd_utils-0.3.63/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/Dockerfile +10 -0
  16. csrd_utils-0.3.63/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/__init__.py +23 -0
  17. csrd_utils-0.3.63/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +3 -0
  18. csrd_utils-0.3.63/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +8 -0
  19. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/.gitignore +0 -0
  20. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/README.md +0 -0
  21. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/__init__.py +0 -0
  22. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/audit.py +0 -0
  23. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/augmentor.py +0 -0
  24. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/doctor.py +0 -0
  25. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/caching/conftest.fragment.py +0 -0
  26. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/caching/docker-compose.fragment.yaml +0 -0
  27. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/caching/manifest.yaml +0 -0
  28. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/caching/requirements.fragment +0 -0
  29. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/caching/settings.fragment.py +0 -0
  30. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/caching/src/app/cache.py +0 -0
  31. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/caching/tests/test_cache.py +0 -0
  32. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/logging/conftest.fragment.py +0 -0
  33. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/logging/manifest.yaml +0 -0
  34. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/logging/requirements.fragment +0 -0
  35. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/logging/settings.fragment.py +0 -0
  36. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/logging/src/app/middleware/logging.py +0 -0
  37. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/logging/tests/test_logging_middleware.py +0 -0
  38. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/metrics/conftest.fragment.py +0 -0
  39. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/metrics/docker-compose.fragment.yaml +0 -0
  40. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/metrics/manifest.yaml +0 -0
  41. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/metrics/requirements.fragment +0 -0
  42. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/metrics/settings.fragment.py +0 -0
  43. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/metrics/src/app/middleware/metrics.py +0 -0
  44. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/metrics/tests/test_metrics_middleware.py +0 -0
  45. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/tracing/conftest.fragment.py +0 -0
  46. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/tracing/manifest.yaml +0 -0
  47. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/tracing/requirements.fragment +0 -0
  48. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/tracing/settings.fragment.py +0 -0
  49. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/tracing/src/app/middleware/tracing.py +0 -0
  50. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/tracing/tests/test_tracing_middleware.py +0 -0
  51. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/workers/conftest.fragment.py +0 -0
  52. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/workers/docker-compose.fragment.yaml +0 -0
  53. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/workers/manifest.yaml +0 -0
  54. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/workers/requirements.fragment +0 -0
  55. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/workers/settings.fragment.py +0 -0
  56. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/workers/src/app/workers/__init__.py +0 -0
  57. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/workers/src/app/workers/celery_app.py +0 -0
  58. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/workers/src/app/workers/tasks.py +0 -0
  59. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/features/workers/tests/test_workers.py +0 -0
  60. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/fragments.py +0 -0
  61. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/resources.py +0 -0
  62. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/README.md +0 -0
  63. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/cookiecutter.json +0 -0
  64. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/hooks/post_gen_project.py +0 -0
  65. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/.cookiecutterignore +0 -0
  66. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
  67. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
  68. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
  69. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
  70. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/cache.py +0 -0
  71. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/delegates/__init__.py +0 -0
  72. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/delegates/upstreams.py +0 -0
  73. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
  74. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/auth_service.py +0 -0
  75. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/delegates.py +0 -0
  76. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/item_repository.py +0 -0
  77. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/worker_broker.py +0 -0
  78. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/docker-compose.yml +0 -0
  79. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/middleware/__init__.py +0 -0
  80. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/middleware/logging.py +0 -0
  81. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
  82. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/repositories/item_repository.py +0 -0
  83. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
  84. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
  85. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/__init__.py +0 -0
  86. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/acceptance/__init__.py +0 -0
  87. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/acceptance/test_logging_middleware.py +0 -0
  88. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/conftest.py +0 -0
  89. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/test_items.py +0 -0
  90. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/__init__.py +0 -0
  91. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_cache.py +0 -0
  92. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_database_settings.py +0 -0
  93. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_delegates.py +0 -0
  94. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_settings_contracts.py +0 -0
  95. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_worker_broker.py +0 -0
  96. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
  97. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
  98. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
  99. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/items_view.py +0 -0
  100. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/workers/__init__.py +0 -0
  101. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/workers/tasks.py +0 -0
  102. {csrd_utils-0.3.62/src/csrd_utils/templates/platform-auth-service → csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service}/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
  103. {csrd_utils-0.3.62/src/csrd_utils/templates/platform-auth-service → csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service}/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
  104. {csrd_utils-0.3.62/src/csrd_utils/templates/platform-auth-service → csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service}/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
  105. {csrd_utils-0.3.62/src/csrd_utils/templates/platform-auth-service → csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service}/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
  106. {csrd_utils-0.3.62/src/csrd_utils/templates/platform-auth-service → csrd_utils-0.3.63/src/csrd_utils/templates/platform-app-service}/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
  107. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-auth-service/cookiecutter.json +0 -0
  108. {csrd_utils-0.3.62/src/csrd_utils/templates/platform-identity-service → csrd_utils-0.3.63/src/csrd_utils/templates/platform-auth-service}/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
  109. {csrd_utils-0.3.62/src/csrd_utils/templates/platform-identity-service → csrd_utils-0.3.63/src/csrd_utils/templates/platform-auth-service}/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
  110. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
  111. {csrd_utils-0.3.62/src/csrd_utils/templates/platform-identity-service → csrd_utils-0.3.63/src/csrd_utils/templates/platform-auth-service}/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
  112. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
  113. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
  114. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/repositories/token_repository.py +0 -0
  115. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
  116. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
  117. {csrd_utils-0.3.62/src/csrd_utils/templates/platform-identity-service → csrd_utils-0.3.63/src/csrd_utils/templates/platform-auth-service}/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
  118. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
  119. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-auth-service/{{cookiecutter.__service_name_snake}}/views/unversioned/auth_view.py +0 -0
  120. {csrd_utils-0.3.62/src/csrd_utils/templates/platform-identity-service → csrd_utils-0.3.63/src/csrd_utils/templates/platform-auth-service}/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
  121. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-identity-service/cookiecutter.json +0 -0
  122. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
  123. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
  124. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
  125. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/repositories/user_repository.py +0 -0
  126. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
  127. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
  128. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
  129. {csrd_utils-0.3.62 → csrd_utils-0.3.63}/src/csrd_utils/templates/platform-identity-service/{{cookiecutter.__service_name_snake}}/views/unversioned/users_view.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csrd-utils
3
- Version: 0.3.62
3
+ Version: 0.3.63
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.62"
3
+ version = "0.3.63"
4
4
  description = "CLI utilities for csrd service generation and feature augmentation"
5
5
  license = { text = "MIT" }
6
6
  requires-python = ">=3.12"
@@ -496,6 +496,10 @@ def _generate_services_from_cluster_spec(
496
496
  "identity-service",
497
497
  )
498
498
  extra["identity_service_url"] = f"http://{identity_name}:{identity_port}"
499
+ elif role == "app":
500
+ auth_port = next((port_map[n] for n in port_map if "auth" in n), 8081)
501
+ auth_name = next((n for n in port_map if "auth" in n), "auth-service")
502
+ extra["auth_service_url"] = f"http://{auth_name}:{auth_port}"
499
503
  result = generate_platform_service(
500
504
  name=name,
501
505
  output_dir=workspace_root,
@@ -30,7 +30,13 @@ DEFAULT_PORT_START = 8091
30
30
  PRESETS: dict[str, list[ServiceSpec]] = {
31
31
  "none": [],
32
32
  "authenticated-cluster": [
33
- {"name": "app-service", "type": "delegate", "port": 8080, "requires": ["auth-service"]},
33
+ {
34
+ "name": "app-service",
35
+ "type": "platform",
36
+ "role": "app",
37
+ "port": 8080,
38
+ "requires": ["auth-service"],
39
+ },
34
40
  {"name": "auth-service", "type": "platform", "role": "auth", "port": 8081, "requires": []},
35
41
  {
36
42
  "name": "identity-service",
@@ -254,6 +254,7 @@ def generate_service(
254
254
 
255
255
  #: Maps role names to the cookiecutter template directory names bundled under templates/.
256
256
  _PLATFORM_ROLE_TEMPLATES: dict[str, str] = {
257
+ "app": "platform-app-service",
257
258
  "auth": "platform-auth-service",
258
259
  "identity": "platform-identity-service",
259
260
  }
@@ -0,0 +1,6 @@
1
+ {
2
+ "service_name": "app-service",
3
+ "port": "8080",
4
+ "auth_service_url": "http://auth-service:8081",
5
+ "__service_name_snake": "{{ cookiecutter.service_name | replace('-', '_') }}"
6
+ }
@@ -0,0 +1,26 @@
1
+ # {{ cookiecutter.service_name }}
2
+
3
+ Platform app service with auth-guarded item endpoints.
4
+
5
+ ## Endpoints
6
+
7
+ - `GET /health` - liveness probe
8
+ - `POST /api/items` - create item (bearer required)
9
+ - `GET /api/items` - list items (bearer required)
10
+ - `GET /api/items/{entity_id}` - get item (bearer required)
11
+ - `PUT /api/items/{entity_id}` - update item (bearer required)
12
+ - `PUT /api/items/{entity_id}/upsert` - upsert item (bearer required)
13
+ - `DELETE /api/items/{entity_id}` - delete item (bearer required)
14
+
15
+ ## Configuration
16
+
17
+ | Variable | Default | Description |
18
+ |---|---|---|
19
+ | `AUTH_SERVICE_URL` | `{{ cookiecutter.auth_service_url }}` | Auth service verify endpoint base URL |
20
+
21
+ ## Run
22
+
23
+ ```bash
24
+ pip install -r requirements.txt
25
+ uvicorn {{ cookiecutter.__service_name_snake }}:build_app --factory --port {{ cookiecutter.port }}
26
+ ```
@@ -0,0 +1,3 @@
1
+ from .auth_service import VerifiedTokenDep
2
+
3
+ __all__ = ("VerifiedTokenDep",)
@@ -0,0 +1,55 @@
1
+ from typing import Annotated
2
+
3
+ import httpx
4
+ from fastapi import HTTPException, Security
5
+ from fastapi.requests import Request
6
+
7
+ from csrd.auth import CallbackAuthenticator, create_bearer_dependency
8
+ from csrd.models.claims import UserClaims
9
+ from csrd.versioning import find_token
10
+
11
+ from ..settings import settings
12
+
13
+
14
+ def _map_claims(payload: dict[str, object]) -> UserClaims:
15
+ claims = payload.get("claims") if isinstance(payload.get("claims"), dict) else payload
16
+ if not isinstance(claims, dict):
17
+ raise HTTPException(status_code=502, detail="invalid auth response")
18
+
19
+ authorities = claims.get("authorities") or claims.get("roles") or []
20
+ if isinstance(authorities, str):
21
+ authorities = authorities.split()
22
+
23
+ sub = str(claims.get("sub", ""))
24
+ user_name = str(claims.get("user_name") or sub)
25
+
26
+ return UserClaims(sub=sub, user_name=user_name, authorities=list(authorities))
27
+
28
+
29
+ async def _remote_verify(_: Request, token: str) -> UserClaims:
30
+ try:
31
+ async with httpx.AsyncClient(timeout=5.0) as client:
32
+ response = await client.post(
33
+ f"{settings.auth_service_url}/api/verify",
34
+ json={"token": token},
35
+ )
36
+ except httpx.ConnectError as exc:
37
+ raise HTTPException(status_code=503, detail="auth service unavailable") from exc
38
+
39
+ if response.status_code != 200:
40
+ raise HTTPException(status_code=401, detail="invalid token")
41
+
42
+ payload = response.json()
43
+ if not isinstance(payload, dict):
44
+ raise HTTPException(status_code=502, detail="invalid auth response")
45
+ return _map_claims(payload)
46
+
47
+
48
+ _authenticator = CallbackAuthenticator(callback=_remote_verify)
49
+
50
+ VerifiedTokenDep = Annotated[
51
+ UserClaims,
52
+ Security(create_bearer_dependency(_authenticator, token_finder=find_token)),
53
+ ]
54
+
55
+ __all__ = ("VerifiedTokenDep",)
@@ -0,0 +1,6 @@
1
+ fastapi>=0.115,<1
2
+ uvicorn[standard]>=0.30,<1
3
+ pydantic-settings>=2.6,<3
4
+ httpx>=0.27,<1
5
+ csrd-auth>=0.1.0,<1
6
+ csrd-versioning>=0.1.0,<1
@@ -0,0 +1,12 @@
1
+ from pydantic_settings import BaseSettings, SettingsConfigDict
2
+
3
+
4
+ class Settings(BaseSettings):
5
+ model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
6
+
7
+ app_name: str = "{{ cookiecutter.service_name }}"
8
+ port: int = {{ cookiecutter.port }}
9
+ auth_service_url: str = "{{ cookiecutter.auth_service_url }}"
10
+
11
+
12
+ settings = Settings()
@@ -0,0 +1,10 @@
1
+ from fastapi import FastAPI
2
+
3
+ from . import health_view, items_view
4
+
5
+ unversioned_app = FastAPI(title="{{ cookiecutter.service_name }}")
6
+
7
+ unversioned_app.include_router(health_view.router)
8
+ unversioned_app.include_router(items_view.router)
9
+
10
+ __all__ = ("unversioned_app",)
@@ -0,0 +1,100 @@
1
+ import uuid
2
+ from datetime import UTC, datetime
3
+
4
+ from fastapi import APIRouter, HTTPException
5
+ from pydantic import BaseModel
6
+
7
+ from ...dependencies import VerifiedTokenDep
8
+
9
+ router = APIRouter(prefix="/api", tags=["Items Endpoints"])
10
+
11
+ _ITEMS: dict[str, dict[str, str]] = {}
12
+
13
+
14
+ class CreateItemRequest(BaseModel):
15
+ name: str
16
+
17
+
18
+ class UpdateItemRequest(BaseModel):
19
+ name: str
20
+
21
+
22
+ class ItemResponse(BaseModel):
23
+ id: str
24
+ name: str
25
+ created_at: str
26
+
27
+
28
+ class ItemListResponse(BaseModel):
29
+ items: list[ItemResponse]
30
+
31
+
32
+ class ItemUpdateResponse(BaseModel):
33
+ id: str
34
+ name: str
35
+ updated: bool
36
+
37
+
38
+ class ItemUpsertResponse(BaseModel):
39
+ id: str
40
+ name: str
41
+ rows_affected: int
42
+
43
+
44
+ class ItemDeleteResponse(BaseModel):
45
+ id: str
46
+ deleted: bool
47
+
48
+
49
+ @router.post("/items", response_model=ItemResponse)
50
+ async def create_item(payload: CreateItemRequest, _verified: VerifiedTokenDep) -> ItemResponse:
51
+ item_id = str(uuid.uuid4())
52
+ created_at = datetime.now(UTC).isoformat()
53
+ item = {"id": item_id, "name": payload.name, "created_at": created_at}
54
+ _ITEMS[item_id] = item
55
+ return item
56
+
57
+
58
+ @router.get("/items", response_model=ItemListResponse)
59
+ async def list_items(_verified: VerifiedTokenDep) -> ItemListResponse:
60
+ return {"items": list(_ITEMS.values())}
61
+
62
+
63
+ @router.get("/items/{entity_id}", response_model=ItemResponse)
64
+ async def get_item(entity_id: str, _verified: VerifiedTokenDep) -> ItemResponse:
65
+ item = _ITEMS.get(entity_id)
66
+ if item is None:
67
+ raise HTTPException(status_code=404, detail="item not found")
68
+ return item
69
+
70
+
71
+ @router.put("/items/{entity_id}", response_model=ItemUpdateResponse)
72
+ async def update_item(
73
+ entity_id: str, payload: UpdateItemRequest, _verified: VerifiedTokenDep
74
+ ) -> ItemUpdateResponse:
75
+ item = _ITEMS.get(entity_id)
76
+ if item is None:
77
+ raise HTTPException(status_code=404, detail="item not found")
78
+ item["name"] = payload.name
79
+ return {"id": entity_id, "name": payload.name, "updated": True}
80
+
81
+
82
+ @router.put("/items/{entity_id}/upsert", response_model=ItemUpsertResponse)
83
+ async def upsert_item(
84
+ entity_id: str, payload: UpdateItemRequest, _verified: VerifiedTokenDep
85
+ ) -> ItemUpsertResponse:
86
+ existing = _ITEMS.get(entity_id)
87
+ if existing is None:
88
+ created_at = datetime.now(UTC).isoformat()
89
+ _ITEMS[entity_id] = {"id": entity_id, "name": payload.name, "created_at": created_at}
90
+ else:
91
+ existing["name"] = payload.name
92
+ return {"id": entity_id, "name": payload.name, "rows_affected": 1}
93
+
94
+
95
+ @router.delete("/items/{entity_id}", response_model=ItemDeleteResponse)
96
+ async def delete_item(entity_id: str, _verified: VerifiedTokenDep) -> ItemDeleteResponse:
97
+ rows = 1 if _ITEMS.pop(entity_id, None) is not None else 0
98
+ if rows == 0:
99
+ raise HTTPException(status_code=404, detail="item not found")
100
+ return {"id": entity_id, "deleted": True}
@@ -0,0 +1,10 @@
1
+ FROM python:3.12-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY . /app
6
+ RUN pip install --no-cache-dir -r /app/requirements.txt
7
+
8
+ ENV PORT={{ cookiecutter.port }}
9
+
10
+ CMD uvicorn {{cookiecutter.__service_name_snake}}:build_app --factory --host 0.0.0.0 --port ${PORT}
@@ -0,0 +1,23 @@
1
+ from fastapi import FastAPI
2
+
3
+ from csrd.versioning import (
4
+ UNVERSIONED,
5
+ VersionedApiConfig,
6
+ VersionedAppComposeConfig,
7
+ compose_versioned_apps,
8
+ )
9
+
10
+ from .views import unversioned_app
11
+
12
+
13
+ def build_app() -> FastAPI:
14
+ return compose_versioned_apps(
15
+ version_mapping={UNVERSIONED: unversioned_app},
16
+ config=VersionedAppComposeConfig(
17
+ title="{{ cookiecutter.service_name }}",
18
+ api=VersionedApiConfig(prefix="/", include_actuator_endpoints=False),
19
+ ),
20
+ )
21
+
22
+
23
+ __all__ = ("build_app",)
@@ -0,0 +1,3 @@
1
+ from .unversioned import unversioned_app
2
+
3
+ __all__ = ("unversioned_app",)
@@ -0,0 +1,8 @@
1
+ from fastapi import APIRouter
2
+
3
+ router = APIRouter(tags=["Health Endpoints"])
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