fastapi-spawn 0.3.0__tar.gz → 0.4.1__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.1/PKG-INFO +482 -0
- fastapi_spawn-0.4.1/README.md +441 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/__init__.py +1 -1
- fastapi_spawn-0.4.1/fastapi_spawn/cli.py +405 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/generator.py +10 -2
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/config.py.j2 +2 -0
- fastapi_spawn-0.4.1/fastapi_spawn/templates/app/frontend/index.html.j2 +321 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/pyproject.toml +1 -1
- fastapi_spawn-0.3.0/PKG-INFO +0 -322
- fastapi_spawn-0.3.0/README.md +0 -281
- fastapi_spawn-0.3.0/fastapi_spawn/cli.py +0 -387
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/.gitignore +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/CHANGELOG.md +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/LICENSE +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/config.py +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/constants.py +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/interactive.py +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/alembic/alembic.ini.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/alembic/env.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/__init__.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/api/deps.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/api/graphql.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/api/v1/auth.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/api/v1/health.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/api/v1/ws.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/ai.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/email.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/exceptions.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/logger.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/logging.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/monitoring.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/notifications.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/security.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/storage.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/vector_db.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/core/ws_manager.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/db/session.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/main.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/middleware/__init__.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/middleware/rate_limit.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/app/middleware/request_logger.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/base/Makefile.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/base/README.md.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/base/env.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/base/env_example.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/base/gitignore.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/base/pre_commit.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/base/pyproject.toml.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/ci/github/publish.yml.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/ci/github/tests.yml.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/ci/gitlab/gitlab-ci.yml.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/docker/Dockerfile.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/docker/docker-compose.yml.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/docker/dockerignore.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/infra/docker/docker-compose.prod.yml.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/infra/helm/Chart.yaml.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/infra/helm/values.yaml.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/infra/terraform/main.tf.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/infra/terraform/variables.tf.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/root/main.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/tasks/arq_worker.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/tasks/celery_app.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/tasks/sample_tasks.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/tests/conftest.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/templates/tests/test_health.py.j2 +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/utils.py +0 -0
- {fastapi_spawn-0.3.0 → fastapi_spawn-0.4.1}/fastapi_spawn/validators.py +0 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fastapi-spawn
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: A powerful CLI tool to scaffold production-ready FastAPI projects with flexible database, auth, broker, and deployment options.
|
|
5
|
+
Project-URL: Homepage, https://github.com/Bishwajitgarai/fastapi-spawn
|
|
6
|
+
Project-URL: Documentation, https://github.com/Bishwajitgarai/fastapi-spawn#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/Bishwajitgarai/fastapi-spawn
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/Bishwajitgarai/fastapi-spawn/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/Bishwajitgarai/fastapi-spawn/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: Bishwajit Garai <bishwajitgarai@gmail.com>
|
|
11
|
+
License: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: boilerplate,cli,devtools,docker,fastapi,generator,jwt,project-generator,python,scaffold,sqlalchemy,template
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
25
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
|
+
Classifier: Topic :: Utilities
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Requires-Dist: click>=8.1.0
|
|
29
|
+
Requires-Dist: jinja2>=3.1.4
|
|
30
|
+
Requires-Dist: questionary>=2.0.1
|
|
31
|
+
Requires-Dist: rich>=13.7.0
|
|
32
|
+
Requires-Dist: tomli>=2.0.1; python_version < '3.11'
|
|
33
|
+
Requires-Dist: typer>=0.12.0
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: mypy>=1.10.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: pre-commit>=3.7.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
<div align="center">
|
|
43
|
+
|
|
44
|
+
# ⚡ fastapi-spawn
|
|
45
|
+
|
|
46
|
+
**The most complete FastAPI project scaffolding CLI — built for modern Python development.**
|
|
47
|
+
|
|
48
|
+
[](https://pypi.org/project/fastapi-spawn/)
|
|
49
|
+
[](https://pypi.org/project/fastapi-spawn/)
|
|
50
|
+
[](LICENSE)
|
|
51
|
+
[](https://github.com/Bishwajitgarai/fastapi-spawn/actions)
|
|
52
|
+
|
|
53
|
+
Generate production-ready FastAPI projects in seconds — with exactly the stack you need.
|
|
54
|
+
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install fastapi-spawn
|
|
63
|
+
# or
|
|
64
|
+
uv pip install fastapi-spawn
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Quick Start
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Interactive TUI — guided step-by-step
|
|
73
|
+
fastapi-spawn new my-api
|
|
74
|
+
|
|
75
|
+
# Full stack one-liner
|
|
76
|
+
fastapi-spawn new my-api \
|
|
77
|
+
--db postgresql \
|
|
78
|
+
--orm sqlalchemy \
|
|
79
|
+
--migration alembic \
|
|
80
|
+
--auth jwt \
|
|
81
|
+
--broker redis \
|
|
82
|
+
--storage s3 \
|
|
83
|
+
--ai openai \
|
|
84
|
+
--monitoring sentry \
|
|
85
|
+
--email sendgrid \
|
|
86
|
+
--notify slack \
|
|
87
|
+
--log-lib loguru \
|
|
88
|
+
--log-dest local \
|
|
89
|
+
--vector-db qdrant \
|
|
90
|
+
--api-extra both \
|
|
91
|
+
--stack full \
|
|
92
|
+
--ci github
|
|
93
|
+
|
|
94
|
+
# Preview file tree without writing
|
|
95
|
+
fastapi-spawn new my-api --dry-run
|
|
96
|
+
|
|
97
|
+
# Add a feature to an existing project
|
|
98
|
+
fastapi-spawn add openai
|
|
99
|
+
fastapi-spawn add alembic
|
|
100
|
+
fastapi-spawn add sentry
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Generated Project Structure
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
my-api/
|
|
109
|
+
├── app/
|
|
110
|
+
│ ├── api/
|
|
111
|
+
│ │ ├── graphql.py # Strawberry GraphQL schema + IDE (if graphql)
|
|
112
|
+
│ │ └── v1/
|
|
113
|
+
│ │ ├── health.py # GET /health /readiness /liveness
|
|
114
|
+
│ │ ├── auth.py # POST /auth/login /auth/refresh
|
|
115
|
+
│ │ └── ws.py # WebSocket /ws/connect /ws/connect/{room_id}
|
|
116
|
+
│ ├── core/
|
|
117
|
+
│ │ ├── config.py # Pydantic Settings v2 — individual env fields + @property URLs
|
|
118
|
+
│ │ ├── logger.py # Context-var logger — request ID, client IP, file rotation
|
|
119
|
+
│ │ ├── exceptions.py # Custom exception hierarchy + handlers
|
|
120
|
+
│ │ ├── security.py # JWT / bcrypt
|
|
121
|
+
│ │ ├── ws_manager.py # WebSocket connection manager — broadcast, rooms
|
|
122
|
+
│ │ ├── storage.py # AWS S3/MinIO | GCS | Cloudinary
|
|
123
|
+
│ │ ├── ai.py # OpenAI | Anthropic | Gemini | Ollama | LangChain | LlamaIndex
|
|
124
|
+
│ │ ├── monitoring.py # Sentry | Prometheus | OpenTelemetry
|
|
125
|
+
│ │ ├── email.py # SendGrid | SMTP | AWS SES
|
|
126
|
+
│ │ ├── notifications.py # Slack | Discord webhooks
|
|
127
|
+
│ │ └── vector_db.py # Qdrant | ChromaDB | Pinecone | Supabase | Elasticsearch
|
|
128
|
+
│ ├── middleware/
|
|
129
|
+
│ │ ├── request_logger.py # X-Request-ID, response time, structured logs
|
|
130
|
+
│ │ └── rate_limit.py # slowapi — 200/min default, 429 + Retry-After
|
|
131
|
+
│ ├── db/
|
|
132
|
+
│ │ └── session.py # Async SQLAlchemy / SQLModel / Tortoise / Beanie
|
|
133
|
+
│ ├── models/
|
|
134
|
+
│ ├── schemas/
|
|
135
|
+
│ ├── services/
|
|
136
|
+
│ └── repositories/
|
|
137
|
+
├── tasks/
|
|
138
|
+
│ ├── celery_app.py # Celery (Redis / RabbitMQ)
|
|
139
|
+
│ ├── sample_tasks.py
|
|
140
|
+
│ └── arq_worker.py # Arq async task queue (if arq)
|
|
141
|
+
├── migrations/ # Alembic async
|
|
142
|
+
│ ├── env.py
|
|
143
|
+
│ └── versions/
|
|
144
|
+
├── infra/
|
|
145
|
+
│ ├── docker/
|
|
146
|
+
│ ├── helm/
|
|
147
|
+
│ └── terraform/
|
|
148
|
+
├── tests/
|
|
149
|
+
├── logs/ # Local rotating logs
|
|
150
|
+
├── main.py # uv run main.py
|
|
151
|
+
├── alembic.ini
|
|
152
|
+
├── Dockerfile
|
|
153
|
+
├── docker-compose.yml
|
|
154
|
+
├── Makefile
|
|
155
|
+
├── .env # gitignored
|
|
156
|
+
├── .env.example # full reference of every supported variable
|
|
157
|
+
├── .gitignore
|
|
158
|
+
├── .pre-commit-config.yaml
|
|
159
|
+
└── pyproject.toml # [tool.uv.scripts] pre-wired
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## All Options
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
fastapi-spawn new [OPTIONS] PROJECT_NAME
|
|
168
|
+
|
|
169
|
+
Database & ORM
|
|
170
|
+
--db postgresql | mysql | mongodb | sqlite | supabase | duckdb | none
|
|
171
|
+
--orm sqlalchemy | sqlmodel | tortoise | beanie | none
|
|
172
|
+
--migration alembic | aerich | none
|
|
173
|
+
|
|
174
|
+
Auth & Security
|
|
175
|
+
--auth jwt | oauth2 | api-key | auth0 | none
|
|
176
|
+
|
|
177
|
+
Messaging & Cache
|
|
178
|
+
--broker redis | rabbitmq | kafka | arq | none
|
|
179
|
+
--cache redis | memcached | none
|
|
180
|
+
|
|
181
|
+
Storage
|
|
182
|
+
--storage s3 | gcs | cloudinary | local | none
|
|
183
|
+
|
|
184
|
+
AI / LLM
|
|
185
|
+
--ai openai | anthropic | gemini | ollama | langchain | llamaindex | none
|
|
186
|
+
|
|
187
|
+
API Extras
|
|
188
|
+
--api-extra websockets | graphql | both | none
|
|
189
|
+
|
|
190
|
+
Monitoring
|
|
191
|
+
--monitoring sentry | prometheus | opentelemetry | both | none
|
|
192
|
+
|
|
193
|
+
Email
|
|
194
|
+
--email sendgrid | smtp | ses | none
|
|
195
|
+
|
|
196
|
+
Notifications
|
|
197
|
+
--notify slack | discord | none
|
|
198
|
+
|
|
199
|
+
Logging
|
|
200
|
+
--log-lib loguru | structlog | standard
|
|
201
|
+
--log-dest local | cloudwatch | datadog | none
|
|
202
|
+
|
|
203
|
+
Vector Database
|
|
204
|
+
--vector-db qdrant | chroma | pinecone | supabase | elasticsearch | none
|
|
205
|
+
|
|
206
|
+
Deployment
|
|
207
|
+
--stack minimal | standard | full
|
|
208
|
+
--ci github | gitlab | both | none
|
|
209
|
+
|
|
210
|
+
Flags
|
|
211
|
+
--no-docker Skip Docker files
|
|
212
|
+
--no-tests Skip test suite
|
|
213
|
+
--dry-run Preview file tree without writing
|
|
214
|
+
--force / -f Overwrite existing directory
|
|
215
|
+
--output / -o Output directory (default: .)
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## uv run Scripts
|
|
221
|
+
|
|
222
|
+
Every generated project has `[tool.uv.scripts]` pre-wired:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
uv run dev # uvicorn --reload
|
|
226
|
+
uv run start # python main.py
|
|
227
|
+
uv run test # pytest --cov
|
|
228
|
+
uv run lint # ruff check
|
|
229
|
+
uv run format # ruff format
|
|
230
|
+
uv run typecheck # mypy
|
|
231
|
+
uv run migrate # alembic upgrade head (if alembic)
|
|
232
|
+
uv run rollback # alembic downgrade -1 (if alembic)
|
|
233
|
+
uv run makemig # alembic revision --autogenerate (if alembic)
|
|
234
|
+
uv run worker # celery worker (if celery)
|
|
235
|
+
uv run beat # celery beat (if celery)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Environment Variables
|
|
241
|
+
|
|
242
|
+
**Individual fields per service — no URL strings.** All connection URLs are assembled via `@property` in `app/core/config.py`. Your `.env.example` includes every supported variable:
|
|
243
|
+
|
|
244
|
+
```env
|
|
245
|
+
# ── Application ──────────────────────────────────────────────────────────────
|
|
246
|
+
APP_NAME=my-api
|
|
247
|
+
ENVIRONMENT=dev # dev | staging | production
|
|
248
|
+
SECRET_KEY=CHANGE_ME # openssl rand -hex 32
|
|
249
|
+
CORS_ORIGINS=http://localhost:3000,http://localhost:8000
|
|
250
|
+
|
|
251
|
+
# ── Logging ───────────────────────────────────────────────────────────────────
|
|
252
|
+
LOG_LEVEL=INFO
|
|
253
|
+
LOG_DIR=logs
|
|
254
|
+
LOG_BACKUP_DAYS=30
|
|
255
|
+
|
|
256
|
+
# ── PostgreSQL ─────────────────────────────────────────────────────────────
|
|
257
|
+
POSTGRES_USER=postgres
|
|
258
|
+
POSTGRES_PASSWORD=CHANGE_ME
|
|
259
|
+
POSTGRES_HOST=localhost
|
|
260
|
+
POSTGRES_PORT=5432
|
|
261
|
+
POSTGRES_DB=my_api_db
|
|
262
|
+
# → assembled as: postgresql+asyncpg://USER:PASS@HOST:PORT/DB
|
|
263
|
+
|
|
264
|
+
# ── MySQL ─────────────────────────────────────────────────────────────────
|
|
265
|
+
MYSQL_USER=root
|
|
266
|
+
MYSQL_PASSWORD=CHANGE_ME
|
|
267
|
+
MYSQL_HOST=localhost
|
|
268
|
+
MYSQL_PORT=3306
|
|
269
|
+
MYSQL_DB=my_api_db
|
|
270
|
+
# → assembled as: mysql+aiomysql://USER:PASS@HOST:PORT/DB
|
|
271
|
+
|
|
272
|
+
# ── MongoDB ───────────────────────────────────────────────────────────────
|
|
273
|
+
MONGODB_USER=mongo
|
|
274
|
+
MONGODB_PASSWORD=CHANGE_ME
|
|
275
|
+
MONGODB_HOST=localhost
|
|
276
|
+
MONGODB_PORT=27017
|
|
277
|
+
MONGODB_DB=my_api_db
|
|
278
|
+
# → assembled as: mongodb://USER:PASS@HOST:PORT
|
|
279
|
+
|
|
280
|
+
# ── Supabase ──────────────────────────────────────────────────────────────
|
|
281
|
+
SUPABASE_URL=https://xxxx.supabase.co
|
|
282
|
+
SUPABASE_KEY=CHANGE_ME # anon or service role key
|
|
283
|
+
|
|
284
|
+
# ── DuckDB ────────────────────────────────────────────────────────────────
|
|
285
|
+
DUCKDB_FILE=my_api.duckdb
|
|
286
|
+
|
|
287
|
+
# ── Redis ─────────────────────────────────────────────────────────────────
|
|
288
|
+
REDIS_HOST=localhost
|
|
289
|
+
REDIS_PORT=6379
|
|
290
|
+
REDIS_PASSWORD=
|
|
291
|
+
REDIS_DB=0
|
|
292
|
+
# → assembled as: redis://:PASS@HOST:PORT/DB
|
|
293
|
+
|
|
294
|
+
# ── RabbitMQ ─────────────────────────────────────────────────────────────
|
|
295
|
+
RABBITMQ_USER=guest
|
|
296
|
+
RABBITMQ_PASSWORD=CHANGE_ME
|
|
297
|
+
RABBITMQ_HOST=localhost
|
|
298
|
+
RABBITMQ_PORT=5672
|
|
299
|
+
RABBITMQ_VHOST=/
|
|
300
|
+
# → assembled as: amqp://USER:PASS@HOST:PORT/VHOST
|
|
301
|
+
|
|
302
|
+
# ── Kafka ────────────────────────────────────────────────────────────────
|
|
303
|
+
KAFKA_HOST=localhost
|
|
304
|
+
KAFKA_PORT=9092
|
|
305
|
+
# → assembled as: HOST:PORT
|
|
306
|
+
|
|
307
|
+
# ── Auth / JWT ───────────────────────────────────────────────────────────
|
|
308
|
+
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
|
309
|
+
REFRESH_TOKEN_EXPIRE_DAYS=7
|
|
310
|
+
ALGORITHM=HS256
|
|
311
|
+
|
|
312
|
+
# ── Auth0 ────────────────────────────────────────────────────────────────
|
|
313
|
+
AUTH0_DOMAIN=your-tenant.auth0.com
|
|
314
|
+
AUTH0_CLIENT_ID=CHANGE_ME
|
|
315
|
+
AUTH0_CLIENT_SECRET=CHANGE_ME
|
|
316
|
+
AUTH0_AUDIENCE=https://your-api.example.com
|
|
317
|
+
|
|
318
|
+
# ── AWS (S3 / SES / CloudWatch) ──────────────────────────────────────────
|
|
319
|
+
AWS_ACCESS_KEY_ID=CHANGE_ME
|
|
320
|
+
AWS_SECRET_ACCESS_KEY=CHANGE_ME
|
|
321
|
+
AWS_REGION=us-east-1
|
|
322
|
+
AWS_S3_BUCKET=my-api-bucket
|
|
323
|
+
AWS_S3_ENDPOINT_URL= # http://localhost:9000 for MinIO
|
|
324
|
+
|
|
325
|
+
# ── Google Cloud Storage ─────────────────────────────────────────────────
|
|
326
|
+
GCS_PROJECT_ID=CHANGE_ME
|
|
327
|
+
GCS_BUCKET=my-api-bucket
|
|
328
|
+
GOOGLE_APPLICATION_CREDENTIALS=./service-account.json
|
|
329
|
+
|
|
330
|
+
# ── Cloudinary ───────────────────────────────────────────────────────────
|
|
331
|
+
CLOUDINARY_CLOUD_NAME=CHANGE_ME
|
|
332
|
+
CLOUDINARY_API_KEY=CHANGE_ME
|
|
333
|
+
CLOUDINARY_API_SECRET=CHANGE_ME
|
|
334
|
+
|
|
335
|
+
# ── OpenAI ───────────────────────────────────────────────────────────────
|
|
336
|
+
OPENAI_API_KEY=sk-placeholder
|
|
337
|
+
OPENAI_MODEL=gpt-4o
|
|
338
|
+
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
|
|
339
|
+
OPENAI_BASE_URL= # blank = api.openai.com
|
|
340
|
+
# Azure: https://<resource>.openai.azure.com/
|
|
341
|
+
# LM Studio: http://localhost:1234/v1
|
|
342
|
+
|
|
343
|
+
# ── Anthropic ────────────────────────────────────────────────────────────
|
|
344
|
+
ANTHROPIC_API_KEY=sk-ant-placeholder
|
|
345
|
+
ANTHROPIC_MODEL=claude-3-5-sonnet-20241022
|
|
346
|
+
|
|
347
|
+
# ── Google Gemini ────────────────────────────────────────────────────────
|
|
348
|
+
GEMINI_API_KEY=CHANGE_ME
|
|
349
|
+
GEMINI_MODEL=gemini-1.5-pro
|
|
350
|
+
|
|
351
|
+
# ── Ollama (local LLM — no API key) ─────────────────────────────────────
|
|
352
|
+
OLLAMA_HOST=localhost
|
|
353
|
+
OLLAMA_PORT=11434
|
|
354
|
+
OLLAMA_MODEL=llama3
|
|
355
|
+
# → assembled as: http://HOST:PORT
|
|
356
|
+
|
|
357
|
+
# ── Sentry ───────────────────────────────────────────────────────────────
|
|
358
|
+
SENTRY_DSN=https://xxx@sentry.io/yyy
|
|
359
|
+
|
|
360
|
+
# ── Datadog ──────────────────────────────────────────────────────────────
|
|
361
|
+
DD_API_KEY=CHANGE_ME
|
|
362
|
+
DD_SITE=datadoghq.com
|
|
363
|
+
|
|
364
|
+
# ── SendGrid ─────────────────────────────────────────────────────────────
|
|
365
|
+
SENDGRID_API_KEY=SG.placeholder
|
|
366
|
+
SENDGRID_FROM_EMAIL=noreply@example.com
|
|
367
|
+
|
|
368
|
+
# ── SMTP ─────────────────────────────────────────────────────────────────
|
|
369
|
+
SMTP_HOST=smtp.gmail.com
|
|
370
|
+
SMTP_PORT=587
|
|
371
|
+
SMTP_USER=CHANGE_ME
|
|
372
|
+
SMTP_PASSWORD=CHANGE_ME
|
|
373
|
+
SMTP_FROM_EMAIL=noreply@example.com
|
|
374
|
+
SMTP_STARTTLS=true
|
|
375
|
+
SMTP_SSL=false
|
|
376
|
+
|
|
377
|
+
# ── AWS SES ──────────────────────────────────────────────────────────────
|
|
378
|
+
SES_FROM_EMAIL=noreply@example.com # uses AWS_* credentials above
|
|
379
|
+
|
|
380
|
+
# ── Slack ────────────────────────────────────────────────────────────────
|
|
381
|
+
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/CHANGE_ME
|
|
382
|
+
|
|
383
|
+
# ── Discord ──────────────────────────────────────────────────────────────
|
|
384
|
+
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/CHANGE_ME
|
|
385
|
+
|
|
386
|
+
# ── Qdrant ───────────────────────────────────────────────────────────────
|
|
387
|
+
QDRANT_HOST=localhost
|
|
388
|
+
QDRANT_PORT=6333
|
|
389
|
+
QDRANT_API_KEY= # blank for local Docker Qdrant
|
|
390
|
+
# → assembled as: http://HOST:PORT
|
|
391
|
+
|
|
392
|
+
# ── Pinecone ─────────────────────────────────────────────────────────────
|
|
393
|
+
PINECONE_API_KEY=CHANGE_ME
|
|
394
|
+
PINECONE_INDEX_NAME=my-api-index
|
|
395
|
+
|
|
396
|
+
# ── Elasticsearch ────────────────────────────────────────────────────────
|
|
397
|
+
ELASTICSEARCH_HOST=localhost
|
|
398
|
+
ELASTICSEARCH_PORT=9200
|
|
399
|
+
ELASTICSEARCH_API_KEY=
|
|
400
|
+
# → assembled as: http://HOST:PORT
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
> All variables are assembled into connection URLs inside `app/core/config.py` via `@property`. Your code always reads from structured fields — never a fragile connection string.
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Middleware (always included)
|
|
408
|
+
|
|
409
|
+
| Middleware | Behaviour |
|
|
410
|
+
|---|---|
|
|
411
|
+
| `RequestLoggingMiddleware` | Assigns `X-Request-ID`, logs `→ METHOD /path` + `✓ status Xms` with client IP |
|
|
412
|
+
| `RateLimitMiddleware` | 200 req/min default via `slowapi`, returns `429` + `Retry-After: 60` |
|
|
413
|
+
| `CORSMiddleware` | Configurable origins via `CORS_ORIGINS` env var |
|
|
414
|
+
|
|
415
|
+
Every response carries `X-Request-ID` and `X-Response-Time` headers automatically.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## WebSockets
|
|
420
|
+
|
|
421
|
+
```python
|
|
422
|
+
# Connect: ws://host/api/v1/ws/connect
|
|
423
|
+
# Room: ws://host/api/v1/ws/connect/{room_id}
|
|
424
|
+
|
|
425
|
+
# Client protocol
|
|
426
|
+
{"type": "broadcast", "data": "hello everyone"}
|
|
427
|
+
{"type": "ping"} # → {"type": "pong"}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## GraphQL
|
|
433
|
+
|
|
434
|
+
Strawberry schema with **Query + Mutation + Subscription** is mounted at `/graphql`.
|
|
435
|
+
GraphiQL IDE is enabled in `dev` mode. Subscriptions use `graphql-transport-ws`.
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## Add Features to Existing Projects
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
fastapi-spawn add sentry # Sentry error tracking
|
|
443
|
+
fastapi-spawn add openai # OpenAI async client
|
|
444
|
+
fastapi-spawn add alembic # Alembic async migrations
|
|
445
|
+
fastapi-spawn add s3 # AWS S3 / MinIO storage
|
|
446
|
+
fastapi-spawn add celery # Celery worker + tasks/
|
|
447
|
+
fastapi-spawn add websockets # WebSocket connection manager
|
|
448
|
+
fastapi-spawn add graphql # Strawberry GraphQL schema
|
|
449
|
+
fastapi-spawn add qdrant # Qdrant vector DB
|
|
450
|
+
fastapi-spawn add chroma # ChromaDB local vector DB
|
|
451
|
+
fastapi-spawn add helm # Helm chart in infra/helm/
|
|
452
|
+
fastapi-spawn add terraform # Terraform in infra/terraform/
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## ORM ↔ Database Compatibility
|
|
458
|
+
|
|
459
|
+
| ORM | Compatible Databases |
|
|
460
|
+
|---|---|
|
|
461
|
+
| `sqlalchemy` | postgresql, mysql, sqlite, supabase |
|
|
462
|
+
| `sqlmodel` | postgresql, mysql, sqlite, supabase |
|
|
463
|
+
| `tortoise` | postgresql, mysql, sqlite |
|
|
464
|
+
| `beanie` | mongodb |
|
|
465
|
+
| `none` | any |
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## Contributing
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
git clone https://github.com/Bishwajitgarai/fastapi-spawn
|
|
473
|
+
cd fastapi-spawn
|
|
474
|
+
uv sync --all-extras
|
|
475
|
+
uv run pytest
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## License
|
|
481
|
+
|
|
482
|
+
MIT © [Bishwajit Garai](https://github.com/Bishwajitgarai)
|