backend-dash 0.1.0__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.
- backend_dash-0.1.0/.gitignore +33 -0
- backend_dash-0.1.0/LICENSE +21 -0
- backend_dash-0.1.0/PKG-INFO +178 -0
- backend_dash-0.1.0/README.md +153 -0
- backend_dash-0.1.0/pyproject.toml +41 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/__init__.py +1 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/cli.py +117 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/db_migrations/alembic/README +1 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/db_migrations/alembic/env.py +52 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/db_migrations/alembic/script.py.mako +28 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/db_migrations/alembic/versions/.gitkeep +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/db_migrations/alembic.ini +149 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/.env.example.j2 +63 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/README.md.j2 +40 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/api/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/api/deps.py.j2 +48 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/api/v1/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/api/v1/api.py.j2 +14 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/api/v1/routes_item.py +42 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/core/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/core/config.py.j2 +49 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/core/exceptions.py +41 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/crud/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/crud/item.py +38 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/db/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/db/base.py.j2 +9 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/db/base_class.py +10 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/db/init_db.py +11 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/db/session.py +28 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/main.py.j2 +44 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/models/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/models/item.py +17 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/schemas/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/schemas/item.py +27 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/app/utils/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/requirements.txt.j2 +19 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/tests/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite/tests/test_items.py +48 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite_auth/app/api/v1/routes_auth.py +57 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite_auth/app/core/security.py +35 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite_auth/app/models/user.py +20 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite_auth/app/repositories/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite_auth/app/repositories/base.py +46 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite_auth/app/repositories/user_repository.py +15 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite_auth/app/schemas/user.py +30 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite_auth/app/services/__init__.py +0 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite_auth/app/services/auth_service.py +108 -0
- backend_dash-0.1.0/src/fastapi_scaffolder/templates/fastapi_sqlite_auth/tests/test_auth.py +85 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
|
|
7
|
+
# Build artifacts
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
|
|
11
|
+
# Virtual environments
|
|
12
|
+
.venv/
|
|
13
|
+
venv/
|
|
14
|
+
env/
|
|
15
|
+
|
|
16
|
+
# Testing
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.coverage
|
|
19
|
+
htmlcov/
|
|
20
|
+
|
|
21
|
+
# Env files / secrets
|
|
22
|
+
.env
|
|
23
|
+
|
|
24
|
+
# Editor
|
|
25
|
+
.vscode/
|
|
26
|
+
.idea/
|
|
27
|
+
|
|
28
|
+
# OS
|
|
29
|
+
.DS_Store
|
|
30
|
+
Thumbs.db
|
|
31
|
+
|
|
32
|
+
# SQLite databases generated by running the app
|
|
33
|
+
*.db
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pratham
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: backend-dash
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Scaffold a FastAPI + SQLAlchemy backend with SQLite/Postgres/MySQL and optional JWT + Google OAuth auth
|
|
5
|
+
Project-URL: Homepage, https://github.com/prathamdmehta/backend-dash
|
|
6
|
+
Project-URL: Repository, https://github.com/prathamdmehta/backend-dash
|
|
7
|
+
Author: Pratham
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: backend,boilerplate,cli,fastapi,scaffold,sqlalchemy
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Framework :: FastAPI
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
20
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: jinja2>=3.1
|
|
23
|
+
Requires-Dist: typer>=0.12
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# backend-dash
|
|
27
|
+
|
|
28
|
+
A CLI that generates ready-to-code FastAPI backend projects with SQLAlchemy, SQLite, PostgreSQL, MySQL, Alembic migrations, CRUD examples, tests, and optional JWT + Google OAuth authentication.
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
- Scaffold a complete FastAPI backend in seconds.
|
|
33
|
+
- Supports `--db=sqlite|postgres|mysql` with SQLite as the default.
|
|
34
|
+
- Generates a working SQLAlchemy setup and DB session wiring.
|
|
35
|
+
- Adds an example CRUD resource so you can start from real code, not boilerplate.
|
|
36
|
+
- Includes tests for the generated project.
|
|
37
|
+
- Adds Alembic migrations for PostgreSQL and MySQL.
|
|
38
|
+
- Keeps SQLite simple with `create_all` for zero-config local development.
|
|
39
|
+
- Optional `--auth` mode adds JWT + Google OAuth auth support.
|
|
40
|
+
- Clear validation for unsupported database values.
|
|
41
|
+
- Clean `.env.example` setup for local development and migrations.
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
### One-off usage
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uvx backend-dash init "My API"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Install locally
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install backend-dash
|
|
55
|
+
backend-dash init "My API"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Editable install for development
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/prathamdmehta/backend-dash.git
|
|
62
|
+
cd backend-dash
|
|
63
|
+
pip install -e . --break-system-packages
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
Create a new project:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
backend-dash init "Demo Project"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Create a project with auth:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
backend-dash init "Demo Project Auth" --auth
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Choose a database:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
backend-dash init "My API" --db=sqlite
|
|
84
|
+
backend-dash init "My API" --db=postgres
|
|
85
|
+
backend-dash init "My API" --db=mysql
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Combine database and auth:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
backend-dash init "My API" --db=postgres --auth
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## What gets generated
|
|
95
|
+
|
|
96
|
+
### Base project
|
|
97
|
+
|
|
98
|
+
- FastAPI app structure.
|
|
99
|
+
- SQLAlchemy session and base model wiring.
|
|
100
|
+
- Example item resource with CRUD routes.
|
|
101
|
+
- Pydantic schemas and models.
|
|
102
|
+
- Pytest test setup.
|
|
103
|
+
|
|
104
|
+
### With `--auth`
|
|
105
|
+
|
|
106
|
+
- Repository layer with a generic `BaseRepository` and `UserRepository`.
|
|
107
|
+
- Auth service for registration, login, JWT issuance, and Google token exchange.
|
|
108
|
+
- Validation with proper schema constraints.
|
|
109
|
+
- Centralized error handling with a consistent error response shape.
|
|
110
|
+
- Auth routes for register, login, me, Google login, and Google callback.
|
|
111
|
+
|
|
112
|
+
## Database support
|
|
113
|
+
|
|
114
|
+
### SQLite
|
|
115
|
+
|
|
116
|
+
SQLite is the default and uses `create_all` for a simple local setup.
|
|
117
|
+
|
|
118
|
+
### PostgreSQL
|
|
119
|
+
|
|
120
|
+
For PostgreSQL, the scaffold uses Alembic migrations and real schema management.
|
|
121
|
+
|
|
122
|
+
### MySQL
|
|
123
|
+
|
|
124
|
+
For MySQL, the scaffold also uses Alembic migrations and the correct MySQL driver setup.
|
|
125
|
+
|
|
126
|
+
## Migrations
|
|
127
|
+
|
|
128
|
+
For PostgreSQL and MySQL, the project generates Alembic configuration and an `env.py` wired to `DATABASE_URL` and your app metadata.
|
|
129
|
+
|
|
130
|
+
Typical workflow:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
alembic revision --autogenerate -m "create initial tables"
|
|
134
|
+
alembic upgrade head
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The generated `.env.example` includes the right migration flow so you can move from scaffold to production-style schema management quickly.
|
|
138
|
+
|
|
139
|
+
## Project structure
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
my_api/
|
|
143
|
+
├── app/
|
|
144
|
+
├── tests/
|
|
145
|
+
├── alembic/
|
|
146
|
+
├── alembic.ini
|
|
147
|
+
└── .env.example
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
If `--auth` is enabled, additional auth-related modules are included inside the app structure.
|
|
151
|
+
|
|
152
|
+
## Example
|
|
153
|
+
|
|
154
|
+
Generate a new API project:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
backend-dash init "Orders API" --db=postgres --auth
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
This creates a FastAPI backend with database wiring, migrations, tests, and authentication already in place, so you can start on business logic immediately.
|
|
161
|
+
|
|
162
|
+
## Development
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
git clone https://github.com/prathamdmehta/backend-dash.git
|
|
166
|
+
cd backend-dash
|
|
167
|
+
pip install -e . --break-system-packages
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Then run the CLI locally:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
backend-dash init "Demo Project"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
MIT
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# backend-dash
|
|
2
|
+
|
|
3
|
+
A CLI that generates ready-to-code FastAPI backend projects with SQLAlchemy, SQLite, PostgreSQL, MySQL, Alembic migrations, CRUD examples, tests, and optional JWT + Google OAuth authentication.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Scaffold a complete FastAPI backend in seconds.
|
|
8
|
+
- Supports `--db=sqlite|postgres|mysql` with SQLite as the default.
|
|
9
|
+
- Generates a working SQLAlchemy setup and DB session wiring.
|
|
10
|
+
- Adds an example CRUD resource so you can start from real code, not boilerplate.
|
|
11
|
+
- Includes tests for the generated project.
|
|
12
|
+
- Adds Alembic migrations for PostgreSQL and MySQL.
|
|
13
|
+
- Keeps SQLite simple with `create_all` for zero-config local development.
|
|
14
|
+
- Optional `--auth` mode adds JWT + Google OAuth auth support.
|
|
15
|
+
- Clear validation for unsupported database values.
|
|
16
|
+
- Clean `.env.example` setup for local development and migrations.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
### One-off usage
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uvx backend-dash init "My API"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Install locally
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install backend-dash
|
|
30
|
+
backend-dash init "My API"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Editable install for development
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git clone https://github.com/prathamdmehta/backend-dash.git
|
|
37
|
+
cd backend-dash
|
|
38
|
+
pip install -e . --break-system-packages
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
Create a new project:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
backend-dash init "Demo Project"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Create a project with auth:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
backend-dash init "Demo Project Auth" --auth
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Choose a database:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
backend-dash init "My API" --db=sqlite
|
|
59
|
+
backend-dash init "My API" --db=postgres
|
|
60
|
+
backend-dash init "My API" --db=mysql
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Combine database and auth:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
backend-dash init "My API" --db=postgres --auth
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## What gets generated
|
|
70
|
+
|
|
71
|
+
### Base project
|
|
72
|
+
|
|
73
|
+
- FastAPI app structure.
|
|
74
|
+
- SQLAlchemy session and base model wiring.
|
|
75
|
+
- Example item resource with CRUD routes.
|
|
76
|
+
- Pydantic schemas and models.
|
|
77
|
+
- Pytest test setup.
|
|
78
|
+
|
|
79
|
+
### With `--auth`
|
|
80
|
+
|
|
81
|
+
- Repository layer with a generic `BaseRepository` and `UserRepository`.
|
|
82
|
+
- Auth service for registration, login, JWT issuance, and Google token exchange.
|
|
83
|
+
- Validation with proper schema constraints.
|
|
84
|
+
- Centralized error handling with a consistent error response shape.
|
|
85
|
+
- Auth routes for register, login, me, Google login, and Google callback.
|
|
86
|
+
|
|
87
|
+
## Database support
|
|
88
|
+
|
|
89
|
+
### SQLite
|
|
90
|
+
|
|
91
|
+
SQLite is the default and uses `create_all` for a simple local setup.
|
|
92
|
+
|
|
93
|
+
### PostgreSQL
|
|
94
|
+
|
|
95
|
+
For PostgreSQL, the scaffold uses Alembic migrations and real schema management.
|
|
96
|
+
|
|
97
|
+
### MySQL
|
|
98
|
+
|
|
99
|
+
For MySQL, the scaffold also uses Alembic migrations and the correct MySQL driver setup.
|
|
100
|
+
|
|
101
|
+
## Migrations
|
|
102
|
+
|
|
103
|
+
For PostgreSQL and MySQL, the project generates Alembic configuration and an `env.py` wired to `DATABASE_URL` and your app metadata.
|
|
104
|
+
|
|
105
|
+
Typical workflow:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
alembic revision --autogenerate -m "create initial tables"
|
|
109
|
+
alembic upgrade head
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The generated `.env.example` includes the right migration flow so you can move from scaffold to production-style schema management quickly.
|
|
113
|
+
|
|
114
|
+
## Project structure
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
my_api/
|
|
118
|
+
├── app/
|
|
119
|
+
├── tests/
|
|
120
|
+
├── alembic/
|
|
121
|
+
├── alembic.ini
|
|
122
|
+
└── .env.example
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
If `--auth` is enabled, additional auth-related modules are included inside the app structure.
|
|
126
|
+
|
|
127
|
+
## Example
|
|
128
|
+
|
|
129
|
+
Generate a new API project:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
backend-dash init "Orders API" --db=postgres --auth
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
This creates a FastAPI backend with database wiring, migrations, tests, and authentication already in place, so you can start on business logic immediately.
|
|
136
|
+
|
|
137
|
+
## Development
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
git clone https://github.com/prathamdmehta/backend-dash.git
|
|
141
|
+
cd backend-dash
|
|
142
|
+
pip install -e . --break-system-packages
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Then run the CLI locally:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
backend-dash init "Demo Project"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "backend-dash"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Scaffold a FastAPI + SQLAlchemy backend with SQLite/Postgres/MySQL and optional JWT + Google OAuth auth"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Pratham" },
|
|
10
|
+
]
|
|
11
|
+
keywords = ["fastapi", "sqlalchemy", "scaffold", "boilerplate", "cli", "backend"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 3 - Alpha",
|
|
14
|
+
"Environment :: Console",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Topic :: Software Development :: Code Generators",
|
|
21
|
+
"Topic :: Software Development :: Build Tools",
|
|
22
|
+
"Framework :: FastAPI",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"typer>=0.12",
|
|
26
|
+
"jinja2>=3.1",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/prathamdmehta/backend-dash"
|
|
31
|
+
Repository = "https://github.com/prathamdmehta/backend-dash"
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
backend-dash = "fastapi_scaffolder.cli:main"
|
|
35
|
+
|
|
36
|
+
[build-system]
|
|
37
|
+
requires = ["hatchling"]
|
|
38
|
+
build-backend = "hatchling.build"
|
|
39
|
+
|
|
40
|
+
[tool.hatch.build.targets.wheel]
|
|
41
|
+
packages = ["src/fastapi_scaffolder"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import shutil
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
from jinja2 import Environment, FileSystemLoader
|
|
7
|
+
|
|
8
|
+
app = typer.Typer(
|
|
9
|
+
help="Scaffold a FastAPI + SQLAlchemy backend so you can skip the boilerplate."
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
TEMPLATES_ROOT = Path(__file__).parent / "templates"
|
|
13
|
+
VALID_DBS = ("sqlite", "postgres", "mysql")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def slugify(name: str) -> str:
|
|
17
|
+
"""Turn 'My Cool API' into 'my_cool_api' for use as a folder name."""
|
|
18
|
+
slug = re.sub(r"[^a-zA-Z0-9]+", "_", name.strip()).strip("_").lower()
|
|
19
|
+
return slug or "backend_project"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def render_template(template_dir: Path, target_dir: Path, context: dict) -> None:
|
|
23
|
+
env = Environment(loader=FileSystemLoader(str(template_dir)), keep_trailing_newline=True)
|
|
24
|
+
|
|
25
|
+
for src_path in sorted(template_dir.rglob("*")):
|
|
26
|
+
if src_path.is_dir():
|
|
27
|
+
continue
|
|
28
|
+
|
|
29
|
+
rel_path = src_path.relative_to(template_dir)
|
|
30
|
+
rel_str = rel_path.as_posix()
|
|
31
|
+
is_template = rel_str.endswith(".j2")
|
|
32
|
+
out_rel = Path(rel_str[:-3]) if is_template else rel_path
|
|
33
|
+
out_path = target_dir / out_rel
|
|
34
|
+
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
35
|
+
|
|
36
|
+
if is_template:
|
|
37
|
+
rendered = env.get_template(rel_str).render(**context)
|
|
38
|
+
out_path.write_text(rendered, encoding="utf-8")
|
|
39
|
+
else:
|
|
40
|
+
shutil.copy2(src_path, out_path)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@app.command()
|
|
44
|
+
def init(
|
|
45
|
+
project_name: str = typer.Argument(..., help="Human-readable project name, e.g. 'My API'"),
|
|
46
|
+
directory: str = typer.Option(
|
|
47
|
+
None,
|
|
48
|
+
"--dir",
|
|
49
|
+
help="Folder to create the project in. Defaults to a slugified version of the project name.",
|
|
50
|
+
),
|
|
51
|
+
auth: bool = typer.Option(
|
|
52
|
+
False,
|
|
53
|
+
"--auth",
|
|
54
|
+
help="Include JWT + Google OAuth authentication (repository pattern, service layer, "
|
|
55
|
+
"centralized error handling, login/register/me routes).",
|
|
56
|
+
),
|
|
57
|
+
db: str = typer.Option(
|
|
58
|
+
"sqlite",
|
|
59
|
+
"--db",
|
|
60
|
+
help="Database backend: sqlite (default, zero setup), postgres, or mysql "
|
|
61
|
+
"(both include Alembic migrations instead of auto-created tables).",
|
|
62
|
+
),
|
|
63
|
+
):
|
|
64
|
+
"""
|
|
65
|
+
Generate a new FastAPI + SQLAlchemy + SQLite backend project.
|
|
66
|
+
"""
|
|
67
|
+
db = db.lower()
|
|
68
|
+
if db not in VALID_DBS:
|
|
69
|
+
typer.secho(f"--db must be one of {VALID_DBS}, got '{db}'.", fg=typer.colors.RED)
|
|
70
|
+
raise typer.Exit(code=1)
|
|
71
|
+
|
|
72
|
+
project_slug = slugify(directory or project_name)
|
|
73
|
+
target_dir = Path.cwd() / project_slug
|
|
74
|
+
|
|
75
|
+
if target_dir.exists() and any(target_dir.iterdir()):
|
|
76
|
+
typer.secho(f"'{project_slug}' already exists and is not empty. Aborting.", fg=typer.colors.RED)
|
|
77
|
+
raise typer.Exit(code=1)
|
|
78
|
+
|
|
79
|
+
context = {"project_name": project_name, "project_slug": project_slug, "auth": auth, "db": db}
|
|
80
|
+
|
|
81
|
+
render_template(TEMPLATES_ROOT / "fastapi_sqlite", target_dir, context)
|
|
82
|
+
if auth:
|
|
83
|
+
render_template(TEMPLATES_ROOT / "fastapi_sqlite_auth", target_dir, context)
|
|
84
|
+
if db in ("postgres", "mysql"):
|
|
85
|
+
render_template(TEMPLATES_ROOT / "db_migrations", target_dir, context)
|
|
86
|
+
|
|
87
|
+
typer.secho(f"\n✅ Created '{project_name}' in ./{project_slug}\n", fg=typer.colors.GREEN, bold=True)
|
|
88
|
+
typer.echo("Next steps:")
|
|
89
|
+
typer.echo(f" cd {project_slug}")
|
|
90
|
+
typer.echo(" pip install -r requirements.txt # or: uv pip install -r requirements.txt")
|
|
91
|
+
typer.echo(" cp .env.example .env")
|
|
92
|
+
if db in ("postgres", "mysql"):
|
|
93
|
+
typer.echo(f" # edit .env with your real {db} credentials, then:")
|
|
94
|
+
typer.echo(' alembic revision --autogenerate -m "initial tables"')
|
|
95
|
+
typer.echo(" alembic upgrade head")
|
|
96
|
+
if auth:
|
|
97
|
+
typer.echo(" # (optional) set GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET in .env for Google login")
|
|
98
|
+
typer.echo(" uvicorn app.main:app --reload")
|
|
99
|
+
if auth:
|
|
100
|
+
typer.echo("\nAuth endpoints: POST /api/v1/auth/register, POST /api/v1/auth/login, "
|
|
101
|
+
"GET /api/v1/auth/me, GET /api/v1/auth/google/login")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@app.command()
|
|
105
|
+
def version():
|
|
106
|
+
"""Print the fastapi-scaffolder version."""
|
|
107
|
+
from fastapi_scaffolder import __version__
|
|
108
|
+
|
|
109
|
+
typer.echo(__version__)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def main():
|
|
113
|
+
app()
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
if __name__ == "__main__":
|
|
117
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Generic single-database configuration.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from logging.config import fileConfig
|
|
2
|
+
|
|
3
|
+
from sqlalchemy import engine_from_config
|
|
4
|
+
from sqlalchemy import pool
|
|
5
|
+
|
|
6
|
+
from alembic import context
|
|
7
|
+
|
|
8
|
+
# Pull the connection URL and model metadata from the app itself,
|
|
9
|
+
# so alembic.ini never needs a hardcoded/duplicated DATABASE_URL.
|
|
10
|
+
from app.core.config import settings
|
|
11
|
+
from app.db.base import Base # noqa: F401 (imports every model)
|
|
12
|
+
|
|
13
|
+
config = context.config
|
|
14
|
+
config.set_main_option("sqlalchemy.url", settings.DATABASE_URL)
|
|
15
|
+
|
|
16
|
+
if config.config_file_name is not None:
|
|
17
|
+
fileConfig(config.config_file_name)
|
|
18
|
+
|
|
19
|
+
target_metadata = Base.metadata
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def run_migrations_offline() -> None:
|
|
23
|
+
url = config.get_main_option("sqlalchemy.url")
|
|
24
|
+
context.configure(
|
|
25
|
+
url=url,
|
|
26
|
+
target_metadata=target_metadata,
|
|
27
|
+
literal_binds=True,
|
|
28
|
+
dialect_opts={"paramstyle": "named"},
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
with context.begin_transaction():
|
|
32
|
+
context.run_migrations()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def run_migrations_online() -> None:
|
|
36
|
+
connectable = engine_from_config(
|
|
37
|
+
config.get_section(config.config_ini_section, {}),
|
|
38
|
+
prefix="sqlalchemy.",
|
|
39
|
+
poolclass=pool.NullPool,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
with connectable.connect() as connection:
|
|
43
|
+
context.configure(connection=connection, target_metadata=target_metadata)
|
|
44
|
+
|
|
45
|
+
with context.begin_transaction():
|
|
46
|
+
context.run_migrations()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if context.is_offline_mode():
|
|
50
|
+
run_migrations_offline()
|
|
51
|
+
else:
|
|
52
|
+
run_migrations_online()
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""${message}
|
|
2
|
+
|
|
3
|
+
Revision ID: ${up_revision}
|
|
4
|
+
Revises: ${down_revision | comma,n}
|
|
5
|
+
Create Date: ${create_date}
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
from typing import Sequence, Union
|
|
9
|
+
|
|
10
|
+
from alembic import op
|
|
11
|
+
import sqlalchemy as sa
|
|
12
|
+
${imports if imports else ""}
|
|
13
|
+
|
|
14
|
+
# revision identifiers, used by Alembic.
|
|
15
|
+
revision: str = ${repr(up_revision)}
|
|
16
|
+
down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)}
|
|
17
|
+
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
|
|
18
|
+
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def upgrade() -> None:
|
|
22
|
+
"""Upgrade schema."""
|
|
23
|
+
${upgrades if upgrades else "pass"}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def downgrade() -> None:
|
|
27
|
+
"""Downgrade schema."""
|
|
28
|
+
${downgrades if downgrades else "pass"}
|
|
File without changes
|