fastapi-spawn 0.4.1__tar.gz → 0.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/.gitignore +2 -0
  2. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/PKG-INFO +1 -1
  3. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/__init__.py +1 -1
  4. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/generator.py +1 -0
  5. fastapi_spawn-0.4.2/fastapi_spawn/templates/app/api/v1/router.py.j2 +19 -0
  6. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/config.py.j2 +8 -2
  7. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/main.py.j2 +9 -6
  8. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/middleware/request_logger.py.j2 +1 -24
  9. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/base/pyproject.toml.j2 +2 -18
  10. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/pyproject.toml +1 -1
  11. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/CHANGELOG.md +0 -0
  12. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/LICENSE +0 -0
  13. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/README.md +0 -0
  14. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/cli.py +0 -0
  15. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/config.py +0 -0
  16. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/constants.py +0 -0
  17. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/interactive.py +0 -0
  18. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/alembic/alembic.ini.j2 +0 -0
  19. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/alembic/env.py.j2 +0 -0
  20. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/__init__.py.j2 +0 -0
  21. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/api/deps.py.j2 +0 -0
  22. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/api/graphql.py.j2 +0 -0
  23. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/api/v1/auth.py.j2 +0 -0
  24. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/api/v1/health.py.j2 +0 -0
  25. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/api/v1/ws.py.j2 +0 -0
  26. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/ai.py.j2 +0 -0
  27. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/email.py.j2 +0 -0
  28. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/exceptions.py.j2 +0 -0
  29. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/logger.py.j2 +0 -0
  30. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/logging.py.j2 +0 -0
  31. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/monitoring.py.j2 +0 -0
  32. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/notifications.py.j2 +0 -0
  33. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/security.py.j2 +0 -0
  34. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/storage.py.j2 +0 -0
  35. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/vector_db.py.j2 +0 -0
  36. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/core/ws_manager.py.j2 +0 -0
  37. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/db/session.py.j2 +0 -0
  38. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/frontend/index.html.j2 +0 -0
  39. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/middleware/__init__.py.j2 +0 -0
  40. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/app/middleware/rate_limit.py.j2 +0 -0
  41. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/base/Makefile.j2 +0 -0
  42. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/base/README.md.j2 +0 -0
  43. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/base/env.j2 +0 -0
  44. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/base/env_example.j2 +0 -0
  45. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/base/gitignore.j2 +0 -0
  46. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/base/pre_commit.j2 +0 -0
  47. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/ci/github/publish.yml.j2 +0 -0
  48. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/ci/github/tests.yml.j2 +0 -0
  49. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/ci/gitlab/gitlab-ci.yml.j2 +0 -0
  50. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/docker/Dockerfile.j2 +0 -0
  51. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/docker/docker-compose.yml.j2 +0 -0
  52. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/docker/dockerignore.j2 +0 -0
  53. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/infra/docker/docker-compose.prod.yml.j2 +0 -0
  54. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/infra/helm/Chart.yaml.j2 +0 -0
  55. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/infra/helm/values.yaml.j2 +0 -0
  56. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/infra/terraform/main.tf.j2 +0 -0
  57. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/infra/terraform/variables.tf.j2 +0 -0
  58. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/root/main.py.j2 +0 -0
  59. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/tasks/arq_worker.py.j2 +0 -0
  60. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/tasks/celery_app.py.j2 +0 -0
  61. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/tasks/sample_tasks.py.j2 +0 -0
  62. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/tests/conftest.py.j2 +0 -0
  63. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/templates/tests/test_health.py.j2 +0 -0
  64. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/utils.py +0 -0
  65. {fastapi_spawn-0.4.1 → fastapi_spawn-0.4.2}/fastapi_spawn/validators.py +0 -0
@@ -51,3 +51,5 @@ Thumbs.db
51
51
 
52
52
  # Hatch / build backends
53
53
  .hatch/
54
+
55
+ .test/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-spawn
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: A powerful CLI tool to scaffold production-ready FastAPI projects with flexible database, auth, broker, and deployment options.
5
5
  Project-URL: Homepage, https://github.com/Bishwajitgarai/fastapi-spawn
6
6
  Project-URL: Documentation, https://github.com/Bishwajitgarai/fastapi-spawn#readme
@@ -1,6 +1,6 @@
1
1
  """fastapi-spawn — Production-ready FastAPI project scaffolding CLI."""
2
2
 
3
- __version__ = "0.4.1"
3
+ __version__ = "0.4.2"
4
4
  __author__ = "Bishwajit Garai"
5
5
  __email__ = "bishwajitgarai@gmail.com"
6
6
  __license__ = "MIT"
@@ -173,6 +173,7 @@ class ProjectGenerator:
173
173
  v1 = api / "v1"
174
174
  v1.mkdir()
175
175
  self._render_to(v1 / "__init__.py", "app/__init__.py.j2")
176
+ self._render_to(v1 / "router.py", "app/api/v1/router.py.j2")
176
177
  self._render_to(v1 / "health.py", "app/api/v1/health.py.j2")
177
178
  if self.config.has_auth:
178
179
  self._render_to(v1 / "auth.py", "app/api/v1/auth.py.j2")
@@ -0,0 +1,19 @@
1
+ from fastapi import APIRouter
2
+
3
+ from app.api.v1.health import router as health_router
4
+ {% if has_auth %}
5
+ from app.api.v1.auth import router as auth_router
6
+ {% endif %}
7
+ {% if has_websockets %}
8
+ from app.api.v1.ws import router as ws_router
9
+ {% endif %}
10
+
11
+ router = APIRouter(prefix="/v1", tags=["v1"])
12
+
13
+ router.include_router(health_router)
14
+ {% if has_auth %}
15
+ router.include_router(auth_router)
16
+ {% endif %}
17
+ {% if has_websockets %}
18
+ router.include_router(ws_router)
19
+ {% endif %}
@@ -3,9 +3,9 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from functools import lru_cache
6
- from typing import Any
6
+ from typing import Any, Optional
7
7
 
8
- from pydantic import field_validator
8
+ from pydantic import ConfigDict, field_validator
9
9
  from pydantic_settings import BaseSettings, SettingsConfigDict
10
10
 
11
11
 
@@ -26,6 +26,12 @@ class Settings(BaseSettings):
26
26
  SECRET_KEY: str = "change-me"
27
27
  CORS_ORIGINS: list[str] = ["http://localhost:3000", "http://localhost:8000"]
28
28
 
29
+ @field_validator("CORS_ORIGINS", mode="before")
30
+ def parse_cors(cls, v: Any) -> list[str]:
31
+ if isinstance(v, str) and not v.startswith("["):
32
+ return [i.strip() for i in v.split(",") if i.strip()]
33
+ return v
34
+
29
35
  @property
30
36
  def DEBUG(self) -> bool:
31
37
  return self.ENVIRONMENT.lower() in ("dev", "development", "local")
@@ -7,9 +7,9 @@ from fastapi import FastAPI
7
7
  from fastapi.middleware.cors import CORSMiddleware
8
8
  from fastapi.responses import ORJSONResponse
9
9
 
10
- from app.api.v1 import health
11
- {% if has_auth %}
12
- from app.api.v1 import auth
10
+ from app.api.v1.router import router as api_v1_router
11
+ {% if has_graphql %}
12
+ from app.api.graphql import graphql_router
13
13
  {% endif %}
14
14
  from app.core.config import settings
15
15
  from app.core.exceptions import register_exception_handlers
@@ -60,9 +60,12 @@ def create_application() -> FastAPI:
60
60
  register_exception_handlers(application)
61
61
 
62
62
  # Routers
63
- application.include_router(health.router, prefix=settings.API_V1_PREFIX, tags=["Health"])
64
- {% if has_auth %}
65
- application.include_router(auth.router, prefix=settings.API_V1_PREFIX, tags=["Auth"])
63
+ # Mount REST API v1 router
64
+ application.include_router(api_v1_router, prefix=settings.API_V1_PREFIX)
65
+
66
+ {% if has_graphql %}
67
+ # Mount GraphQL endpoint
68
+ application.include_router(graphql_router, prefix="/graphql")
66
69
  {% endif %}
67
70
 
68
71
  return application
@@ -7,33 +7,11 @@ from __future__ import annotations
7
7
 
8
8
  import time
9
9
  import uuid
10
- from contextvars import ContextVar
11
- from typing import Optional
12
-
13
10
  from fastapi import Request
14
11
  from starlette.middleware.base import BaseHTTPMiddleware
15
12
  from starlette.responses import Response
16
13
 
17
- # ── Context variables (per-request, async-safe) ────────────────────────────
18
- _request_id_ctx: ContextVar[Optional[str]] = ContextVar("request_id", default=None)
19
- _client_ip_ctx: ContextVar[Optional[str]] = ContextVar("client_ip", default=None)
20
-
21
-
22
- def set_request_id(value: Optional[str]) -> None:
23
- _request_id_ctx.set(value)
24
-
25
-
26
- def get_request_id() -> Optional[str]:
27
- return _request_id_ctx.get()
28
-
29
-
30
- def set_client_ip(value: Optional[str]) -> None:
31
- _client_ip_ctx.set(value)
32
-
33
-
34
- def get_client_ip() -> Optional[str]:
35
- return _client_ip_ctx.get()
36
-
14
+ from app.core.logger import logger, set_client_ip, set_request_id
37
15
 
38
16
  def _extract_client_ip(request: Request) -> str:
39
17
  """Respect X-Forwarded-For / X-Real-IP from reverse proxies."""
@@ -70,7 +48,6 @@ class RequestLoggingMiddleware(BaseHTTPMiddleware):
70
48
 
71
49
  start = time.perf_counter()
72
50
 
73
- from app.core.logger import logger
74
51
  logger.info("→ %s %s rid=%s ip=%s", request.method, request.url.path, request_id, client_ip)
75
52
 
76
53
  try:
@@ -175,24 +175,8 @@ dev-dependencies = [
175
175
  "pre-commit>=3.7.0",
176
176
  ]
177
177
 
178
- # ── uv run scripts ────────────────────────────────────────────────────────────
179
- # Usage: uv run <script-name>
180
- [tool.uv.scripts]
181
- dev = "uvicorn app.main:app --reload --host 0.0.0.0 --port 8000"
182
- start = "python main.py"
183
- test = "pytest --cov=app --cov-report=term-missing"
184
- lint = "ruff check ."
185
- format = "ruff format ."
186
- typecheck = "mypy app/"
187
- {% if migration == "alembic" %}
188
- migrate = "alembic upgrade head"
189
- rollback = "alembic downgrade -1"
190
- makemig = "alembic revision --autogenerate -m"
191
- {% endif %}
192
- {% if has_broker %}
193
- worker = "celery -A tasks.celery_app worker --loglevel=info"
194
- beat = "celery -A tasks.celery_app beat --loglevel=info"
195
- {% endif %}
178
+ [tool.hatch.build.targets.wheel]
179
+ packages = ["app"]
196
180
 
197
181
  [tool.pytest.ini_options]
198
182
  asyncio_mode = "auto"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "fastapi-spawn"
7
- version = "0.4.1"
7
+ version = "0.4.2"
8
8
  description = "A powerful CLI tool to scaffold production-ready FastAPI projects with flexible database, auth, broker, and deployment options."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
File without changes
File without changes