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.
- fastapi_fastkit/__init__.py +1 -1
- fastapi_fastkit/backend/inspection/__init__.py +26 -0
- fastapi_fastkit/backend/inspection/checks.py +349 -0
- fastapi_fastkit/backend/inspection/consistency.py +125 -0
- fastapi_fastkit/backend/inspection/context.py +71 -0
- fastapi_fastkit/backend/inspection/core.py +351 -0
- fastapi_fastkit/backend/inspection/docker.py +320 -0
- fastapi_fastkit/backend/inspection/freshness.py +145 -0
- fastapi_fastkit/backend/inspection/fsutils.py +139 -0
- fastapi_fastkit/backend/inspection/lint.py +103 -0
- fastapi_fastkit/backend/inspection/report.py +58 -0
- fastapi_fastkit/backend/inspection/smoke.py +381 -0
- fastapi_fastkit/backend/inspection/strategies.py +367 -0
- fastapi_fastkit/backend/inspector.py +18 -1400
- fastapi_fastkit/backend/interactive/__init__.py +6 -0
- fastapi_fastkit/backend/interactive/config_builder.py +45 -63
- fastapi_fastkit/backend/interactive/prompts.py +155 -6
- fastapi_fastkit/backend/interactive/selectors.py +18 -2
- fastapi_fastkit/backend/main.py +887 -99
- fastapi_fastkit/backend/package_managers/base.py +172 -0
- fastapi_fastkit/backend/package_managers/factory.py +5 -4
- fastapi_fastkit/backend/package_managers/pdm_manager.py +29 -82
- fastapi_fastkit/backend/package_managers/pip_manager.py +31 -85
- fastapi_fastkit/backend/package_managers/poetry_manager.py +70 -110
- fastapi_fastkit/backend/package_managers/uv_manager.py +43 -112
- fastapi_fastkit/backend/project_builder/__init__.py +8 -1
- fastapi_fastkit/backend/project_builder/config_generator.py +806 -450
- fastapi_fastkit/backend/project_builder/config_schema.py +384 -0
- fastapi_fastkit/backend/project_builder/dependency_collector.py +105 -66
- fastapi_fastkit/backend/project_builder/preset_layout.py +254 -28
- fastapi_fastkit/backend/scaffolder.py +578 -0
- fastapi_fastkit/backend/transducer.py +154 -22
- fastapi_fastkit/cli.py +434 -311
- fastapi_fastkit/core/settings.py +234 -45
- fastapi_fastkit/fastapi_project_template/README.md +26 -10
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/README.md-tpl +3 -0
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/pyproject.toml-tpl +21 -22
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/requirements.txt-tpl +39 -36
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/api/api.py-tpl +3 -0
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/api/routes/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/core/config.py-tpl +5 -6
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/crud/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/main.py-tpl +9 -1
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/src/schemas/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/tests/conftest.py-tpl +0 -1
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/.env-tpl +21 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/.gitignore-tpl +33 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/Dockerfile-tpl +18 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/README.md-tpl +210 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/alembic.ini-tpl +119 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/pyproject.toml-tpl +86 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/requirements.txt-tpl +23 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/scripts/format.sh-tpl +5 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/scripts/lint.sh-tpl +6 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/scripts/run-server.sh-tpl +8 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/scripts/test.sh-tpl +6 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/alembic/README-tpl +1 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/alembic/env.py-tpl +51 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/alembic/script.py.mako-tpl +26 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/alembic/versions/0001_initial_auth_schema.py-tpl +62 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/api/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/api/deps.py-tpl +91 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/api/health.py-tpl +11 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/api/router.py-tpl +17 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/core/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/core/config.py-tpl +64 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/core/security.py-tpl +100 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/db/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/db/session.py-tpl +36 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/models.py-tpl +25 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/repository.py-tpl +41 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/router.py-tpl +82 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/schemas.py-tpl +14 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/auth/service.py-tpl +65 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/models.py-tpl +35 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/repository.py-tpl +33 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/router.py-tpl +71 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/schemas.py-tpl +29 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/domains/users/service.py-tpl +55 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/src/app/main.py-tpl +69 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/template-config.yml-tpl +16 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/tests/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/tests/conftest.py-tpl +73 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/tests/test_auth.py-tpl +201 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/tests/test_health.py-tpl +15 -0
- fastapi_fastkit/fastapi_project_template/fastapi-auth-jwt/tests/test_users.py-tpl +77 -0
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/pyproject.toml-tpl +21 -22
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/requirements.txt-tpl +39 -36
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/api/api.py-tpl +3 -0
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/api/routes/items.py-tpl +3 -3
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/core/config.py-tpl +5 -6
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/crud/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/helper/pagination.py-tpl +8 -8
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/main.py-tpl +9 -0
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/schemas/base.py-tpl +1 -1
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/src/schemas/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/tests/conftest.py-tpl +0 -1
- fastapi_fastkit/fastapi_project_template/fastapi-default/pyproject.toml-tpl +18 -19
- fastapi_fastkit/fastapi_project_template/fastapi-default/requirements.txt-tpl +37 -34
- fastapi_fastkit/fastapi_project_template/fastapi-default/src/api/api.py-tpl +3 -0
- fastapi_fastkit/fastapi_project_template/fastapi-default/src/api/routes/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-default/src/core/config.py-tpl +5 -6
- fastapi_fastkit/fastapi_project_template/fastapi-default/src/crud/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-default/src/main.py-tpl +9 -1
- fastapi_fastkit/fastapi_project_template/fastapi-default/src/schemas/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-default/tests/conftest.py-tpl +2 -3
- fastapi_fastkit/fastapi_project_template/fastapi-default/tests/test_items.py-tpl +0 -2
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/Dockerfile-tpl +1 -1
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/README.md-tpl +3 -0
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/pyproject.toml-tpl +21 -22
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/requirements.txt-tpl +41 -36
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/api/api.py-tpl +3 -0
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/api/routes/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/core/config.py-tpl +5 -6
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/crud/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/main.py-tpl +9 -1
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/src/schemas/items.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/tests/conftest.py-tpl +2 -3
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/tests/test_items.py-tpl +0 -2
- fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/pyproject.toml-tpl +13 -14
- fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/requirements.txt-tpl +36 -10
- fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/api/router.py-tpl +3 -0
- fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/core/config.py-tpl +4 -4
- fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/db/memory.py-tpl +4 -3
- fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/domains/items/repository.py-tpl +4 -5
- fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/domains/items/router.py-tpl +2 -3
- fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/domains/items/service.py-tpl +2 -3
- fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/src/app/main.py-tpl +3 -0
- fastapi_fastkit/fastapi_project_template/fastapi-domain-starter/tests/conftest.py-tpl +0 -1
- fastapi_fastkit/fastapi_project_template/fastapi-empty/pyproject.toml-tpl +14 -15
- fastapi_fastkit/fastapi_project_template/fastapi-empty/requirements.txt-tpl +36 -10
- fastapi_fastkit/fastapi_project_template/fastapi-empty/src/core/config.py-tpl +5 -6
- fastapi_fastkit/fastapi_project_template/fastapi-empty/src/main.py-tpl +3 -1
- fastapi_fastkit/fastapi_project_template/fastapi-empty/tests/conftest.py-tpl +0 -1
- fastapi_fastkit/fastapi_project_template/fastapi-empty/tests/test_main.py-tpl +0 -1
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/.env-tpl +15 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/.gitignore-tpl +31 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/Dockerfile-tpl +18 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/README.md-tpl +193 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/pyproject.toml-tpl +76 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/requirements.txt-tpl +15 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/scripts/chat.sh-tpl +10 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/scripts/format.sh-tpl +5 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/scripts/lint.sh-tpl +6 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/scripts/run-server.sh-tpl +8 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/scripts/test.sh-tpl +6 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/api/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/api/chat.py-tpl +62 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/api/deps.py-tpl +23 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/api/health.py-tpl +11 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/api/router.py-tpl +13 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/core/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/core/config.py-tpl +67 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/llm/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/llm/agent.py-tpl +136 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/llm/client.py-tpl +30 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/llm/tools.py-tpl +131 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/main.py-tpl +53 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/memory/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/memory/base.py-tpl +27 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/memory/in_memory.py-tpl +32 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/schemas/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/src/app/schemas/chat.py-tpl +46 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/template-config.yml-tpl +16 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/conftest.py-tpl +158 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/test_chat.py-tpl +160 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/test_health.py-tpl +12 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/test_memory.py-tpl +38 -0
- fastapi_fastkit/fastapi_project_template/fastapi-llm-agent/tests/test_tools.py-tpl +37 -0
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/.env-tpl +1 -1
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/README.md-tpl +2 -2
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/pyproject.toml-tpl +25 -26
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/requirements.txt-tpl +65 -40
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/setup.cfg-tpl +2 -3
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/api/api.py-tpl +3 -0
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/api/routes/auth.py-tpl +13 -14
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/api/routes/items.py-tpl +3 -4
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/auth/dependencies.py-tpl +6 -7
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/core/config.py-tpl +5 -6
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/main.py-tpl +4 -1
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/{mcp → mcp_server}/router.py-tpl +3 -5
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/schemas/items.py-tpl +6 -7
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/tests/conftest.py-tpl +1 -1
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/tests/test_auth.py-tpl +0 -1
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/tests/test_items.py-tpl +0 -1
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/tests/test_mcp.py-tpl +0 -1
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/.env-tpl +2 -0
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/Dockerfile-tpl +1 -1
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/pyproject.toml-tpl +22 -23
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/requirements.txt-tpl +44 -41
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/alembic/env.py-tpl +1 -3
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/alembic/versions/bedcdc35b64a_first_alembic.py-tpl +5 -6
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/api/api.py-tpl +2 -0
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/api/routes/items.py-tpl +2 -4
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/core/config.py-tpl +1 -2
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/core/db.py-tpl +1 -1
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/crud/items.py-tpl +4 -6
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/main.py-tpl +9 -0
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/src/schemas/items.py-tpl +4 -5
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/tests/conftest.py-tpl +1 -5
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/tests/test_items.py-tpl +0 -2
- fastapi_fastkit/fastapi_project_template/fastapi-single-module/.env-tpl +1 -0
- fastapi_fastkit/fastapi_project_template/fastapi-single-module/.gitignore-tpl +30 -0
- fastapi_fastkit/fastapi_project_template/fastapi-single-module/pyproject.toml-tpl +3 -4
- fastapi_fastkit/fastapi_project_template/fastapi-single-module/requirements.txt-tpl +26 -6
- fastapi_fastkit/fastapi_project_template/fastapi-single-module/src/main.py-tpl +3 -0
- fastapi_fastkit/fastapi_project_template/fastapi-single-module/tests/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-single-module/tests/conftest.py-tpl +0 -1
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/.env-tpl +7 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/.gitignore-tpl +35 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/Dockerfile-tpl +18 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/README.md-tpl +166 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/alembic.ini-tpl +44 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/pyproject.toml-tpl +82 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/requirements.txt-tpl +21 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/scripts/format.sh-tpl +5 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/scripts/lint.sh-tpl +6 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/scripts/migrate.sh-tpl +7 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/scripts/run-server.sh-tpl +8 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/scripts/test.sh-tpl +6 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/alembic/README-tpl +9 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/alembic/env.py-tpl +72 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/alembic/script.py.mako-tpl +27 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/alembic/versions/0001_create_items_table.py-tpl +38 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/api/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/api/health.py-tpl +11 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/api/router.py-tpl +15 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/core/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/core/config.py-tpl +62 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/crud/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/crud/base.py-tpl +62 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/crud/pagination.py-tpl +21 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/db/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/db/base.py-tpl +12 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/db/session.py-tpl +50 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/domains/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/domains/items/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/domains/items/crud.py-tpl +26 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/domains/items/models.py-tpl +70 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/domains/items/router.py-tpl +69 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/src/app/main.py-tpl +43 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/template-config.yml-tpl +16 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/tests/__init__.py-tpl +0 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/tests/conftest.py-tpl +60 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/tests/test_crud_base.py-tpl +43 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/tests/test_health.py-tpl +12 -0
- fastapi_fastkit/fastapi_project_template/fastapi-sqlmodel/tests/test_items.py-tpl +110 -0
- fastapi_fastkit/fastapi_project_template/modules/api/routes/new_route.py-tpl +2 -2
- fastapi_fastkit/fragments/README.md +90 -0
- fastapi_fastkit/fragments/auth/fastapi_users.py.j2 +8 -0
- fastapi_fastkit/fragments/auth/jwt.py.j2 +44 -0
- fastapi_fastkit/fragments/auth/oauth2.py.j2 +105 -0
- fastapi_fastkit/fragments/auth/session.py.j2 +67 -0
- fastapi_fastkit/fragments/db/mongodb.py.j2 +19 -0
- fastapi_fastkit/fragments/db/redis.py.j2 +26 -0
- fastapi_fastkit/fragments/db/sqlalchemy.py.j2 +45 -0
- fastapi_fastkit/fragments/docker/docker_compose.j2 +84 -0
- fastapi_fastkit/fragments/docker/dockerfile.j2 +19 -0
- fastapi_fastkit/fragments/features/cache.py.j2 +26 -0
- fastapi_fastkit/fragments/features/pagination.py.j2 +31 -0
- fastapi_fastkit/fragments/features/tasks_celery.py.j2 +50 -0
- fastapi_fastkit/fragments/features/tasks_dramatiq.py.j2 +59 -0
- fastapi_fastkit/fragments/features/websocket.py.j2 +66 -0
- fastapi_fastkit/fragments/header.j2 +4 -0
- fastapi_fastkit/fragments/logging/structured.py.j2 +88 -0
- fastapi_fastkit/fragments/main/imports/async_tasks.j2 +1 -0
- fastapi_fastkit/fragments/main/imports/caching.j2 +5 -0
- fastapi_fastkit/fragments/main/imports/fastapi_users.j2 +1 -0
- fastapi_fastkit/fragments/main/imports/jwt.j2 +1 -0
- fastapi_fastkit/fragments/main/imports/loguru.j2 +1 -0
- fastapi_fastkit/fragments/main/imports/mongodb.j2 +1 -0
- fastapi_fastkit/fragments/main/imports/oauth2.j2 +4 -0
- fastapi_fastkit/fragments/main/imports/opentelemetry.j2 +6 -0
- fastapi_fastkit/fragments/main/imports/pagination.j2 +3 -0
- fastapi_fastkit/fragments/main/imports/prometheus.j2 +1 -0
- fastapi_fastkit/fragments/main/imports/rate_limiting.j2 +3 -0
- fastapi_fastkit/fragments/main/imports/session_auth.j2 +4 -0
- fastapi_fastkit/fragments/main/imports/sqlalchemy.j2 +2 -0
- fastapi_fastkit/fragments/main/imports/structured_logging.j2 +1 -0
- fastapi_fastkit/fragments/main/imports/websocket.j2 +1 -0
- fastapi_fastkit/fragments/main/lifespan/caching.j2 +7 -0
- fastapi_fastkit/fragments/main/lifespan/mongodb.j2 +2 -0
- fastapi_fastkit/fragments/main/lifespan/prometheus.j2 +2 -0
- fastapi_fastkit/fragments/main/lifespan/sqlalchemy.j2 +2 -0
- fastapi_fastkit/fragments/main/setup/async_tasks.j2 +1 -0
- fastapi_fastkit/fragments/main/setup/caching.j2 +1 -0
- fastapi_fastkit/fragments/main/setup/cors.j2 +8 -0
- fastapi_fastkit/fragments/main/setup/oauth2.j2 +3 -0
- fastapi_fastkit/fragments/main/setup/opentelemetry.j2 +19 -0
- fastapi_fastkit/fragments/main/setup/pagination.j2 +2 -0
- fastapi_fastkit/fragments/main/setup/rate_limiting.j2 +3 -0
- fastapi_fastkit/fragments/main/setup/session_auth.j2 +6 -0
- fastapi_fastkit/fragments/main/setup/structured_logging.j2 +2 -0
- fastapi_fastkit/fragments/main/setup/websocket.j2 +1 -0
- fastapi_fastkit/fragments/main.py.j2 +57 -0
- fastapi_fastkit/fragments/migrations/alembic_ini.j2 +42 -0
- fastapi_fastkit/fragments/migrations/env.py.j2 +76 -0
- fastapi_fastkit/fragments/migrations/initial_revision.py.j2 +27 -0
- fastapi_fastkit/fragments/migrations/migrate_sh.j2 +34 -0
- fastapi_fastkit/fragments/migrations/script.py.mako.j2 +26 -0
- fastapi_fastkit/fragments/tasks/celery_worker.py.j2 +49 -0
- fastapi_fastkit/fragments/tasks/dramatiq_worker.py.j2 +41 -0
- fastapi_fastkit/fragments/test/factories.py.j2 +68 -0
- fastapi_fastkit/fragments/test/pytest_ini.j2 +16 -0
- fastapi_fastkit/fragments/test/test_factories.py.j2 +27 -0
- fastapi_fastkit/fragments/test/test_main.py.j2 +46 -0
- fastapi_fastkit/fragments/tooling/devcontainer.j2 +26 -0
- fastapi_fastkit/fragments/tooling/github_actions.j2 +37 -0
- fastapi_fastkit/fragments/tooling/makefile.j2 +40 -0
- fastapi_fastkit/fragments/tooling/pre_commit.j2 +36 -0
- fastapi_fastkit/fragments/tooling/ruff_toml.j2 +16 -0
- fastapi_fastkit/utils/config_file.py +263 -0
- fastapi_fastkit/utils/main.py +38 -0
- {fastapi_fastkit-1.3.0.dist-info → fastapi_fastkit-1.4.1.dist-info}/METADATA +49 -6
- fastapi_fastkit-1.4.1.dist-info/RECORD +484 -0
- {fastapi_fastkit-1.3.0.dist-info → fastapi_fastkit-1.4.1.dist-info}/WHEEL +1 -1
- fastapi_fastkit/fastapi_project_template/fastapi-async-crud/setup.py-tpl +0 -25
- fastapi_fastkit/fastapi_project_template/fastapi-custom-response/setup.py-tpl +0 -27
- fastapi_fastkit/fastapi_project_template/fastapi-default/setup.py-tpl +0 -22
- fastapi_fastkit/fastapi_project_template/fastapi-dockerized/setup.py-tpl +0 -22
- fastapi_fastkit/fastapi_project_template/fastapi-empty/setup.py-tpl +0 -22
- fastapi_fastkit/fastapi_project_template/fastapi-mcp/setup.py-tpl +0 -51
- fastapi_fastkit/fastapi_project_template/fastapi-psql-orm/setup.py-tpl +0 -25
- fastapi_fastkit/fastapi_project_template/fastapi-single-module/setup.py-tpl +0 -17
- fastapi_fastkit-1.3.0.dist-info/RECORD +0 -287
- /fastapi_fastkit/fastapi_project_template/fastapi-mcp/src/{mcp → mcp_server}/__init__.py-tpl +0 -0
- {fastapi_fastkit-1.3.0.dist-info → fastapi_fastkit-1.4.1.dist-info}/entry_points.txt +0 -0
- {fastapi_fastkit-1.3.0.dist-info → fastapi_fastkit-1.4.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -16,10 +16,13 @@ from .prompts import (
|
|
|
16
16
|
prompt_custom_packages,
|
|
17
17
|
prompt_database_selection,
|
|
18
18
|
prompt_deployment_options,
|
|
19
|
+
prompt_logging_selection,
|
|
20
|
+
prompt_migrations_selection,
|
|
19
21
|
prompt_monitoring_selection,
|
|
20
22
|
prompt_package_manager_selection,
|
|
21
23
|
prompt_template_selection,
|
|
22
24
|
prompt_testing_selection,
|
|
25
|
+
prompt_tooling_selection,
|
|
23
26
|
prompt_utilities_selection,
|
|
24
27
|
)
|
|
25
28
|
from .selectors import confirm_selections, multi_select_prompt, render_selection_table
|
|
@@ -37,6 +40,9 @@ __all__ = [
|
|
|
37
40
|
"prompt_database_selection",
|
|
38
41
|
"prompt_authentication_selection",
|
|
39
42
|
"prompt_additional_features",
|
|
43
|
+
"prompt_logging_selection",
|
|
44
|
+
"prompt_migrations_selection",
|
|
45
|
+
"prompt_tooling_selection",
|
|
40
46
|
"prompt_testing_selection",
|
|
41
47
|
"prompt_deployment_options",
|
|
42
48
|
"prompt_custom_packages",
|
|
@@ -10,6 +10,8 @@ from typing import Any, Dict, List
|
|
|
10
10
|
|
|
11
11
|
from fastapi_fastkit.utils.main import console, print_warning
|
|
12
12
|
|
|
13
|
+
from ..project_builder.config_schema import normalize_project_config
|
|
14
|
+
from ..project_builder.dependency_collector import DependencyCollector
|
|
13
15
|
from .prompts import (
|
|
14
16
|
prompt_additional_features,
|
|
15
17
|
prompt_architecture_preset,
|
|
@@ -107,6 +109,32 @@ class InteractiveConfigBuilder:
|
|
|
107
109
|
features = prompt_additional_features(self.settings)
|
|
108
110
|
self.config.update(features)
|
|
109
111
|
|
|
112
|
+
def build_config_from_mapping(self, config: Dict[str, Any]) -> Dict[str, Any]:
|
|
113
|
+
"""
|
|
114
|
+
Complete a configuration that came from a file instead of prompts.
|
|
115
|
+
|
|
116
|
+
``fastkit init --config`` accepts a hand-written file that lists only
|
|
117
|
+
feature selections; running them back through the same dependency
|
|
118
|
+
collection the interactive flow uses keeps both entry points in
|
|
119
|
+
agreement about which packages a selection implies.
|
|
120
|
+
|
|
121
|
+
The mapping is normalised first, so a file that spells an axis
|
|
122
|
+
differently than the prompts do (a ``{"type": ...}`` block for a
|
|
123
|
+
single-select axis, say) still resolves to the catalog choice the
|
|
124
|
+
rest of the pipeline reads.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
config: Configuration mapping (interactive builder shape)
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
The normalised mapping with ``all_dependencies`` filled in
|
|
131
|
+
|
|
132
|
+
Raises:
|
|
133
|
+
ConfigSchemaError: If the mapping holds an unknown key or choice
|
|
134
|
+
"""
|
|
135
|
+
self.config = normalize_project_config(config, self.settings)
|
|
136
|
+
return self._build_final_config()
|
|
137
|
+
|
|
110
138
|
def _build_final_config(self) -> Dict[str, Any]:
|
|
111
139
|
"""
|
|
112
140
|
Build and validate final configuration.
|
|
@@ -114,6 +142,10 @@ class InteractiveConfigBuilder:
|
|
|
114
142
|
Returns:
|
|
115
143
|
Complete configuration dictionary with collected dependencies
|
|
116
144
|
"""
|
|
145
|
+
# Normalise before anything reads the selections, so an interactive
|
|
146
|
+
# session and a ``--config`` file hand the pipeline the same shape.
|
|
147
|
+
self.config = normalize_project_config(self.config, self.settings)
|
|
148
|
+
|
|
117
149
|
# Collect all dependencies
|
|
118
150
|
all_deps = self._collect_all_dependencies()
|
|
119
151
|
|
|
@@ -126,74 +158,24 @@ class InteractiveConfigBuilder:
|
|
|
126
158
|
"""
|
|
127
159
|
Collect all dependencies from selected features.
|
|
128
160
|
|
|
161
|
+
Delegates to :class:`DependencyCollector`, which walks every axis in
|
|
162
|
+
``PACKAGE_CATALOG`` generically. Duplicating the walk here meant a
|
|
163
|
+
newly added axis (logging, migrations, tooling) was silently skipped
|
|
164
|
+
for interactive projects while ``fastkit init --config`` picked it up.
|
|
165
|
+
|
|
129
166
|
Returns:
|
|
130
167
|
Deduplicated list of all package dependencies
|
|
131
168
|
"""
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
#
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
# Database dependencies
|
|
138
|
-
db_info = self.config.get("database", {})
|
|
139
|
-
if isinstance(db_info, dict) and db_info.get("packages"):
|
|
140
|
-
dependencies.update(db_info["packages"])
|
|
141
|
-
|
|
142
|
-
# Authentication dependencies
|
|
143
|
-
auth_type = self.config.get("authentication", "None")
|
|
144
|
-
if auth_type != "None":
|
|
145
|
-
auth_packages = self.settings.PACKAGE_CATALOG["authentication"].get(
|
|
146
|
-
auth_type, []
|
|
147
|
-
)
|
|
148
|
-
dependencies.update(auth_packages)
|
|
149
|
-
|
|
150
|
-
# Async tasks dependencies
|
|
151
|
-
tasks_type = self.config.get("async_tasks", "None")
|
|
152
|
-
if tasks_type != "None":
|
|
153
|
-
task_packages = self.settings.PACKAGE_CATALOG["async_tasks"].get(
|
|
154
|
-
tasks_type, []
|
|
155
|
-
)
|
|
156
|
-
dependencies.update(task_packages)
|
|
157
|
-
|
|
158
|
-
# Caching dependencies
|
|
159
|
-
cache_type = self.config.get("caching", "None")
|
|
160
|
-
if cache_type != "None":
|
|
161
|
-
cache_packages = self.settings.PACKAGE_CATALOG["caching"].get(
|
|
162
|
-
cache_type, []
|
|
163
|
-
)
|
|
164
|
-
dependencies.update(cache_packages)
|
|
165
|
-
|
|
166
|
-
# Monitoring dependencies
|
|
167
|
-
monitoring_type = self.config.get("monitoring", "None")
|
|
168
|
-
if monitoring_type != "None":
|
|
169
|
-
monitoring_packages = self.settings.PACKAGE_CATALOG["monitoring"].get(
|
|
170
|
-
monitoring_type, []
|
|
171
|
-
)
|
|
172
|
-
dependencies.update(monitoring_packages)
|
|
173
|
-
|
|
174
|
-
# Testing dependencies
|
|
175
|
-
testing_type = self.config.get("testing", "None")
|
|
176
|
-
if testing_type != "None":
|
|
177
|
-
testing_packages = self.settings.PACKAGE_CATALOG["testing"].get(
|
|
178
|
-
testing_type, []
|
|
179
|
-
)
|
|
180
|
-
dependencies.update(testing_packages)
|
|
181
|
-
|
|
182
|
-
# Utilities dependencies
|
|
183
|
-
utilities = self.config.get("utilities", [])
|
|
184
|
-
for util in utilities:
|
|
185
|
-
if util in self.settings.PACKAGE_CATALOG["utilities"]:
|
|
186
|
-
util_packages = self.settings.PACKAGE_CATALOG["utilities"][util]
|
|
187
|
-
dependencies.update(util_packages)
|
|
188
|
-
|
|
189
|
-
# Custom packages
|
|
190
|
-
custom_packages = self.config.get("custom_packages", [])
|
|
169
|
+
config = dict(self.config)
|
|
170
|
+
|
|
171
|
+
# Custom packages are free-form user input, so they are sanitized
|
|
172
|
+
# before the collector merges them with the catalog-derived set.
|
|
173
|
+
custom_packages = config.get("custom_packages", [])
|
|
191
174
|
if custom_packages:
|
|
192
|
-
|
|
193
|
-
dependencies.update(sanitized)
|
|
175
|
+
config["custom_packages"] = sanitize_custom_packages(custom_packages)
|
|
194
176
|
|
|
195
|
-
|
|
196
|
-
return
|
|
177
|
+
collector = DependencyCollector(self.settings)
|
|
178
|
+
return collector.collect_from_config(config)
|
|
197
179
|
|
|
198
180
|
def get_config(self) -> Dict[str, Any]:
|
|
199
181
|
"""
|
|
@@ -16,6 +16,14 @@ from typing import Any, Dict, List, Optional, cast
|
|
|
16
16
|
|
|
17
17
|
import click
|
|
18
18
|
|
|
19
|
+
from fastapi_fastkit.backend.project_builder.config_generator import SQL_DATABASES
|
|
20
|
+
from fastapi_fastkit.core.settings import (
|
|
21
|
+
NONE_CHOICE,
|
|
22
|
+
FeatureAxis,
|
|
23
|
+
LoggingChoice,
|
|
24
|
+
MigrationsChoice,
|
|
25
|
+
ToolingChoice,
|
|
26
|
+
)
|
|
19
27
|
from fastapi_fastkit.utils.main import console, print_error
|
|
20
28
|
|
|
21
29
|
from .selectors import render_selection_table
|
|
@@ -103,7 +111,7 @@ def prompt_architecture_preset(settings: Any) -> str:
|
|
|
103
111
|
}
|
|
104
112
|
render_selection_table("Architecture Presets", display_options)
|
|
105
113
|
|
|
106
|
-
preset_ids = list(presets.keys())
|
|
114
|
+
preset_ids: List[str] = list(presets.keys())
|
|
107
115
|
default_idx = preset_ids.index(default_id) + 1
|
|
108
116
|
|
|
109
117
|
choice = click.prompt(
|
|
@@ -112,7 +120,8 @@ def prompt_architecture_preset(settings: Any) -> str:
|
|
|
112
120
|
default=default_idx,
|
|
113
121
|
)
|
|
114
122
|
|
|
115
|
-
|
|
123
|
+
result: str = preset_ids[choice - 1]
|
|
124
|
+
return result
|
|
116
125
|
|
|
117
126
|
|
|
118
127
|
def prompt_template_selection(settings: Any) -> Optional[str]:
|
|
@@ -161,11 +170,10 @@ def prompt_template_selection(settings: Any) -> Optional[str]:
|
|
|
161
170
|
default=1,
|
|
162
171
|
)
|
|
163
172
|
|
|
164
|
-
|
|
173
|
+
template_keys: List[str] = list(options.keys())
|
|
174
|
+
selected_key: str = template_keys[choice - 1]
|
|
165
175
|
|
|
166
|
-
return
|
|
167
|
-
Optional[str], selected_key if selected_key != "Empty Project" else None
|
|
168
|
-
)
|
|
176
|
+
return selected_key if selected_key != "Empty Project" else None
|
|
169
177
|
|
|
170
178
|
|
|
171
179
|
def prompt_database_selection(settings: Any) -> Dict[str, Any]:
|
|
@@ -436,6 +444,137 @@ def prompt_utilities_selection(settings: Any) -> List[str]:
|
|
|
436
444
|
return []
|
|
437
445
|
|
|
438
446
|
|
|
447
|
+
def prompt_logging_selection(settings: Any) -> str:
|
|
448
|
+
"""
|
|
449
|
+
Prompt for the application logging format.
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
settings: FastkitConfig instance
|
|
453
|
+
|
|
454
|
+
Returns:
|
|
455
|
+
Logging style name
|
|
456
|
+
"""
|
|
457
|
+
console.print("\n[bold cyan]🪵 Logging Format[/bold cyan]")
|
|
458
|
+
console.print("[dim]Choose how the application emits its logs[/dim]\n")
|
|
459
|
+
|
|
460
|
+
logging_catalog = settings.PACKAGE_CATALOG[FeatureAxis.LOGGING]
|
|
461
|
+
descriptions = {
|
|
462
|
+
LoggingChoice.STRUCTURED: (
|
|
463
|
+
"JSON logs + X-Request-ID correlation middleware (stdlib only)"
|
|
464
|
+
),
|
|
465
|
+
LoggingChoice.NONE: "Uvicorn's default plain-text logging",
|
|
466
|
+
}
|
|
467
|
+
options = {
|
|
468
|
+
name: descriptions.get(name, f"Packages: {', '.join(pkgs) or 'None'}")
|
|
469
|
+
for name, pkgs in logging_catalog.items()
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
render_selection_table("Logging Options", options)
|
|
473
|
+
|
|
474
|
+
choice = click.prompt(
|
|
475
|
+
"\nSelect logging format",
|
|
476
|
+
type=click.IntRange(1, len(options)),
|
|
477
|
+
default=len(options), # Default to "None"
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
return cast(str, list(options.keys())[choice - 1])
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def prompt_migrations_selection(settings: Any, database_type: str = "None") -> str:
|
|
484
|
+
"""
|
|
485
|
+
Prompt for the schema migration tool.
|
|
486
|
+
|
|
487
|
+
Alembic only has something to migrate on a relational database, so it is
|
|
488
|
+
pre-selected as the default when the user picked one and the prompt
|
|
489
|
+
defaults to ``None`` otherwise.
|
|
490
|
+
|
|
491
|
+
Args:
|
|
492
|
+
settings: FastkitConfig instance
|
|
493
|
+
database_type: The database chosen earlier in the flow
|
|
494
|
+
|
|
495
|
+
Returns:
|
|
496
|
+
Migration tool name
|
|
497
|
+
"""
|
|
498
|
+
console.print("\n[bold cyan]🧬 Database Migrations[/bold cyan]")
|
|
499
|
+
console.print("[dim]Version-control your database schema[/dim]\n")
|
|
500
|
+
|
|
501
|
+
migrations_catalog = settings.PACKAGE_CATALOG[FeatureAxis.MIGRATIONS]
|
|
502
|
+
is_sql = database_type in SQL_DATABASES
|
|
503
|
+
|
|
504
|
+
descriptions = {
|
|
505
|
+
MigrationsChoice.ALEMBIC: (
|
|
506
|
+
"alembic.ini + async alembic/env.py + scripts/migrate.sh"
|
|
507
|
+
+ (
|
|
508
|
+
" [bold green](recommended for SQL databases)[/bold green]"
|
|
509
|
+
if is_sql
|
|
510
|
+
else " [yellow](needs a relational database)[/yellow]"
|
|
511
|
+
)
|
|
512
|
+
),
|
|
513
|
+
MigrationsChoice.NONE: "No migration tooling",
|
|
514
|
+
}
|
|
515
|
+
options = {name: descriptions.get(name, "") for name in migrations_catalog}
|
|
516
|
+
|
|
517
|
+
render_selection_table("Migration Options", options)
|
|
518
|
+
|
|
519
|
+
option_names = list(options.keys())
|
|
520
|
+
default_idx = (
|
|
521
|
+
option_names.index(MigrationsChoice.ALEMBIC) + 1 if is_sql else len(options)
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
choice = click.prompt(
|
|
525
|
+
"\nSelect migration tool",
|
|
526
|
+
type=click.IntRange(1, len(options)),
|
|
527
|
+
default=default_idx,
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
return cast(str, option_names[choice - 1])
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
def prompt_tooling_selection(settings: Any) -> List[str]:
|
|
534
|
+
"""
|
|
535
|
+
Prompt for developer tooling (multi-select).
|
|
536
|
+
|
|
537
|
+
Args:
|
|
538
|
+
settings: FastkitConfig instance
|
|
539
|
+
|
|
540
|
+
Returns:
|
|
541
|
+
List of selected tooling names
|
|
542
|
+
"""
|
|
543
|
+
console.print("\n[bold cyan]🧰 Developer Tooling[/bold cyan]")
|
|
544
|
+
console.print(
|
|
545
|
+
"[dim]Select tooling to generate (comma-separated numbers, e.g., 1,3)[/dim]\n"
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
tooling_catalog = settings.PACKAGE_CATALOG[FeatureAxis.TOOLING]
|
|
549
|
+
descriptions = {
|
|
550
|
+
ToolingChoice.RUFF: "ruff + ruff-format config in pyproject.toml (replaces black/isort)",
|
|
551
|
+
ToolingChoice.PRE_COMMIT: ".pre-commit-config.yaml",
|
|
552
|
+
ToolingChoice.GITHUB_ACTIONS: ".github/workflows/test.yml (Python 3.12)",
|
|
553
|
+
ToolingChoice.DEVCONTAINER: ".devcontainer/devcontainer.json",
|
|
554
|
+
ToolingChoice.MAKEFILE: "Makefile with install/test/lint/format/run",
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
options = [name for name in tooling_catalog if name != NONE_CHOICE]
|
|
558
|
+
for i, option in enumerate(options, 1):
|
|
559
|
+
console.print(
|
|
560
|
+
f" [cyan]{i}[/cyan]. {option} [dim]{descriptions.get(option, '')}[/dim]"
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
selected_input = console.input(
|
|
564
|
+
"\n[cyan]Your choice (or press Enter to skip):[/cyan] "
|
|
565
|
+
).strip()
|
|
566
|
+
|
|
567
|
+
if not selected_input:
|
|
568
|
+
return []
|
|
569
|
+
|
|
570
|
+
try:
|
|
571
|
+
indices = [int(x.strip()) for x in selected_input.split(",") if x.strip()]
|
|
572
|
+
return [options[idx - 1] for idx in indices if 1 <= idx <= len(options)]
|
|
573
|
+
except (ValueError, IndexError):
|
|
574
|
+
console.print("[yellow]Invalid selection. Skipping tooling.[/yellow]")
|
|
575
|
+
return []
|
|
576
|
+
|
|
577
|
+
|
|
439
578
|
def prompt_deployment_options() -> List[str]:
|
|
440
579
|
"""
|
|
441
580
|
Prompt for deployment configuration.
|
|
@@ -561,12 +700,22 @@ def prompt_additional_features(settings: Any) -> Dict[str, Any]:
|
|
|
561
700
|
# Monitoring
|
|
562
701
|
features["monitoring"] = prompt_monitoring_selection(settings)
|
|
563
702
|
|
|
703
|
+
# Logging format
|
|
704
|
+
features["logging"] = prompt_logging_selection(settings)
|
|
705
|
+
|
|
564
706
|
# Testing
|
|
565
707
|
features["testing"] = prompt_testing_selection(settings)
|
|
566
708
|
|
|
709
|
+
# Migrations — the database choice decides the recommended default.
|
|
710
|
+
database_type = features["database"].get("type", NONE_CHOICE)
|
|
711
|
+
features["migrations"] = prompt_migrations_selection(settings, database_type)
|
|
712
|
+
|
|
567
713
|
# Utilities
|
|
568
714
|
features["utilities"] = prompt_utilities_selection(settings)
|
|
569
715
|
|
|
716
|
+
# Developer tooling
|
|
717
|
+
features["tooling"] = prompt_tooling_selection(settings)
|
|
718
|
+
|
|
570
719
|
# Deployment
|
|
571
720
|
features["deployment"] = prompt_deployment_options()
|
|
572
721
|
|
|
@@ -13,6 +13,7 @@ from typing import Any, Dict, List, Optional
|
|
|
13
13
|
from rich.panel import Panel
|
|
14
14
|
from rich.table import Table
|
|
15
15
|
|
|
16
|
+
from fastapi_fastkit.core.settings import MULTI_SELECT_AXES
|
|
16
17
|
from fastapi_fastkit.utils.main import console
|
|
17
18
|
|
|
18
19
|
|
|
@@ -177,11 +178,26 @@ def confirm_selections(config: Dict[str, Any]) -> bool:
|
|
|
177
178
|
if testing_type != "None":
|
|
178
179
|
table.add_row("Testing", testing_type)
|
|
179
180
|
|
|
181
|
+
# Logging format
|
|
182
|
+
logging_type = config.get("logging", "None")
|
|
183
|
+
if logging_type != "None":
|
|
184
|
+
table.add_row("Logging", logging_type)
|
|
185
|
+
|
|
186
|
+
# Migrations
|
|
187
|
+
migrations_type = config.get("migrations", "None")
|
|
188
|
+
if migrations_type != "None":
|
|
189
|
+
table.add_row("Migrations", migrations_type)
|
|
190
|
+
|
|
180
191
|
# Utilities
|
|
181
192
|
utilities = config.get("utilities", [])
|
|
182
193
|
if utilities:
|
|
183
194
|
table.add_row("Utilities", ", ".join(utilities))
|
|
184
195
|
|
|
196
|
+
# Developer tooling
|
|
197
|
+
tooling = config.get("tooling", [])
|
|
198
|
+
if tooling:
|
|
199
|
+
table.add_row("Tooling", ", ".join(tooling))
|
|
200
|
+
|
|
185
201
|
# Custom packages
|
|
186
202
|
custom = config.get("custom_packages", [])
|
|
187
203
|
if custom:
|
|
@@ -229,8 +245,8 @@ def display_feature_catalog(
|
|
|
229
245
|
console.print(panel)
|
|
230
246
|
|
|
231
247
|
for category, options in catalog.items():
|
|
232
|
-
if category
|
|
233
|
-
continue # Skip
|
|
248
|
+
if category in MULTI_SELECT_AXES:
|
|
249
|
+
continue # Skip multi-selects: several options ship no packages
|
|
234
250
|
|
|
235
251
|
desc = descriptions.get(category, category.title())
|
|
236
252
|
table = Table(title=f"{desc}", show_header=True, header_style="bold yellow")
|