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.
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/PKG-INFO +13 -8
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/README.md +12 -7
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/__init__.py +1 -1
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/cli.py +12 -4
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/constants.py +6 -2
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/generator.py +2 -1
- fastapi_spawn-0.4.11/fastapi_spawn/templates/app/api/v1/auth/sso.py.j2 +116 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/env.j2 +21 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/env_example.j2 +41 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/pyproject.toml.j2 +4 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/pyproject.toml +1 -1
- fastapi_spawn-0.4.8/fastapi_spawn/templates/app/api/v1/auth/sso.py.j2 +0 -36
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/.gitignore +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/LICENSE +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/config.py +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/interactive.py +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/alembic/alembic.ini.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/alembic/env.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/__init__.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/deps.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/graphql.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/auth/router.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/health/router.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/payments/router.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/router.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/streaming/router.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/ws/router.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/ai.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/config.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/email.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/exceptions.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/logger.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/logging.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/monitoring.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/notifications.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/ocr.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/search.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/security.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/storage.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/vector_db.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/ws_manager.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/db/session.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/frontend/index.html.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/main.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/middleware/__init__.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/middleware/rate_limit.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/middleware/request_logger.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/Makefile.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/README.md.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/gitignore.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/base/pre_commit.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/ci/github/publish.yml.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/ci/github/tests.yml.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/ci/gitlab/gitlab-ci.yml.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/db/seed.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/docker/Dockerfile.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/docker/docker-compose.yml.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/docker/dockerignore.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/docker/docker-compose.prod.yml.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/helm/Chart.yaml.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/helm/values.yaml.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/terraform/main.tf.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/terraform/variables.tf.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/root/main.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tasks/arq_worker.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tasks/celery_app.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tasks/sample_tasks.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tests/conftest.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tests/test_health.py.j2 +0 -0
- {fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/utils.py +0 -0
- {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.
|
|
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
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
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
|
|
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
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
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
|
|
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
|
|
@@ -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 (
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/auth/router.py.j2
RENAMED
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/health/router.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/router.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/api/v1/ws/router.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/exceptions.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/monitoring.py.j2
RENAMED
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/notifications.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/security.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/vector_db.py.j2
RENAMED
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/core/ws_manager.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/frontend/index.html.j2
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/middleware/__init__.py.j2
RENAMED
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/app/middleware/rate_limit.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/ci/github/publish.yml.j2
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/ci/gitlab/gitlab-ci.yml.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/docker/docker-compose.yml.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/helm/Chart.yaml.j2
RENAMED
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/helm/values.yaml.j2
RENAMED
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/terraform/main.tf.j2
RENAMED
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/infra/terraform/variables.tf.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tasks/sample_tasks.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_spawn-0.4.8 → fastapi_spawn-0.4.11}/fastapi_spawn/templates/tests/test_health.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|