fastapi-spawn 0.4.8__tar.gz → 0.4.11__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 (71) hide show
  1. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/PKG-INFO +13 -8
  2. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/README.md +12 -7
  3. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/__init__.py +1 -1
  4. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/cli.py +12 -4
  5. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/constants.py +6 -2
  6. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/generator.py +2 -1
  7. fastapi_spawn-0.4.11/fastapi_spawn/templates/app/api/v1/auth/sso.py.j2 +116 -0
  8. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/env.j2 +21 -0
  9. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/env_example.j2 +41 -0
  10. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/pyproject.toml.j2 +4 -0
  11. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/pyproject.toml +1 -1
  12. fastapi_spawn-0.4.8/fastapi_spawn/templates/app/api/v1/auth/sso.py.j2 +0 -36
  13. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/.gitignore +0 -0
  14. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/LICENSE +0 -0
  15. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/config.py +0 -0
  16. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/interactive.py +0 -0
  17. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/alembic/alembic.ini.j2 +0 -0
  18. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/alembic/env.py.j2 +0 -0
  19. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/__init__.py.j2 +0 -0
  20. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/deps.py.j2 +0 -0
  21. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/graphql.py.j2 +0 -0
  22. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/auth/router.py.j2 +0 -0
  23. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/health/router.py.j2 +0 -0
  24. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/payments/router.py.j2 +0 -0
  25. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/router.py.j2 +0 -0
  26. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/streaming/router.py.j2 +0 -0
  27. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/ws/router.py.j2 +0 -0
  28. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/ai.py.j2 +0 -0
  29. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/config.py.j2 +0 -0
  30. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/email.py.j2 +0 -0
  31. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/exceptions.py.j2 +0 -0
  32. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/logger.py.j2 +0 -0
  33. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/logging.py.j2 +0 -0
  34. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/monitoring.py.j2 +0 -0
  35. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/notifications.py.j2 +0 -0
  36. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/ocr.py.j2 +0 -0
  37. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/search.py.j2 +0 -0
  38. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/security.py.j2 +0 -0
  39. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/storage.py.j2 +0 -0
  40. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/vector_db.py.j2 +0 -0
  41. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/ws_manager.py.j2 +0 -0
  42. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/db/session.py.j2 +0 -0
  43. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/frontend/index.html.j2 +0 -0
  44. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/main.py.j2 +0 -0
  45. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/middleware/__init__.py.j2 +0 -0
  46. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/middleware/rate_limit.py.j2 +0 -0
  47. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/middleware/request_logger.py.j2 +0 -0
  48. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/Makefile.j2 +0 -0
  49. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/README.md.j2 +0 -0
  50. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/gitignore.j2 +0 -0
  51. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/pre_commit.j2 +0 -0
  52. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/ci/github/publish.yml.j2 +0 -0
  53. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/ci/github/tests.yml.j2 +0 -0
  54. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/ci/gitlab/gitlab-ci.yml.j2 +0 -0
  55. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/db/seed.py.j2 +0 -0
  56. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/docker/Dockerfile.j2 +0 -0
  57. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/docker/docker-compose.yml.j2 +0 -0
  58. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/docker/dockerignore.j2 +0 -0
  59. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/docker/docker-compose.prod.yml.j2 +0 -0
  60. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/helm/Chart.yaml.j2 +0 -0
  61. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/helm/values.yaml.j2 +0 -0
  62. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/terraform/main.tf.j2 +0 -0
  63. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/terraform/variables.tf.j2 +0 -0
  64. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/root/main.py.j2 +0 -0
  65. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tasks/arq_worker.py.j2 +0 -0
  66. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tasks/celery_app.py.j2 +0 -0
  67. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tasks/sample_tasks.py.j2 +0 -0
  68. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tests/conftest.py.j2 +0 -0
  69. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tests/test_health.py.j2 +0 -0
  70. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/utils.py +0 -0
  71. {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/validators.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-spawn
3
- Version: 0.4.8
3
+ Version: 0.4.11
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
@@ -450,12 +450,12 @@ Did you generate a minimal project and now realize you need WebSockets, AWS S3,
450
450
  fastapi-spawn add [FEATURE]
451
451
  ```
452
452
 
453
- ### How it works:
454
- 1. **Generates the Module**: It creates the necessary file (e.g., `app/core/ai.py` or `app/api/v1/ws/router.py`) tailored to your project structure.
455
- 2. **Environment Variables**: It prompts you with the exact environment variables you need to append to your `.env` and `config.py`.
456
- 3. **Integration Guide**: It outputs a step-by-step UI snippet telling you *exactly* where to import and mount the new feature in your `main.py` or `router.py`.
453
+ Or you can add them at creation time with the `--extra` flag:
454
+ ```bash
455
+ fastapi-spawn new my_app --extra stripe --extra sso --extra seed
456
+ ```
457
457
 
458
- ### All Possibilities you can `add`:
458
+ ### All Possibilities you can `add` or `--extra`:
459
459
 
460
460
  You can run any of the following commands inside an existing project:
461
461
 
@@ -474,11 +474,16 @@ fastapi-spawn add qdrant # Qdrant vector DB
474
474
  fastapi-spawn add chroma # ChromaDB local vector DB
475
475
  fastapi-spawn add pinecone # Pinecone cloud vector DB
476
476
  fastapi-spawn add meilisearch # Meilisearch typo-tolerant search
477
+ fastapi-spawn add opensearch # OpenSearch vector & text search
478
+ fastapi-spawn add vespa # Vespa big data serving engine
477
479
  fastapi-spawn add ocr # PDF & OCR data extraction pipeline
478
480
 
479
481
  # Payments & Identity
480
482
  fastapi-spawn add stripe # Stripe payments & webhooks
481
- fastapi-spawn add sso # FastAPI SSO (Google/GitHub login)
483
+ fastapi-spawn add sso # FastAPI SSO (Google, GitHub, Microsoft)
484
+ fastapi-spawn add sso-google # FastAPI SSO (Google only)
485
+ fastapi-spawn add sso-github # FastAPI SSO (GitHub only)
486
+ fastapi-spawn add sso-microsoft # FastAPI SSO (Microsoft only)
482
487
 
483
488
  # Messaging & Async Workers
484
489
  fastapi-spawn add celery # Celery worker + tasks/
@@ -490,7 +495,7 @@ fastapi-spawn add sse # Server-Sent Events streaming
490
495
  fastapi-spawn add s3 # AWS S3 / MinIO storage
491
496
  fastapi-spawn add graphql # Strawberry GraphQL schema
492
497
  fastapi-spawn add alembic # Alembic async migrations
493
- fastapi-spawn add seed # Faker database seeding script
498
+ fastapi-spawn add seed # Faker database seeding script (Users, Posts, Comments)
494
499
  fastapi-spawn add resend # Resend modern email client
495
500
  fastapi-spawn add sentry # Sentry APM integration
496
501
  fastapi-spawn add prometheus # Prometheus metrics
@@ -409,12 +409,12 @@ Did you generate a minimal project and now realize you need WebSockets, AWS S3,
409
409
  fastapi-spawn add [FEATURE]
410
410
  ```
411
411
 
412
- ### How it works:
413
- 1. **Generates the Module**: It creates the necessary file (e.g., `app/core/ai.py` or `app/api/v1/ws/router.py`) tailored to your project structure.
414
- 2. **Environment Variables**: It prompts you with the exact environment variables you need to append to your `.env` and `config.py`.
415
- 3. **Integration Guide**: It outputs a step-by-step UI snippet telling you *exactly* where to import and mount the new feature in your `main.py` or `router.py`.
412
+ Or you can add them at creation time with the `--extra` flag:
413
+ ```bash
414
+ fastapi-spawn new my_app --extra stripe --extra sso --extra seed
415
+ ```
416
416
 
417
- ### All Possibilities you can `add`:
417
+ ### All Possibilities you can `add` or `--extra`:
418
418
 
419
419
  You can run any of the following commands inside an existing project:
420
420
 
@@ -433,11 +433,16 @@ fastapi-spawn add qdrant # Qdrant vector DB
433
433
  fastapi-spawn add chroma # ChromaDB local vector DB
434
434
  fastapi-spawn add pinecone # Pinecone cloud vector DB
435
435
  fastapi-spawn add meilisearch # Meilisearch typo-tolerant search
436
+ fastapi-spawn add opensearch # OpenSearch vector & text search
437
+ fastapi-spawn add vespa # Vespa big data serving engine
436
438
  fastapi-spawn add ocr # PDF & OCR data extraction pipeline
437
439
 
438
440
  # Payments & Identity
439
441
  fastapi-spawn add stripe # Stripe payments & webhooks
440
- fastapi-spawn add sso # FastAPI SSO (Google/GitHub login)
442
+ fastapi-spawn add sso # FastAPI SSO (Google, GitHub, Microsoft)
443
+ fastapi-spawn add sso-google # FastAPI SSO (Google only)
444
+ fastapi-spawn add sso-github # FastAPI SSO (GitHub only)
445
+ fastapi-spawn add sso-microsoft # FastAPI SSO (Microsoft only)
441
446
 
442
447
  # Messaging & Async Workers
443
448
  fastapi-spawn add celery # Celery worker + tasks/
@@ -449,7 +454,7 @@ fastapi-spawn add sse # Server-Sent Events streaming
449
454
  fastapi-spawn add s3 # AWS S3 / MinIO storage
450
455
  fastapi-spawn add graphql # Strawberry GraphQL schema
451
456
  fastapi-spawn add alembic # Alembic async migrations
452
- fastapi-spawn add seed # Faker database seeding script
457
+ fastapi-spawn add seed # Faker database seeding script (Users, Posts, Comments)
453
458
  fastapi-spawn add resend # Resend modern email client
454
459
  fastapi-spawn add sentry # Sentry APM integration
455
460
  fastapi-spawn add prometheus # Prometheus metrics
@@ -1,6 +1,6 @@
1
1
  """fastapi-spawn — Production-ready FastAPI project scaffolding CLI."""
2
2
 
3
- __version__ = "0.4.8"
3
+ __version__ = "0.4.11"
4
4
  __author__ = "Bishwajit Garai"
5
5
  __email__ = "bishwajitgarai@gmail.com"
6
6
  __license__ = "MIT"
@@ -278,8 +278,6 @@ _ADDABLE_FEATURES = {
278
278
  "opentelemetry": "OpenTelemetry distributed tracing",
279
279
  "sendgrid": "SendGrid email",
280
280
  "smtp": "SMTP email (fastapi-mail)",
281
- "ses": "AWS SES email",
282
- "resend": "Resend email client (modern React/HTML emails)",
283
281
  "slack": "Slack webhook notifications",
284
282
  "discord": "Discord webhook notifications",
285
283
  "qdrant": "Qdrant vector database",
@@ -287,11 +285,16 @@ _ADDABLE_FEATURES = {
287
285
  "pinecone": "Pinecone managed vector database",
288
286
  "elasticsearch": "Elasticsearch KNN search",
289
287
  "meilisearch": "Meilisearch ultra-fast typo-tolerant search",
288
+ "opensearch": "OpenSearch vector and text search",
289
+ "vespa": "Vespa big data serving engine",
290
290
  "websockets": "WebSocket connection manager + endpoints",
291
291
  "sse": "Server-Sent Events (SSE) streaming endpoint",
292
292
  "graphql": "Strawberry GraphQL schema + subscriptions",
293
293
  "stripe": "Stripe payments & webhook signature validation",
294
- "sso": "FastAPI SSO (Login with Google / GitHub)",
294
+ "sso": "FastAPI SSO (Google, GitHub, Microsoft)",
295
+ "sso-google": "FastAPI SSO (Google only)",
296
+ "sso-github": "FastAPI SSO (GitHub only)",
297
+ "sso-microsoft": "FastAPI SSO (Microsoft only)",
295
298
  "seed": "Database seeding script using Faker",
296
299
  "ocr": "PDF & OCR data pipeline (PyMuPDF / Tesseract)",
297
300
  "docker": "Dockerfile + docker-compose.yml",
@@ -356,11 +359,16 @@ def _feature_guidance(feature: str, _project_dir: Path) -> None:
356
359
  "pinecone": ["Add dep: pinecone-client>=3.2.0", "Create app/core/vector_db.py", "Add to .env: PINECONE_API_KEY, PINECONE_INDEX_NAME"],
357
360
  "elasticsearch": ["Add dep: elasticsearch[async]>=8.13.0", "Create app/core/vector_db.py (kNN search)", "Add to .env: ELASTICSEARCH_HOST, ELASTICSEARCH_PORT, ELASTICSEARCH_API_KEY"],
358
361
  "meilisearch": ["Add dep: meilisearch>=0.30.0", "Create app/core/search.py (Meilisearch client)", "Add to .env: MEILISEARCH_HOST=http://localhost:7700, MEILISEARCH_API_KEY"],
362
+ "opensearch": ["Add dep: opensearch-py[async]>=2.5.0", "Create app/core/search.py (OpenSearch client)", "Add to .env: OPENSEARCH_HOST, OPENSEARCH_PORT, OPENSEARCH_USER, OPENSEARCH_PASSWORD"],
363
+ "vespa": ["Add dep: pyvespa>=0.40.0", "Create app/core/search.py (Vespa client)", "Add to .env: VESPA_ENDPOINT"],
359
364
  "websockets":["No extra dep (built into FastAPI)", "Create app/core/ws_manager.py (ConnectionManager)", "Create app/api/v1/ws/router.py — /ws/connect, /ws/connect/{room_id}"],
360
365
  "sse": ["Add dep: sse-starlette>=2.1.0", "Create app/api/v1/streaming/router.py", "Return EventSourceResponse(async_generator)"],
361
366
  "graphql": ["Add dep: strawberry-graphql[fastapi]>=0.227.0", "Create app/api/graphql.py (Query + Mutation + Subscription)", "Mount: app.include_router(graphql_router, prefix='/graphql')"],
362
367
  "stripe": ["Add dep: stripe>=9.0.0", "Create app/api/v1/payments/router.py (webhook endpoint)", "Add to .env: STRIPE_API_KEY, STRIPE_WEBHOOK_SECRET"],
363
- "sso": ["Add dep: fastapi-sso>=0.14.0", "Create app/api/v1/auth/sso.py (GoogleSSO / GithubSSO)", "Add to .env: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET"],
368
+ "sso": ["Add dep: fastapi-sso>=0.14.0", "Create app/api/v1/auth/sso.py (Google/Github/Microsoft SSO)", "Add to .env: GOOGLE_CLIENT_ID, GITHUB_CLIENT_ID, etc."],
369
+ "sso-google": ["1. Use 'fastapi-spawn new temp_app --extra sso-google' and copy the resulting sso.py"],
370
+ "sso-github": ["1. Use 'fastapi-spawn new temp_app --extra sso-github' and copy the resulting sso.py"],
371
+ "sso-microsoft": ["1. Use 'fastapi-spawn new temp_app --extra sso-microsoft' and copy the resulting sso.py"],
364
372
  "seed": ["Add dep: faker>=25.0.0", "Create db/seed.py (generate 100 mock users/posts)", "Run: uv run python db/seed.py"],
365
373
  "ocr": ["Add deps: pymupdf>=1.24.0, pytesseract>=0.3.10", "Create app/core/ocr.py (PDF parsing pipeline)", "Install system deps: sudo apt install tesseract-ocr"],
366
374
  "docker": ["Create Dockerfile (multi-stage, uv-based)", "Create docker-compose.yml with all selected services", "Create .dockerignore"],
@@ -128,6 +128,8 @@ class VectorDB(str, Enum):
128
128
  pinecone = "pinecone"
129
129
  supabase = "supabase" # pgvector on Supabase
130
130
  elasticsearch = "elasticsearch"
131
+ opensearch = "opensearch"
132
+ vespa = "vespa"
131
133
  none = "none"
132
134
 
133
135
 
@@ -256,8 +258,10 @@ VECTOR_DB_LABELS = {
256
258
  VectorDB.qdrant: "Qdrant — local Docker or Qdrant Cloud",
257
259
  VectorDB.chroma: "ChromaDB — local open-source vector DB",
258
260
  VectorDB.pinecone: "Pinecone — managed cloud",
259
- VectorDB.supabase: "Supabase pgvector",
260
- VectorDB.elasticsearch: "Elasticsearch — kNN search",
261
+ VectorDB.supabase: "Supabase (pgvector)",
262
+ VectorDB.elasticsearch: "Elasticsearch",
263
+ VectorDB.opensearch: "OpenSearch",
264
+ VectorDB.vespa: "Vespa",
261
265
  VectorDB.none: "No vector database",
262
266
  }
263
267
 
@@ -216,7 +216,8 @@ class ProjectGenerator:
216
216
  self._render_to(v1 / "payments" / "router.py", "app/api/v1/payments/router.py.j2")
217
217
  self._render_to(v1 / "payments" / "__init__.py", "app/__init__.py.j2")
218
218
 
219
- if "sso" in extras:
219
+ has_sso = any(e.startswith("sso") for e in extras)
220
+ if has_sso:
220
221
  (v1 / "auth").mkdir(parents=True, exist_ok=True)
221
222
  self._render_to(v1 / "auth" / "sso.py", "app/api/v1/auth/sso.py.j2")
222
223
 
@@ -0,0 +1,116 @@
1
+ from fastapi import APIRouter, Request, HTTPException
2
+ from app.core.config import settings
3
+
4
+ router = APIRouter(prefix="/sso", tags=["auth"])
5
+
6
+ {% if "sso-google" in extras or "sso" in extras %}
7
+ from fastapi_sso.sso.google import GoogleSSO
8
+
9
+ # Requires GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in .env
10
+ google_sso = GoogleSSO(
11
+ client_id=getattr(settings, "GOOGLE_CLIENT_ID", "placeholder"),
12
+ client_secret=getattr(settings, "GOOGLE_CLIENT_SECRET", "placeholder"),
13
+ redirect_uri="http://localhost:8000/api/v1/auth/sso/google/callback",
14
+ allow_insecure_http=True, # Set to False in production
15
+ )
16
+
17
+ @router.get("/google/login")
18
+ async def google_login():
19
+ """Redirects the user to the Google login page."""
20
+ with google_sso:
21
+ return await google_sso.get_login_redirect()
22
+
23
+ @router.get("/google/callback")
24
+ async def google_callback(request: Request):
25
+ """Process login response from Google and return user info."""
26
+ with google_sso:
27
+ user = await google_sso.verify_and_process(request)
28
+ if not user:
29
+ raise HTTPException(status_code=400, detail="Failed to login via Google")
30
+
31
+ return {
32
+ "id": user.id,
33
+ "email": user.email,
34
+ "first_name": user.first_name,
35
+ "last_name": user.last_name,
36
+ "picture": user.picture,
37
+ "provider": "google"
38
+ }
39
+ {% endif %}
40
+
41
+ {% if "sso-github" in extras or "sso" in extras %}
42
+ from fastapi_sso.sso.github import GithubSSO
43
+
44
+ # --- GitHub SSO ---
45
+
46
+ # Requires GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET in .env
47
+ github_sso = GithubSSO(
48
+ client_id=getattr(settings, "GITHUB_CLIENT_ID", "placeholder"),
49
+ client_secret=getattr(settings, "GITHUB_CLIENT_SECRET", "placeholder"),
50
+ redirect_uri="http://localhost:8000/api/v1/auth/sso/github/callback",
51
+ allow_insecure_http=True, # Set to False in production
52
+ )
53
+
54
+ @router.get("/github/login")
55
+ async def github_login():
56
+ """Redirects the user to the GitHub login page."""
57
+ with github_sso:
58
+ return await github_sso.get_login_redirect()
59
+
60
+ @router.get("/github/callback")
61
+ async def github_callback(request: Request):
62
+ """Process login response from GitHub and return user info."""
63
+ with github_sso:
64
+ user = await github_sso.verify_and_process(request)
65
+ if not user:
66
+ raise HTTPException(status_code=400, detail="Failed to login via GitHub")
67
+
68
+ return {
69
+ "id": user.id,
70
+ "email": user.email,
71
+ "first_name": getattr(user, "first_name", None),
72
+ "last_name": getattr(user, "last_name", None),
73
+ "picture": getattr(user, "picture", None),
74
+ "provider": "github"
75
+ }
76
+ {% endif %}
77
+
78
+ {% if "sso-microsoft" in extras or "sso" in extras %}
79
+ from fastapi_sso.sso.microsoft import MicrosoftSSO
80
+
81
+ # --- Microsoft SSO ---
82
+
83
+ # Requires MICROSOFT_CLIENT_ID and MICROSOFT_CLIENT_SECRET in .env
84
+ microsoft_sso = MicrosoftSSO(
85
+ client_id=getattr(settings, "MICROSOFT_CLIENT_ID", "placeholder"),
86
+ client_secret=getattr(settings, "MICROSOFT_CLIENT_SECRET", "placeholder"),
87
+ tenant="common", # Or your specific tenant ID
88
+ redirect_uri="http://localhost:8000/api/v1/auth/sso/microsoft/callback",
89
+ allow_insecure_http=True, # Set to False in production
90
+ )
91
+
92
+ @router.get("/microsoft/login")
93
+ async def microsoft_login():
94
+ """Redirects the user to the Microsoft login page."""
95
+ with microsoft_sso:
96
+ return await microsoft_sso.get_login_redirect()
97
+
98
+ @router.get("/microsoft/callback")
99
+ async def microsoft_callback(request: Request):
100
+ """Process login response from Microsoft and return user info."""
101
+ with microsoft_sso:
102
+ user = await microsoft_sso.verify_and_process(request)
103
+ if not user:
104
+ raise HTTPException(status_code=400, detail="Failed to login via Microsoft")
105
+
106
+ return {
107
+ "id": user.id,
108
+ "email": user.email,
109
+ "first_name": getattr(user, "first_name", None),
110
+ "last_name": getattr(user, "last_name", None),
111
+ "picture": getattr(user, "picture", None),
112
+ "provider": "microsoft"
113
+ }
114
+ {% endif %}
115
+
116
+
@@ -80,3 +80,24 @@ OPENAI_BASE_URL= # leave blank for api.openai.com; set fo
80
80
  ANTHROPIC_API_KEY=sk-ant-placeholder
81
81
  ANTHROPIC_MODEL=claude-3-5-sonnet-20241022
82
82
  {% endif %}
83
+ {% if extras %}
84
+ {% if "stripe" in extras %}
85
+ # Stripe
86
+ STRIPE_API_KEY=sk_test_placeholder
87
+ STRIPE_WEBHOOK_SECRET=whsec_placeholder
88
+ {% endif %}
89
+ {% if "sso" in extras or "sso-google" in extras or "sso-github" in extras or "sso-microsoft" in extras %}
90
+ # SSO (Google, GitHub, Microsoft)
91
+ GOOGLE_CLIENT_ID=placeholder
92
+ GOOGLE_CLIENT_SECRET=placeholder
93
+ GITHUB_CLIENT_ID=placeholder
94
+ GITHUB_CLIENT_SECRET=placeholder
95
+ MICROSOFT_CLIENT_ID=placeholder
96
+ MICROSOFT_CLIENT_SECRET=placeholder
97
+ {% endif %}
98
+ {% if "meilisearch" in extras %}
99
+ # Meilisearch
100
+ MEILISEARCH_HOST=http://localhost:7700
101
+ MEILISEARCH_API_KEY=masterKey
102
+ {% endif %}
103
+ {% endif %}
@@ -229,11 +229,16 @@ SMTP_SSL=false
229
229
  {% elif email == "ses" %}
230
230
  # AWS SES (active) — uses AWS_* credentials above
231
231
  SES_FROM_EMAIL=noreply@example.com
232
+ {% elif email == "resend" %}
233
+ # Resend (active)
234
+ RESEND_API_KEY=re_placeholder
235
+ RESEND_FROM_EMAIL=noreply@example.com
232
236
  {% else %}
233
237
  # Email — uncomment the provider you need:
234
238
  # SendGrid: SENDGRID_API_KEY=SG.placeholder | SENDGRID_FROM_EMAIL=noreply@example.com
235
239
  # SMTP: SMTP_HOST=smtp.gmail.com | SMTP_PORT=587 | SMTP_USER=... | SMTP_PASSWORD=... | SMTP_FROM_EMAIL=... | SMTP_STARTTLS=true | SMTP_SSL=false
236
240
  # AWS SES: SES_FROM_EMAIL=noreply@example.com (uses AWS_* credentials)
241
+ # Resend: RESEND_API_KEY=re_placeholder | RESEND_FROM_EMAIL=noreply@example.com
237
242
  {% endif %}
238
243
 
239
244
  # =============================================================================
@@ -273,6 +278,15 @@ PINECONE_INDEX_NAME={{ slug }}-index
273
278
  ELASTICSEARCH_HOST=localhost
274
279
  ELASTICSEARCH_PORT=9200
275
280
  ELASTICSEARCH_API_KEY=
281
+ {% elif vector_db == "opensearch" %}
282
+ # OpenSearch (active)
283
+ OPENSEARCH_HOST=localhost
284
+ OPENSEARCH_PORT=9200
285
+ OPENSEARCH_USER=admin
286
+ OPENSEARCH_PASSWORD=admin
287
+ {% elif vector_db == "vespa" %}
288
+ # Vespa (active)
289
+ VESPA_ENDPOINT=http://localhost:8080
276
290
  {% else %}
277
291
  # Vector DB — uncomment the provider you need:
278
292
  # Qdrant: QDRANT_HOST=localhost | QDRANT_PORT=6333 | QDRANT_API_KEY= (blank for local)
@@ -280,6 +294,8 @@ ELASTICSEARCH_API_KEY=
280
294
  # Pinecone: PINECONE_API_KEY=CHANGE_ME | PINECONE_INDEX_NAME={{ slug }}-index
281
295
  # Supabase: uses SUPABASE_URL / SUPABASE_KEY above
282
296
  # Elasticsearch: ELASTICSEARCH_HOST=localhost | ELASTICSEARCH_PORT=9200 | ELASTICSEARCH_API_KEY=
297
+ # OpenSearch: OPENSEARCH_HOST=localhost | OPENSEARCH_PORT=9200 | OPENSEARCH_USER=admin | OPENSEARCH_PASSWORD=admin
298
+ # Vespa: VESPA_ENDPOINT=http://localhost:8080
283
299
  {% endif %}
284
300
 
285
301
  # =============================================================================
@@ -298,3 +314,28 @@ DD_SITE=datadoghq.com
298
314
  # Datadog: DD_API_KEY=CHANGE_ME | DD_SITE=datadoghq.com
299
315
  # OpenTelemetry: OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4317 (set in compose)
300
316
  {% endif %}
317
+
318
+ # =============================================================================
319
+ # EXTRAS (Payments, SSO, Search)
320
+ # =============================================================================
321
+ {% if extras %}
322
+ {% if "stripe" in extras %}
323
+ # Stripe (active)
324
+ STRIPE_API_KEY=sk_test_placeholder
325
+ STRIPE_WEBHOOK_SECRET=whsec_placeholder
326
+ {% endif %}
327
+ {% if "sso" in extras or "sso-google" in extras or "sso-github" in extras or "sso-microsoft" in extras %}
328
+ # SSO - Google, GitHub, Microsoft (active)
329
+ GOOGLE_CLIENT_ID=placeholder
330
+ GOOGLE_CLIENT_SECRET=placeholder
331
+ GITHUB_CLIENT_ID=placeholder
332
+ GITHUB_CLIENT_SECRET=placeholder
333
+ MICROSOFT_CLIENT_ID=placeholder
334
+ MICROSOFT_CLIENT_SECRET=placeholder
335
+ {% endif %}
336
+ {% if "meilisearch" in extras %}
337
+ # Meilisearch (active)
338
+ MEILISEARCH_HOST=http://localhost:7700
339
+ MEILISEARCH_API_KEY=masterKey
340
+ {% endif %}
341
+ {% endif %}
@@ -111,6 +111,10 @@ dependencies = [
111
111
  "supabase>=2.4.0",
112
112
  {% elif vector_db == "elasticsearch" %}
113
113
  "elasticsearch[async]>=8.13.0",
114
+ {% elif vector_db == "opensearch" %}
115
+ "opensearch-py[async]>=2.5.0",
116
+ {% elif vector_db == "vespa" %}
117
+ "pyvespa>=0.40.0",
114
118
  {% endif %}
115
119
 
116
120
  {% if has_websockets %}
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "fastapi-spawn"
7
- version = "0.4.8"
7
+ version = "0.4.11"
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" }
@@ -1,36 +0,0 @@
1
- from fastapi import APIRouter, Request, HTTPException
2
- from fastapi_sso.sso.google import GoogleSSO
3
- from app.core.config import settings
4
-
5
- router = APIRouter(prefix="/sso", tags=["auth"])
6
-
7
- # Requires GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in .env
8
- google_sso = GoogleSSO(
9
- client_id=getattr(settings, "GOOGLE_CLIENT_ID", "placeholder"),
10
- client_secret=getattr(settings, "GOOGLE_CLIENT_SECRET", "placeholder"),
11
- redirect_uri="http://localhost:8000/api/v1/auth/sso/google/callback",
12
- allow_insecure_http=True, # Set to False in production
13
- )
14
-
15
- @router.get("/google/login")
16
- async def google_login():
17
- """Redirects the user to the Google login page."""
18
- with google_sso:
19
- return await google_sso.get_login_redirect()
20
-
21
- @router.get("/google/callback")
22
- async def google_callback(request: Request):
23
- """Process login response from Google and return user info."""
24
- with google_sso:
25
- user = await google_sso.verify_and_process(request)
26
- if not user:
27
- raise HTTPException(status_code=400, detail="Failed to login via Google")
28
-
29
- # TODO: Create or update user in database, then generate and return JWT
30
- return {
31
- "id": user.id,
32
- "email": user.email,
33
- "first_name": user.first_name,
34
- "last_name": user.last_name,
35
- "picture": user.picture
36
- }
File without changes
File without changes