FastAPI-fastkit 1.3.0__py3-none-any.whl โ†’ 1.4.1__py3-none-any.whl

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 (338) hide show
  1. fastapi_fastkit/__init__.py +1 -1
  2. fastapi_fastkit/backend/inspection/__init__.py +26 -0
  3. fastapi_fastkit/backend/inspection/checks.py +349 -0
  4. fastapi_fastkit/backend/inspection/consistency.py +125 -0
  5. fastapi_fastkit/backend/inspection/context.py +71 -0
  6. fastapi_fastkit/backend/inspection/core.py +351 -0
  7. fastapi_fastkit/backend/inspection/docker.py +320 -0
  8. fastapi_fastkit/backend/inspection/freshness.py +145 -0
  9. fastapi_fastkit/backend/inspection/fsutils.py +139 -0
  10. fastapi_fastkit/backend/inspection/lint.py +103 -0
  11. fastapi_fastkit/backend/inspection/report.py +58 -0
  12. fastapi_fastkit/backend/inspection/smoke.py +381 -0
  13. fastapi_fastkit/backend/inspection/strategies.py +367 -0
  14. fastapi_fastkit/backend/inspector.py +18 -1400
  15. fastapi_fastkit/backend/interactive/__init__.py +6 -0
  16. fastapi_fastkit/backend/interactive/config_builder.py +45 -63
  17. fastapi_fastkit/backend/interactive/prompts.py +155 -6
  18. fastapi_fastkit/backend/interactive/selectors.py +18 -2
  19. fastapi_fastkit/backend/main.py +887 -99
  20. fastapi_fastkit/backend/package_managers/base.py +172 -0
  21. fastapi_fastkit/backend/package_managers/factory.py +5 -4
  22. fastapi_fastkit/backend/package_managers/pdm_manager.py +29 -82
  23. fastapi_fastkit/backend/package_managers/pip_manager.py +31 -85
  24. fastapi_fastkit/backend/package_managers/poetry_manager.py +70 -110
  25. fastapi_fastkit/backend/package_managers/uv_manager.py +43 -112
  26. fastapi_fastkit/backend/project_builder/__init__.py +8 -1
  27. fastapi_fastkit/backend/project_builder/config_generator.py +806 -450
  28. fastapi_fastkit/backend/project_builder/config_schema.py +384 -0
  29. fastapi_fastkit/backend/project_builder/dependency_collector.py +105 -66
  30. fastapi_fastkit/backend/project_builder/preset_layout.py +254 -28
  31. fastapi_fastkit/backend/scaffolder.py +578 -0
  32. fastapi_fastkit/backend/transducer.py +154 -22
  33. fastapi_fastkit/cli.py +434 -311
  34. fastapi_fastkit/core/settings.py +234 -45
  35. fastapi_fastkit/fastapi_project_template/README.md +26 -10
  36. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/README.md-tpl +3 -0
  37. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/pyproject.toml-tpl +21 -22
  38. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/requirements.txt-tpl +39 -36
  39. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/api/api.py-tpl +3 -0
  40. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/api/routes/items.py-tpl +1 -2
  41. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/core/config.py-tpl +5 -6
  42. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/crud/items.py-tpl +1 -2
  43. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/main.py-tpl +9 -1
  44. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/schemas/items.py-tpl +1 -2
  45. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/tests/conftest.py-tpl +0 -1
  46. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/.env-tpl +21 -0
  47. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/.gitignore-tpl +33 -0
  48. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/Dockerfile-tpl +18 -0
  49. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/README.md-tpl +210 -0
  50. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/alembic.ini-tpl +119 -0
  51. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/pyproject.toml-tpl +86 -0
  52. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/requirements.txt-tpl +23 -0
  53. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/scripts/format.sh-tpl +5 -0
  54. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/scripts/lint.sh-tpl +6 -0
  55. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/scripts/run-server.sh-tpl +8 -0
  56. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/scripts/test.sh-tpl +6 -0
  57. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/__init__.py-tpl +0 -0
  58. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/__init__.py-tpl +0 -0
  59. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/alembic/README-tpl +1 -0
  60. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/alembic/env.py-tpl +51 -0
  61. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/alembic/script.py.mako-tpl +26 -0
  62. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/alembic/versions/0001_initial_auth_schema.py-tpl +62 -0
  63. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/api/__init__.py-tpl +0 -0
  64. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/api/deps.py-tpl +91 -0
  65. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/api/health.py-tpl +11 -0
  66. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/api/router.py-tpl +17 -0
  67. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/core/__init__.py-tpl +0 -0
  68. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/core/config.py-tpl +64 -0
  69. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/core/security.py-tpl +100 -0
  70. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/db/__init__.py-tpl +0 -0
  71. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/db/session.py-tpl +36 -0
  72. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/__init__.py-tpl +0 -0
  73. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/__init__.py-tpl +0 -0
  74. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/models.py-tpl +25 -0
  75. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/repository.py-tpl +41 -0
  76. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/router.py-tpl +82 -0
  77. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/schemas.py-tpl +14 -0
  78. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/service.py-tpl +65 -0
  79. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/__init__.py-tpl +0 -0
  80. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/models.py-tpl +35 -0
  81. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/repository.py-tpl +33 -0
  82. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/router.py-tpl +71 -0
  83. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/schemas.py-tpl +29 -0
  84. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/service.py-tpl +55 -0
  85. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/main.py-tpl +69 -0
  86. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/template-config.yml-tpl +16 -0
  87. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/tests/__init__.py-tpl +0 -0
  88. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/tests/conftest.py-tpl +73 -0
  89. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/tests/test_auth.py-tpl +201 -0
  90. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/tests/test_health.py-tpl +15 -0
  91. fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/tests/test_users.py-tpl +77 -0
  92. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/pyproject.toml-tpl +21 -22
  93. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/requirements.txt-tpl +39 -36
  94. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/api/api.py-tpl +3 -0
  95. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/api/routes/items.py-tpl +3 -3
  96. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/core/config.py-tpl +5 -6
  97. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/crud/items.py-tpl +1 -2
  98. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/helper/pagination.py-tpl +8 -8
  99. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/main.py-tpl +9 -0
  100. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/schemas/base.py-tpl +1 -1
  101. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/schemas/items.py-tpl +1 -2
  102. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/tests/conftest.py-tpl +0 -1
  103. fastapi_fastkit/fastapi_project_template/fastapi-default/pyproject.toml-tpl +18 -19
  104. fastapi_fastkit/fastapi_project_template/fastapi-default/requirements.txt-tpl +37 -34
  105. fastapi_fastkit/fastapi_project_template/fastapi-default/src/api/api.py-tpl +3 -0
  106. fastapi_fastkit/fastapi_project_template/fastapi-default/src/api/routes/items.py-tpl +1 -2
  107. fastapi_fastkit/fastapi_project_template/fastapi-default/src/core/config.py-tpl +5 -6
  108. fastapi_fastkit/fastapi_project_template/fastapi-default/src/crud/items.py-tpl +1 -2
  109. fastapi_fastkit/fastapi_project_template/fastapi-default/src/main.py-tpl +9 -1
  110. fastapi_fastkit/fastapi_project_template/fastapi-default/src/schemas/items.py-tpl +1 -2
  111. fastapi_fastkit/fastapi_project_template/fastapi-default/tests/conftest.py-tpl +2 -3
  112. fastapi_fastkit/fastapi_project_template/fastapi-default/tests/test_items.py-tpl +0 -2
  113. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/Dockerfile-tpl +1 -1
  114. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/README.md-tpl +3 -0
  115. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/pyproject.toml-tpl +21 -22
  116. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/requirements.txt-tpl +41 -36
  117. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/api/api.py-tpl +3 -0
  118. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/api/routes/items.py-tpl +1 -2
  119. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/core/config.py-tpl +5 -6
  120. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/crud/items.py-tpl +1 -2
  121. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/main.py-tpl +9 -1
  122. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/schemas/items.py-tpl +1 -2
  123. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/tests/conftest.py-tpl +2 -3
  124. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/tests/test_items.py-tpl +0 -2
  125. fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/pyproject.toml-tpl +13 -14
  126. fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/requirements.txt-tpl +36 -10
  127. fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/api/router.py-tpl +3 -0
  128. fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/core/config.py-tpl +4 -4
  129. fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/db/memory.py-tpl +4 -3
  130. fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/domains/items/repository.py-tpl +4 -5
  131. fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/domains/items/router.py-tpl +2 -3
  132. fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/domains/items/service.py-tpl +2 -3
  133. fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/main.py-tpl +3 -0
  134. fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/tests/conftest.py-tpl +0 -1
  135. fastapi_fastkit/fastapi_project_template/fastapi-empty/pyproject.toml-tpl +14 -15
  136. fastapi_fastkit/fastapi_project_template/fastapi-empty/requirements.txt-tpl +36 -10
  137. fastapi_fastkit/fastapi_project_template/fastapi-empty/src/core/config.py-tpl +5 -6
  138. fastapi_fastkit/fastapi_project_template/fastapi-empty/src/main.py-tpl +3 -1
  139. fastapi_fastkit/fastapi_project_template/fastapi-empty/tests/conftest.py-tpl +0 -1
  140. fastapi_fastkit/fastapi_project_template/fastapi-empty/tests/test_main.py-tpl +0 -1
  141. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/.env-tpl +15 -0
  142. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/.gitignore-tpl +31 -0
  143. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/Dockerfile-tpl +18 -0
  144. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/README.md-tpl +193 -0
  145. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/pyproject.toml-tpl +76 -0
  146. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/requirements.txt-tpl +15 -0
  147. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/scripts/chat.sh-tpl +10 -0
  148. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/scripts/format.sh-tpl +5 -0
  149. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/scripts/lint.sh-tpl +6 -0
  150. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/scripts/run-server.sh-tpl +8 -0
  151. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/scripts/test.sh-tpl +6 -0
  152. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/__init__.py-tpl +0 -0
  153. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/__init__.py-tpl +0 -0
  154. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/api/__init__.py-tpl +0 -0
  155. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/api/chat.py-tpl +62 -0
  156. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/api/deps.py-tpl +23 -0
  157. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/api/health.py-tpl +11 -0
  158. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/api/router.py-tpl +13 -0
  159. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/core/__init__.py-tpl +0 -0
  160. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/core/config.py-tpl +67 -0
  161. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/llm/__init__.py-tpl +0 -0
  162. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/llm/agent.py-tpl +136 -0
  163. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/llm/client.py-tpl +30 -0
  164. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/llm/tools.py-tpl +131 -0
  165. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/main.py-tpl +53 -0
  166. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/memory/__init__.py-tpl +0 -0
  167. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/memory/base.py-tpl +27 -0
  168. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/memory/in_memory.py-tpl +32 -0
  169. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/schemas/__init__.py-tpl +0 -0
  170. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/schemas/chat.py-tpl +46 -0
  171. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/template-config.yml-tpl +16 -0
  172. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/__init__.py-tpl +0 -0
  173. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/conftest.py-tpl +158 -0
  174. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/test_chat.py-tpl +160 -0
  175. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/test_health.py-tpl +12 -0
  176. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/test_memory.py-tpl +38 -0
  177. fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/test_tools.py-tpl +37 -0
  178. fastapi_fastkit/fastapi_project_template/fastapi-mcp/.env-tpl +1 -1
  179. fastapi_fastkit/fastapi_project_template/fastapi-mcp/README.md-tpl +2 -2
  180. fastapi_fastkit/fastapi_project_template/fastapi-mcp/pyproject.toml-tpl +25 -26
  181. fastapi_fastkit/fastapi_project_template/fastapi-mcp/requirements.txt-tpl +65 -40
  182. fastapi_fastkit/fastapi_project_template/fastapi-mcp/setup.cfg-tpl +2 -3
  183. fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/api/api.py-tpl +3 -0
  184. fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/api/routes/auth.py-tpl +13 -14
  185. fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/api/routes/items.py-tpl +3 -4
  186. fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/auth/dependencies.py-tpl +6 -7
  187. fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/core/config.py-tpl +5 -6
  188. fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/main.py-tpl +4 -1
  189. fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/{mcp โ†’ mcp_server}/router.py-tpl +3 -5
  190. fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/schemas/items.py-tpl +6 -7
  191. fastapi_fastkit/fastapi_project_template/fastapi-mcp/tests/conftest.py-tpl +1 -1
  192. fastapi_fastkit/fastapi_project_template/fastapi-mcp/tests/test_auth.py-tpl +0 -1
  193. fastapi_fastkit/fastapi_project_template/fastapi-mcp/tests/test_items.py-tpl +0 -1
  194. fastapi_fastkit/fastapi_project_template/fastapi-mcp/tests/test_mcp.py-tpl +0 -1
  195. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/.env-tpl +2 -0
  196. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/Dockerfile-tpl +1 -1
  197. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/pyproject.toml-tpl +22 -23
  198. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/requirements.txt-tpl +44 -41
  199. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/alembic/env.py-tpl +1 -3
  200. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/alembic/versions/bedcdc35b64a_first_alembic.py-tpl +5 -6
  201. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/api/api.py-tpl +2 -0
  202. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/api/routes/items.py-tpl +2 -4
  203. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/core/config.py-tpl +1 -2
  204. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/core/db.py-tpl +1 -1
  205. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/crud/items.py-tpl +4 -6
  206. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/main.py-tpl +9 -0
  207. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/schemas/items.py-tpl +4 -5
  208. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/tests/conftest.py-tpl +1 -5
  209. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/tests/test_items.py-tpl +0 -2
  210. fastapi_fastkit/fastapi_project_template/fastapi-single-module/.env-tpl +1 -0
  211. fastapi_fastkit/fastapi_project_template/fastapi-single-module/.gitignore-tpl +30 -0
  212. fastapi_fastkit/fastapi_project_template/fastapi-single-module/pyproject.toml-tpl +3 -4
  213. fastapi_fastkit/fastapi_project_template/fastapi-single-module/requirements.txt-tpl +26 -6
  214. fastapi_fastkit/fastapi_project_template/fastapi-single-module/src/main.py-tpl +3 -0
  215. fastapi_fastkit/fastapi_project_template/fastapi-single-module/tests/__init__.py-tpl +0 -0
  216. fastapi_fastkit/fastapi_project_template/fastapi-single-module/tests/conftest.py-tpl +0 -1
  217. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/.env-tpl +7 -0
  218. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/.gitignore-tpl +35 -0
  219. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/Dockerfile-tpl +18 -0
  220. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/README.md-tpl +166 -0
  221. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/alembic.ini-tpl +44 -0
  222. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/pyproject.toml-tpl +82 -0
  223. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/requirements.txt-tpl +21 -0
  224. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/scripts/format.sh-tpl +5 -0
  225. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/scripts/lint.sh-tpl +6 -0
  226. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/scripts/migrate.sh-tpl +7 -0
  227. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/scripts/run-server.sh-tpl +8 -0
  228. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/scripts/test.sh-tpl +6 -0
  229. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/__init__.py-tpl +0 -0
  230. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/__init__.py-tpl +0 -0
  231. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/alembic/README-tpl +9 -0
  232. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/alembic/env.py-tpl +72 -0
  233. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/alembic/script.py.mako-tpl +27 -0
  234. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/alembic/versions/0001_create_items_table.py-tpl +38 -0
  235. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/api/__init__.py-tpl +0 -0
  236. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/api/health.py-tpl +11 -0
  237. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/api/router.py-tpl +15 -0
  238. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/core/__init__.py-tpl +0 -0
  239. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/core/config.py-tpl +62 -0
  240. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/crud/__init__.py-tpl +0 -0
  241. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/crud/base.py-tpl +62 -0
  242. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/crud/pagination.py-tpl +21 -0
  243. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/db/__init__.py-tpl +0 -0
  244. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/db/base.py-tpl +12 -0
  245. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/db/session.py-tpl +50 -0
  246. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/domains/__init__.py-tpl +0 -0
  247. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/domains/items/__init__.py-tpl +0 -0
  248. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/domains/items/crud.py-tpl +26 -0
  249. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/domains/items/models.py-tpl +70 -0
  250. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/domains/items/router.py-tpl +69 -0
  251. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/main.py-tpl +43 -0
  252. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/template-config.yml-tpl +16 -0
  253. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/tests/__init__.py-tpl +0 -0
  254. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/tests/conftest.py-tpl +60 -0
  255. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/tests/test_crud_base.py-tpl +43 -0
  256. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/tests/test_health.py-tpl +12 -0
  257. fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/tests/test_items.py-tpl +110 -0
  258. fastapi_fastkit/fastapi_project_template/modules/api/routes/new_route.py-tpl +2 -2
  259. fastapi_fastkit/fragments/README.md +90 -0
  260. fastapi_fastkit/fragments/auth/fastapi_users.py.j2 +8 -0
  261. fastapi_fastkit/fragments/auth/jwt.py.j2 +44 -0
  262. fastapi_fastkit/fragments/auth/oauth2.py.j2 +105 -0
  263. fastapi_fastkit/fragments/auth/session.py.j2 +67 -0
  264. fastapi_fastkit/fragments/db/mongodb.py.j2 +19 -0
  265. fastapi_fastkit/fragments/db/redis.py.j2 +26 -0
  266. fastapi_fastkit/fragments/db/sqlalchemy.py.j2 +45 -0
  267. fastapi_fastkit/fragments/docker/docker_compose.j2 +84 -0
  268. fastapi_fastkit/fragments/docker/dockerfile.j2 +19 -0
  269. fastapi_fastkit/fragments/features/cache.py.j2 +26 -0
  270. fastapi_fastkit/fragments/features/pagination.py.j2 +31 -0
  271. fastapi_fastkit/fragments/features/tasks_celery.py.j2 +50 -0
  272. fastapi_fastkit/fragments/features/tasks_dramatiq.py.j2 +59 -0
  273. fastapi_fastkit/fragments/features/websocket.py.j2 +66 -0
  274. fastapi_fastkit/fragments/header.j2 +4 -0
  275. fastapi_fastkit/fragments/logging/structured.py.j2 +88 -0
  276. fastapi_fastkit/fragments/main/imports/async_tasks.j2 +1 -0
  277. fastapi_fastkit/fragments/main/imports/caching.j2 +5 -0
  278. fastapi_fastkit/fragments/main/imports/fastapi_users.j2 +1 -0
  279. fastapi_fastkit/fragments/main/imports/jwt.j2 +1 -0
  280. fastapi_fastkit/fragments/main/imports/loguru.j2 +1 -0
  281. fastapi_fastkit/fragments/main/imports/mongodb.j2 +1 -0
  282. fastapi_fastkit/fragments/main/imports/oauth2.j2 +4 -0
  283. fastapi_fastkit/fragments/main/imports/opentelemetry.j2 +6 -0
  284. fastapi_fastkit/fragments/main/imports/pagination.j2 +3 -0
  285. fastapi_fastkit/fragments/main/imports/prometheus.j2 +1 -0
  286. fastapi_fastkit/fragments/main/imports/rate_limiting.j2 +3 -0
  287. fastapi_fastkit/fragments/main/imports/session_auth.j2 +4 -0
  288. fastapi_fastkit/fragments/main/imports/sqlalchemy.j2 +2 -0
  289. fastapi_fastkit/fragments/main/imports/structured_logging.j2 +1 -0
  290. fastapi_fastkit/fragments/main/imports/websocket.j2 +1 -0
  291. fastapi_fastkit/fragments/main/lifespan/caching.j2 +7 -0
  292. fastapi_fastkit/fragments/main/lifespan/mongodb.j2 +2 -0
  293. fastapi_fastkit/fragments/main/lifespan/prometheus.j2 +2 -0
  294. fastapi_fastkit/fragments/main/lifespan/sqlalchemy.j2 +2 -0
  295. fastapi_fastkit/fragments/main/setup/async_tasks.j2 +1 -0
  296. fastapi_fastkit/fragments/main/setup/caching.j2 +1 -0
  297. fastapi_fastkit/fragments/main/setup/cors.j2 +8 -0
  298. fastapi_fastkit/fragments/main/setup/oauth2.j2 +3 -0
  299. fastapi_fastkit/fragments/main/setup/opentelemetry.j2 +19 -0
  300. fastapi_fastkit/fragments/main/setup/pagination.j2 +2 -0
  301. fastapi_fastkit/fragments/main/setup/rate_limiting.j2 +3 -0
  302. fastapi_fastkit/fragments/main/setup/session_auth.j2 +6 -0
  303. fastapi_fastkit/fragments/main/setup/structured_logging.j2 +2 -0
  304. fastapi_fastkit/fragments/main/setup/websocket.j2 +1 -0
  305. fastapi_fastkit/fragments/main.py.j2 +57 -0
  306. fastapi_fastkit/fragments/migrations/alembic_ini.j2 +42 -0
  307. fastapi_fastkit/fragments/migrations/env.py.j2 +76 -0
  308. fastapi_fastkit/fragments/migrations/initial_revision.py.j2 +27 -0
  309. fastapi_fastkit/fragments/migrations/migrate_sh.j2 +34 -0
  310. fastapi_fastkit/fragments/migrations/script.py.mako.j2 +26 -0
  311. fastapi_fastkit/fragments/tasks/celery_worker.py.j2 +49 -0
  312. fastapi_fastkit/fragments/tasks/dramatiq_worker.py.j2 +41 -0
  313. fastapi_fastkit/fragments/test/factories.py.j2 +68 -0
  314. fastapi_fastkit/fragments/test/pytest_ini.j2 +16 -0
  315. fastapi_fastkit/fragments/test/test_factories.py.j2 +27 -0
  316. fastapi_fastkit/fragments/test/test_main.py.j2 +46 -0
  317. fastapi_fastkit/fragments/tooling/devcontainer.j2 +26 -0
  318. fastapi_fastkit/fragments/tooling/github_actions.j2 +37 -0
  319. fastapi_fastkit/fragments/tooling/makefile.j2 +40 -0
  320. fastapi_fastkit/fragments/tooling/pre_commit.j2 +36 -0
  321. fastapi_fastkit/fragments/tooling/ruff_toml.j2 +16 -0
  322. fastapi_fastkit/utils/config_file.py +263 -0
  323. fastapi_fastkit/utils/main.py +38 -0
  324. {fastapi_fastkit-1.3.0.dist-info โ†’ fastapi_fastkit-1.4.1.dist-info}/METADATA +49 -6
  325. fastapi_fastkit-1.4.1.dist-info/RECORD +484 -0
  326. {fastapi_fastkit-1.3.0.dist-info โ†’ fastapi_fastkit-1.4.1.dist-info}/WHEEL +1 -1
  327. fastapi_fastkit/fastapi_project_template/fastapi-async-crud/setup.py-tpl +0 -25
  328. fastapi_fastkit/fastapi_project_template/fastapi-custom-response/setup.py-tpl +0 -27
  329. fastapi_fastkit/fastapi_project_template/fastapi-default/setup.py-tpl +0 -22
  330. fastapi_fastkit/fastapi_project_template/fastapi-dockerized/setup.py-tpl +0 -22
  331. fastapi_fastkit/fastapi_project_template/fastapi-empty/setup.py-tpl +0 -22
  332. fastapi_fastkit/fastapi_project_template/fastapi-mcp/setup.py-tpl +0 -51
  333. fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/setup.py-tpl +0 -25
  334. fastapi_fastkit/fastapi_project_template/fastapi-single-module/setup.py-tpl +0 -17
  335. fastapi_fastkit-1.3.0.dist-info/RECORD +0 -287
  336. /fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/{mcp โ†’ mcp_server}/__init__.py-tpl +0 -0
  337. {fastapi_fastkit-1.3.0.dist-info โ†’ fastapi_fastkit-1.4.1.dist-info}/entry_points.txt +0 -0
  338. {fastapi_fastkit-1.3.0.dist-info โ†’ fastapi_fastkit-1.4.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,263 @@
1
+ # --------------------------------------------------------------------------
2
+ # Project configuration file (de)serialization for non-interactive ``init``.
3
+ #
4
+ # ``fastkit init --interactive`` builds a plain configuration dict; this
5
+ # module lets that same dict travel through a file so a project can be
6
+ # reproduced without answering a single prompt (``--config``), and so an
7
+ # interactive session can be captured for later reuse (``--save-config``).
8
+ #
9
+ # Supported formats are picked from the file extension: JSON and TOML are
10
+ # always available (both ship with the stdlib on Python 3.12), YAML only
11
+ # when PyYAML happens to be installed โ€” fastkit deliberately does not add it
12
+ # as a runtime dependency.
13
+ #
14
+ # @author bnbong bbbong9@gmail.com
15
+ # --------------------------------------------------------------------------
16
+ import importlib
17
+ import json
18
+ import os
19
+ import tomllib
20
+ from typing import Any, Dict, List, Tuple
21
+
22
+ from fastapi_fastkit.backend.interactive.validators import (
23
+ validate_email_format,
24
+ validate_project_name,
25
+ )
26
+ from fastapi_fastkit.backend.project_builder.config_schema import (
27
+ ConfigSchemaError,
28
+ normalize_project_config,
29
+ validate_project_config_schema,
30
+ )
31
+
32
+ JSON_EXTENSIONS: Tuple[str, ...] = (".json",)
33
+ TOML_EXTENSIONS: Tuple[str, ...] = (".toml",)
34
+ YAML_EXTENSIONS: Tuple[str, ...] = (".yaml", ".yml")
35
+
36
+ SUPPORTED_EXTENSIONS: Tuple[str, ...] = (
37
+ JSON_EXTENSIONS + TOML_EXTENSIONS + YAML_EXTENSIONS
38
+ )
39
+
40
+ # Keys the scaffolder needs; everything else in the file is passed through
41
+ # untouched so feature blocks stay forward-compatible.
42
+ REQUIRED_KEYS: Tuple[str, ...] = ("project_name", "author", "author_email")
43
+
44
+
45
+ class ConfigFileError(Exception):
46
+ """Raised when a project config file cannot be read, parsed or trusted."""
47
+
48
+
49
+ def _yaml_module() -> Any:
50
+ """Return the optional PyYAML module, or None when it isn't installed."""
51
+ try:
52
+ # Imported dynamically: PyYAML is optional, so a static import would
53
+ # make it look like a hard dependency to type checkers and readers.
54
+ return importlib.import_module("yaml")
55
+ except ImportError:
56
+ return None
57
+
58
+
59
+ def load_project_config(path: str) -> Dict[str, Any]:
60
+ """
61
+ Load a project configuration dict from a JSON / TOML / YAML file.
62
+
63
+ :param path: Path to the configuration file
64
+ :return: Configuration dictionary equivalent to the interactive builder's
65
+ :raises ConfigFileError: If the file is missing, of an unsupported format,
66
+ unparsable, or does not describe a mapping.
67
+ """
68
+ if not os.path.exists(path):
69
+ raise ConfigFileError(f"Config file not found: {path}")
70
+
71
+ extension = os.path.splitext(path)[1].lower()
72
+
73
+ if extension in JSON_EXTENSIONS:
74
+ raw = _load_json(path)
75
+ elif extension in TOML_EXTENSIONS:
76
+ raw = _load_toml(path)
77
+ elif extension in YAML_EXTENSIONS:
78
+ raw = _load_yaml(path)
79
+ else:
80
+ raise ConfigFileError(
81
+ f"Unsupported config file extension '{extension or path}'. "
82
+ f"Supported extensions: {', '.join(SUPPORTED_EXTENSIONS)}"
83
+ )
84
+
85
+ if not isinstance(raw, dict):
86
+ raise ConfigFileError(
87
+ f"Config file '{path}' must contain a mapping at its top level."
88
+ )
89
+
90
+ return raw
91
+
92
+
93
+ def _load_json(path: str) -> Any:
94
+ try:
95
+ with open(path, "r", encoding="utf-8") as f:
96
+ return json.load(f)
97
+ except (OSError, UnicodeDecodeError, json.JSONDecodeError) as e:
98
+ raise ConfigFileError(f"Could not parse JSON config '{path}': {e}")
99
+
100
+
101
+ def _load_toml(path: str) -> Any:
102
+ try:
103
+ with open(path, "rb") as f:
104
+ return tomllib.load(f)
105
+ except (OSError, tomllib.TOMLDecodeError) as e:
106
+ raise ConfigFileError(f"Could not parse TOML config '{path}': {e}")
107
+
108
+
109
+ def _load_yaml(path: str) -> Any:
110
+ yaml = _yaml_module()
111
+ if yaml is None:
112
+ raise ConfigFileError(
113
+ "YAML config files need PyYAML, which is not installed. "
114
+ "Install it (pip install pyyaml) or use a .json / .toml config file instead."
115
+ )
116
+ try:
117
+ with open(path, "r", encoding="utf-8") as f:
118
+ return yaml.safe_load(f)
119
+ except Exception as e:
120
+ # PyYAML raises its own YAMLError hierarchy; catching broadly keeps
121
+ # this import-optional module free of a yaml type import.
122
+ raise ConfigFileError(f"Could not parse YAML config '{path}': {e}")
123
+
124
+
125
+ def validate_project_config(config: Dict[str, Any]) -> List[str]:
126
+ """
127
+ Validate a loaded configuration against the interactive-mode rules.
128
+
129
+ Reuses ``interactive.validators`` so a file-driven run is held to exactly
130
+ the same standard as an answered prompt.
131
+
132
+ :param config: Configuration dictionary
133
+ :return: List of human-readable error messages (empty when the config is valid)
134
+ """
135
+ errors: List[str] = []
136
+
137
+ for key in REQUIRED_KEYS:
138
+ if not config.get(key):
139
+ errors.append(f"Missing required config key: '{key}'")
140
+
141
+ project_name = config.get("project_name")
142
+ if isinstance(project_name, str) and project_name:
143
+ is_valid, message = validate_project_name(project_name)
144
+ if not is_valid and message:
145
+ errors.append(message)
146
+
147
+ author_email = config.get("author_email")
148
+ if isinstance(author_email, str) and author_email:
149
+ if not validate_email_format(author_email):
150
+ errors.append(f"Invalid author email format: '{author_email}'")
151
+
152
+ # Feature selections are held to the catalog: an axis spelled in a shape
153
+ # the pipeline cannot read used to reach generation and produce a project
154
+ # whose ``main.py`` imported modules nobody wrote.
155
+ errors.extend(validate_project_config_schema(config))
156
+
157
+ return errors
158
+
159
+
160
+ def load_normalized_project_config(path: str) -> Dict[str, Any]:
161
+ """
162
+ Load a config file and return it in the canonical pipeline shape.
163
+
164
+ ``load_project_config`` deliberately hands back exactly what the file
165
+ said (so ``--save-config`` round-trips byte for byte); this wrapper is
166
+ what the generation pipeline consumes, because every consumer of a
167
+ configuration must see the same normalised selections.
168
+
169
+ :param path: Path to the configuration file
170
+ :return: Normalised configuration dictionary
171
+ :raises ConfigFileError: If the file cannot be read, parsed or trusted
172
+ """
173
+ raw = load_project_config(path)
174
+ try:
175
+ return normalize_project_config(raw)
176
+ except ConfigSchemaError as e:
177
+ raise ConfigFileError(f"Invalid project config '{path}': {e}")
178
+
179
+
180
+ def save_project_config(config: Dict[str, Any], path: str) -> None:
181
+ """
182
+ Write a configuration dict to a JSON / TOML / YAML file.
183
+
184
+ :param config: Configuration dictionary produced by the interactive builder
185
+ :param path: Destination path; the extension selects the format
186
+ :raises ConfigFileError: If the format is unsupported or the write fails
187
+ """
188
+ extension = os.path.splitext(path)[1].lower()
189
+
190
+ if extension in JSON_EXTENSIONS:
191
+ content = (
192
+ json.dumps(config, indent=2, sort_keys=True, ensure_ascii=False) + "\n"
193
+ )
194
+ elif extension in TOML_EXTENSIONS:
195
+ content = _dump_toml(config)
196
+ elif extension in YAML_EXTENSIONS:
197
+ yaml = _yaml_module()
198
+ if yaml is None:
199
+ raise ConfigFileError(
200
+ "Saving YAML config files needs PyYAML, which is not installed. "
201
+ "Use a .json / .toml path instead."
202
+ )
203
+ content = str(yaml.safe_dump(config, sort_keys=True, allow_unicode=True))
204
+ else:
205
+ raise ConfigFileError(
206
+ f"Unsupported config file extension '{extension or path}'. "
207
+ f"Supported extensions: {', '.join(SUPPORTED_EXTENSIONS)}"
208
+ )
209
+
210
+ try:
211
+ parent = os.path.dirname(os.path.abspath(path))
212
+ os.makedirs(parent, exist_ok=True)
213
+ with open(path, "w", encoding="utf-8") as f:
214
+ f.write(content)
215
+ except OSError as e:
216
+ raise ConfigFileError(f"Could not write config file '{path}': {e}")
217
+
218
+
219
+ def _dump_toml(config: Dict[str, Any]) -> str:
220
+ """
221
+ Serialize a configuration dict to TOML.
222
+
223
+ Python 3.12 ships a TOML reader but no writer, and fastkit may not add a
224
+ runtime dependency for one. The interactive config only ever holds
225
+ strings, booleans, numbers, string lists and one level of nested tables
226
+ (``database``), which this covers.
227
+ """
228
+ scalars: List[str] = []
229
+ tables: List[str] = []
230
+
231
+ for key in sorted(config):
232
+ value = config[key]
233
+ if isinstance(value, dict):
234
+ table_lines = [f"[{key}]"]
235
+ for sub_key in sorted(value):
236
+ table_lines.append(f"{sub_key} = {format_toml_value(value[sub_key])}")
237
+ tables.append("\n".join(table_lines))
238
+ else:
239
+ scalars.append(f"{key} = {format_toml_value(value)}")
240
+
241
+ sections = ["\n".join(scalars)] if scalars else []
242
+ sections.extend(tables)
243
+ return "\n\n".join(section for section in sections if section) + "\n"
244
+
245
+
246
+ def format_toml_value(value: Any) -> str:
247
+ """
248
+ Render a Python value as a TOML literal.
249
+
250
+ Shared with pyproject metadata injection so both writers escape and
251
+ quote values identically.
252
+
253
+ :param value: Value to render (bool / int / float / list / str)
254
+ :return: TOML literal string
255
+ """
256
+ if isinstance(value, bool):
257
+ return "true" if value else "false"
258
+ if isinstance(value, (int, float)):
259
+ return str(value)
260
+ if isinstance(value, (list, tuple)):
261
+ return "[" + ", ".join(format_toml_value(item) for item in value) + "]"
262
+ escaped = str(value).replace("\\", "\\\\").replace('"', '\\"')
263
+ return f'"{escaped}"'
@@ -356,3 +356,41 @@ def _pyproject_text_marks_fastkit(pyproject_path: str) -> bool:
356
356
  if FASTKIT_DESCRIPTION_MARKER.lower() in content:
357
357
  return True
358
358
  return False
359
+
360
+
361
+ def read_fastkit_metadata(project_dir: str) -> Dict[str, Any]:
362
+ """Read the ``[tool.fastapi-fastkit]`` block of a generated project.
363
+
364
+ The block is the shared contract between generation (``init`` /
365
+ ``startdemo``) and the commands that operate on an existing project
366
+ (``runserver``, ``addroute``): it records the template, preset,
367
+ package manager, selected features and โ€” most importantly โ€” the
368
+ ``app_module`` entrypoint, so those commands no longer have to
369
+ re-derive the layout heuristically.
370
+
371
+ :param project_dir: Path to the generated project directory
372
+ :return: The metadata mapping, or an empty dict when the project has no
373
+ readable ``pyproject.toml`` / no fastkit block.
374
+ """
375
+ pyproject_path = os.path.join(project_dir, "pyproject.toml")
376
+ if not os.path.exists(pyproject_path):
377
+ return {}
378
+
379
+ try:
380
+ with open(pyproject_path, "rb") as f:
381
+ data = tomllib.load(f)
382
+ except (OSError, tomllib.TOMLDecodeError, UnicodeDecodeError) as e:
383
+ debug_log(
384
+ f"Could not read fastkit metadata from {pyproject_path}: {e}", "warning"
385
+ )
386
+ return {}
387
+
388
+ tool_section = data.get("tool", {})
389
+ if not isinstance(tool_section, dict):
390
+ return {}
391
+
392
+ metadata = tool_section.get(FASTKIT_TOOL_SECTION, {})
393
+ if not isinstance(metadata, dict):
394
+ return {}
395
+
396
+ return dict(metadata)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FastAPI-fastkit
3
- Version: 1.3.0
3
+ Version: 1.4.1
4
4
  Summary: Fast, easy-to-use starter kit for new users of Python and FastAPI
5
5
  Author-Email: bnbong <bbbong9@gmail.com>
6
6
  License: MIT
@@ -11,6 +11,7 @@ Project-URL: Changelog, https://bnbong.github.io/FastAPI-fastkit/changelog/
11
11
  Requires-Python: >=3.12
12
12
  Requires-Dist: click>=8.1.7
13
13
  Requires-Dist: rich>=13.9.2
14
+ Requires-Dist: jinja2>=3.1
14
15
  Provides-Extra: dev
15
16
  Requires-Dist: pytest>=9.0.3; extra == "dev"
16
17
  Requires-Dist: pytest-cov>=6.2.1; extra == "dev"
@@ -19,10 +20,11 @@ Requires-Dist: pre-commit>=4.0.1; extra == "dev"
19
20
  Requires-Dist: mypy>=1.12.0; extra == "dev"
20
21
  Requires-Dist: isort>=5.13.2; extra == "dev"
21
22
  Requires-Dist: pygments>=2.20.0; extra == "dev"
23
+ Requires-Dist: types-pyyaml>=6.0.12.20260408; extra == "dev"
22
24
  Description-Content-Type: text/markdown
23
25
 
24
26
  <p align="center">
25
- <img align="top" width="70%" src="https://bnbong.github.io/projects/img/fastkit_general_logo.png" alt="FastAPI-fastkit"/>
27
+ <img align="top" width="70%" src=".github/fastkit_general_logo.png" alt="FastAPI-fastkit"/>
26
28
  </p>
27
29
  <p align="center">
28
30
  <em><b>FastAPI-fastkit</b>: Fast, easy-to-use starter kit for new users of Python and FastAPI</em>
@@ -57,6 +59,8 @@ This project was inspired by the `SpringBoot initializer` & Python Django's `dja
57
59
  - **๐Ÿ” Automated template quality assurance** : Weekly automated testing ensures all templates remain functional and up-to-date
58
60
  - **๐Ÿš€ Multiple project templates** : Choose from various pre-configured templates for different use cases (async CRUD, Docker, PostgreSQL, etc.)
59
61
  - **๐Ÿ“ฆ Multiple package manager support** : Choose your preferred Python package manager (pip, uv, pdm, poetry) for dependency management
62
+ - **๐Ÿงพ Reproducible project configs** : Save an interactive session to a `.json` / `.toml` / `.yaml` file and replay it with `fastkit init --config`
63
+ - **๐Ÿท๏ธ Self-describing projects** : Every generated project records its template, preset, package manager, entrypoint and selected features in a `[tool.fastapi-fastkit]` block that `runserver` and `addroute` read back
60
64
 
61
65
  ## Installation
62
66
 
@@ -78,17 +82,27 @@ $ pip install FastAPI-fastkit
78
82
  ```console
79
83
  fastkit init [OPTIONS]
80
84
  ```
81
- - What it does: Scaffolds an empty FastAPI project, creates a virtual environment, installs dependencies
85
+ > [!TIP]
86
+ > Scaffolds an empty FastAPI project, creates a virtual environment, installs dependencies
87
+
82
88
  - Key options:
83
89
  - `--project-name`, `--author`, `--author-email`, `--description`
84
90
  - `--package-manager` [pip|uv|pdm|poetry]
91
+ - `--config <path>`: create the project from a saved config file (`.json` / `.toml`, and `.yaml` when PyYAML is installed) with no prompts
92
+ - `--save-config <path>`: with `--interactive`, record the answers for later reuse
93
+ - `--dry-run`: print the files and packages that would be created, write nothing
94
+ - `--no-venv`: skip virtual environment creation (implies `--no-install`)
95
+ - `--no-install`: skip dependency installation
96
+ - `--yes` / `-y`: skip the "Overwrite these files?" confirmation when deploying in place
85
97
  - Stack selection: `minimal` | `standard` | `full` (interactive)
86
98
 
87
99
  ### Create a project with interactive mode
88
100
  ```console
89
101
  fastkit init --interactive
90
102
  ```
91
- - What it does: Guided step-by-step project setup with intelligent feature selection
103
+ > [!TIP]
104
+ > Guided step-by-step project setup with intelligent feature selection
105
+
92
106
  - Features:
93
107
  - **Architecture preset**: `minimal` | `single-module` | `classic-layered` | `domain-starter` (default)
94
108
  - **Database selection**: PostgreSQL, MySQL, MongoDB, Redis, SQLite
@@ -98,23 +112,33 @@ fastkit init --interactive
98
112
  - **Monitoring**: Loguru, OpenTelemetry, Prometheus
99
113
  - **Testing**: Basic (pytest), Coverage, Advanced (with faker, factory-boy)
100
114
  - **Utilities**: CORS, Rate-Limiting, Pagination, WebSocket
115
+ - **Logging**: structured JSON logging with a request-id middleware
116
+ - **Migrations**: Alembic (async env, baseline revision)
117
+ - **Tooling**: ruff, pre-commit, GitHub Actions, devcontainer, Makefile (multi-select)
101
118
  - **Deployment**: Docker, docker-compose with auto-generated configs
102
119
  - **Package manager**: pip, uv, pdm, poetry
103
120
  - **Custom packages**: Add your own dependencies
104
- - Auto-generates (varies by preset โ€” see [the matrix](https://bnbong.github.io/FastAPI-fastkit/reference/preset-feature-matrix/) for details):
121
+ - Auto-generates (varies by preset - see [the matrix](https://bnbong.github.io/FastAPI-fastkit/reference/preset-feature-matrix/) for details):
105
122
  - `main.py` regenerated from selected features for `minimal` / `single-module`; preserved as-shipped for `classic-layered` / `domain-starter`
106
123
  - Database and authentication configuration files at preset-specific paths
107
124
  - Docker deployment files (`Dockerfile`, `docker-compose.yml`) with the preset's correct uvicorn entrypoint
108
125
  - Test configuration (pytest with coverage)
126
+ - `/health` and `/ready` endpoints on every generated project
127
+ - Real working code โ€” not just installed packages โ€” for background tasks, caching, WebSocket, pagination, OpenTelemetry, OAuth2 and session-based auth
128
+ - `--dry-run` previews the exact file tree a run would create, including logging/migrations/tooling artifacts
109
129
 
110
130
  ### Create a project from a template
111
131
  ```console
112
132
  fastkit startdemo [TEMPLATE] [OPTIONS]
113
133
  ```
114
- - What it does: Creates a project from a template (e.g., `fastapi-default`) and installs dependencies
134
+ > [!TIP]
135
+ > Creates a project from a template (e.g., `fastapi-default`) and installs dependencies
136
+
115
137
  - Key options:
116
138
  - `--project-name`, `--author`, `--author-email`, `--description`
117
139
  - `--package-manager` [pip|uv|pdm|poetry]
140
+ - `--dry-run`, `--no-venv`, `--no-install`, `--yes`/`-y` โ€” same meaning as on `init`
141
+ - Refuses to run if the target project directory already exists (`--dry-run` excepted)
118
142
  - Tip: List available templates with `fastkit list-templates`
119
143
 
120
144
  ### Add a new route
@@ -136,6 +160,25 @@ fastkit runserver [OPTIONS]
136
160
  fastkit list-templates
137
161
  ```
138
162
 
163
+ Available templates:
164
+
165
+ | Template | Description | Notes |
166
+ |---|---|---|
167
+ | [`fastapi-default`](src/fastapi_fastkit/fastapi_project_template/fastapi-default/README.md-tpl) | Simple FastAPI project with a classic layered layout | Good first choice |
168
+ | [`fastapi-empty`](src/fastapi_fastkit/fastapi_project_template/fastapi-empty/README.md-tpl) | Minimal FastAPI template | Base for `minimal` preset |
169
+ | [`fastapi-single-module`](src/fastapi_fastkit/fastapi_project_template/fastapi-single-module/README.md-tpl) | Single-file FastAPI app | Base for `single-module` preset |
170
+ | [`fastapi-domain-starter`](src/fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/README.md-tpl) | Domain-oriented, pyproject-first starter for medium-sized APIs | Base for `domain-starter` preset |
171
+ | [`fastapi-auth-jwt`](src/fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/README.md-tpl) | JWT authentication with refresh-token rotation, argon2 hashing and scopes | New in v1.4.0 |
172
+ | [`fastapi-sqlmodel`](src/fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/README.md-tpl) | Async SQLModel + Alembic migrations + generic CRUD with pagination | New in v1.4.0 |
173
+ | [`fastapi-llm-agent`](src/fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/README.md-tpl) | Streaming Claude chat agent (SSE) with a tool-call loop | New in v1.4.0 |
174
+ | [`fastapi-mcp`](src/fastapi_fastkit/fastapi_project_template/fastapi-mcp/README.md-tpl) | FastAPI app exposed as an MCP server | |
175
+ | [`fastapi-psql-orm`](src/fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/README.md-tpl) | Item management API with PostgreSQL, SQLModel, Alembic and docker-compose | Requires Docker |
176
+ | [`fastapi-custom-response`](src/fastapi_fastkit/fastapi_project_template/fastapi-custom-response/README.md-tpl) | Item management API with a custom response envelope, error handling and pagination | |
177
+ | [`fastapi-async-crud`](src/fastapi_fastkit/fastapi_project_template/fastapi-async-crud/README.md-tpl) | Async item management API | **Deprecated** โ€” use `fastapi-sqlmodel` |
178
+ | [`fastapi-dockerized`](src/fastapi_fastkit/fastapi_project_template/fastapi-dockerized/README.md-tpl) | Dockerized item management API | **Deprecated** โ€” use `fastapi-default` with the Docker option in `init --interactive` |
179
+
180
+ Deprecated templates still work but are no longer recommended starting points. See [Which starter should I choose?](https://bnbong.github.io/FastAPI-fastkit/user-guide/choosing-a-starter/) for a decision guide.
181
+
139
182
  ### Delete a project
140
183
  ```console
141
184
  fastkit deleteproject <project_name>