hinbert-fastapi 0.2.0__tar.gz → 0.2.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.
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/PKG-INFO +336 -322
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/README.md +16 -2
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/deps/auth.py +1 -1
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/middleware/__init__.py +2 -2
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/hinbert_cli/main.py +70 -101
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/hinbert_fastapi.egg-info/PKG-INFO +336 -322
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/pyproject.toml +1 -1
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/setup.cfg +4 -4
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/LICENSE +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/deps/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/deps/pagination.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/v1/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/v1/endpoints/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/v1/endpoints/auth.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/v1/endpoints/dashboard.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/v1/endpoints/products.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/v1/endpoints/users.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/v1/routers/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/api/v1/routers/api_router.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/config/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/config/database.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/config/settings.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/exceptions/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/exceptions/base_exception.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/exceptions/custom_exceptions.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/middleware/cors.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/middleware/error_handler.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/middleware/logging.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/middleware/rate_limit.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/security/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/security/auth.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/security/jwt.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/security/oauth.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/security/password.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/core/security/totp.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/db/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/db/base.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/db/migrations/env.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/db/migrations/versions/97ed1bc05f4a_complete_product_and_totp_fields.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/db/migrations/versions/f8b632aa11da_initial_migration.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/db/session.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/main.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/domain/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/domain/base.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/domain/email_verification.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/domain/password_reset.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/domain/product.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/domain/refresh_token.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/domain/totp_secret.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/domain/user.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/schemas/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/schemas/auth.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/schemas/password.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/schemas/product.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/schemas/response.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/schemas/token.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/schemas/totp.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/models/schemas/user.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/repositories/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/repositories/base/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/repositories/base/base_repository.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/repositories/email_verification_repository.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/repositories/password_reset_repository.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/repositories/product_repository.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/repositories/refresh_token_repository.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/repositories/totp_secret_repository.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/repositories/user_repository.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/services/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/services/auth_service.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/services/base/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/services/base/base_service.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/services/email_service.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/services/product_service.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/services/social_auth_service.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/services/totp_service.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/services/user_service.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/tests/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/tests/conftest.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/tests/integration/test_auth_api.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/tests/integration/test_product_api.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/tests/integration/test_user_api.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/tests/unit/test_auth_service.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/tests/unit/test_product_service.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/tests/unit/test_user_service.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/utils/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/utils/date_utils.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/utils/file_utils.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/utils/logger.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/app/utils/validators.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/hinbert_cli/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/hinbert_fastapi.egg-info/SOURCES.txt +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/hinbert_fastapi.egg-info/dependency_links.txt +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/hinbert_fastapi.egg-info/entry_points.txt +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/hinbert_fastapi.egg-info/requires.txt +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/hinbert_fastapi.egg-info/top_level.txt +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/scripts/__init__.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/scripts/create_admin.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/scripts/run_migrations.py +0 -0
- {hinbert_fastapi-0.2.0 → hinbert_fastapi-0.2.1}/scripts/seed_data.py +0 -0
|
@@ -1,322 +1,336 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: hinbert-fastapi
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary: Professional FastAPI boilerplate with JWT auth, 2FA, PostgreSQL, Docker
|
|
5
|
-
Author: Hinbert Engineering
|
|
6
|
-
License: MIT
|
|
7
|
-
Project-URL: Documentation, https://github.com/hinbert/hinbert-fastapi#readme
|
|
8
|
-
Project-URL: Repository, https://github.com/hinbert/hinbert-fastapi
|
|
9
|
-
Classifier: Development Status :: 3 - Alpha
|
|
10
|
-
Classifier: Framework :: FastAPI
|
|
11
|
-
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
-
Requires-Python: >=3.10
|
|
15
|
-
Description-Content-Type: text/markdown
|
|
16
|
-
License-File: LICENSE
|
|
17
|
-
Requires-Dist: fastapi<1,>=0.115
|
|
18
|
-
Requires-Dist: uvicorn[standard]<1,>=0.30
|
|
19
|
-
Requires-Dist: sqlalchemy[asyncio]<3,>=2.0
|
|
20
|
-
Requires-Dist: asyncpg<1,>=0.29
|
|
21
|
-
Requires-Dist: aiosqlite<1,>=0.20
|
|
22
|
-
Requires-Dist: alembic<2,>=1.13
|
|
23
|
-
Requires-Dist: pydantic<3,>=2.8
|
|
24
|
-
Requires-Dist: pydantic-settings<3,>=2.4
|
|
25
|
-
Requires-Dist: python-jose[cryptography]<4,>=3.3
|
|
26
|
-
Requires-Dist: passlib[bcrypt]<2,>=1.7
|
|
27
|
-
Requires-Dist: bcrypt<5,>=4.0
|
|
28
|
-
Requires-Dist: pyotp<3,>=2.9
|
|
29
|
-
Requires-Dist: slowapi<1,>=0.1.9
|
|
30
|
-
Requires-Dist: loguru<1,>=0.7
|
|
31
|
-
Requires-Dist: email-validator<3,>=2.2
|
|
32
|
-
Requires-Dist: python-multipart<1,>=0.0.9
|
|
33
|
-
Requires-Dist: redis<6,>=5
|
|
34
|
-
Requires-Dist: aiosmtplib<4,>=3
|
|
35
|
-
Requires-Dist: cryptography<46,>=42
|
|
36
|
-
Requires-Dist: httpx<1,>=0.27
|
|
37
|
-
Dynamic: license-file
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Hinbert FastAPI
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
│
|
|
115
|
-
|
|
116
|
-
│
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
│
|
|
120
|
-
├──
|
|
121
|
-
├──
|
|
122
|
-
|
|
123
|
-
├──
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
├──
|
|
129
|
-
├──
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
├──
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
```bash
|
|
201
|
-
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
- `/api/v1/auth/
|
|
246
|
-
- `/api/v1/auth/
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
- `/api/v1/
|
|
251
|
-
- `/api/v1/
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
The
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
- `
|
|
286
|
-
- `
|
|
287
|
-
- `
|
|
288
|
-
- `
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hinbert-fastapi
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Professional FastAPI boilerplate with JWT auth, 2FA, PostgreSQL, Docker
|
|
5
|
+
Author: Hinbert Engineering
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Documentation, https://github.com/hinbert/hinbert-fastapi#readme
|
|
8
|
+
Project-URL: Repository, https://github.com/hinbert/hinbert-fastapi
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Framework :: FastAPI
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: fastapi<1,>=0.115
|
|
18
|
+
Requires-Dist: uvicorn[standard]<1,>=0.30
|
|
19
|
+
Requires-Dist: sqlalchemy[asyncio]<3,>=2.0
|
|
20
|
+
Requires-Dist: asyncpg<1,>=0.29
|
|
21
|
+
Requires-Dist: aiosqlite<1,>=0.20
|
|
22
|
+
Requires-Dist: alembic<2,>=1.13
|
|
23
|
+
Requires-Dist: pydantic<3,>=2.8
|
|
24
|
+
Requires-Dist: pydantic-settings<3,>=2.4
|
|
25
|
+
Requires-Dist: python-jose[cryptography]<4,>=3.3
|
|
26
|
+
Requires-Dist: passlib[bcrypt]<2,>=1.7
|
|
27
|
+
Requires-Dist: bcrypt<5,>=4.0
|
|
28
|
+
Requires-Dist: pyotp<3,>=2.9
|
|
29
|
+
Requires-Dist: slowapi<1,>=0.1.9
|
|
30
|
+
Requires-Dist: loguru<1,>=0.7
|
|
31
|
+
Requires-Dist: email-validator<3,>=2.2
|
|
32
|
+
Requires-Dist: python-multipart<1,>=0.0.9
|
|
33
|
+
Requires-Dist: redis<6,>=5
|
|
34
|
+
Requires-Dist: aiosmtplib<4,>=3
|
|
35
|
+
Requires-Dist: cryptography<46,>=42
|
|
36
|
+
Requires-Dist: httpx<1,>=0.27
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
[](https://github.com/hinbert-cli-development/hinbert_fastapi/stargazers)
|
|
40
|
+
[](https://github.com/hinbert-cli-development/hinbert_fastapi/forks)
|
|
41
|
+
[](https://github.com/hinbert-cli-development/hinbert_fastapi/issues)
|
|
42
|
+
[](https://github.com/hinbert-cli-development/hinbert_fastapi/pulls)
|
|
43
|
+
[](https://pypi.org/project/hinbert-fastapi/)
|
|
44
|
+
[](LICENSE)
|
|
45
|
+
# Hinbert FastAPI
|
|
46
|
+
|
|
47
|
+
A modern, production-oriented FastAPI backend foundation for secure web applications. Built for teams that want a clean architecture, strong authentication defaults, scalable API design, and quick deployment without starting from scratch.
|
|
48
|
+
|
|
49
|
+
## Why this project?
|
|
50
|
+
|
|
51
|
+
Hinbert FastAPI combines a pragmatic backend structure with security-first design patterns:
|
|
52
|
+
|
|
53
|
+
- JWT-based authentication with refresh token rotation
|
|
54
|
+
- Password reset and email verification flows
|
|
55
|
+
- Optional TOTP multi-factor authentication
|
|
56
|
+
- OAuth login for Google and Facebook
|
|
57
|
+
- Async SQLAlchemy data layer with PostgreSQL support
|
|
58
|
+
- Rate limiting, request logging, and structured error handling
|
|
59
|
+
- Clean separation between API, services, repositories, and models
|
|
60
|
+
- Docker-ready local environment and deployment support
|
|
61
|
+
|
|
62
|
+
## Features
|
|
63
|
+
|
|
64
|
+
- Secure user registration and login
|
|
65
|
+
- Email verification and password recovery
|
|
66
|
+
- Access token + refresh token issuance
|
|
67
|
+
- Logout and refresh-token revocation
|
|
68
|
+
- TOTP setup and validation
|
|
69
|
+
- Social authentication hooks
|
|
70
|
+
- Product CRUD endpoints with filtering, sorting, and pagination
|
|
71
|
+
- Redis-backed rate limiting
|
|
72
|
+
- Pydantic-based validation and environment configuration
|
|
73
|
+
- Alembic migrations for database evolution
|
|
74
|
+
- Python testing coverage for core business flows
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
### Available Commands
|
|
79
|
+
|
|
80
|
+
| Command | Description | Example |
|
|
81
|
+
| --- | --- | --- |
|
|
82
|
+
| `hinbert init [PROJECT_NAME]` | Create a new FastAPI project | `hinbert init my_app` |
|
|
83
|
+
| `hinbert init --help` | Show help and available options | `hinbert init --help` |
|
|
84
|
+
| `hinbert init .` | Generate project in current directory | `hinbert init .` |
|
|
85
|
+
| `hinbert init [PROJECT_NAME] --yes` | Skip prompts, use defaults | `hinbert init my_app --yes` |
|
|
86
|
+
| `--db [postgresql|mysql|sqlite]` | Choose database | `--db postgresql` |
|
|
87
|
+
| `--auth [jwt|oauth2|none]` | Choose authentication | `--auth jwt` |
|
|
88
|
+
| `--no-2fa` | Skip two-factor authentication | `--no-2fa` |
|
|
89
|
+
| `--no-email` | Skip email verification | `--no-email` |
|
|
90
|
+
| `--no-rate-limit` | Skip rate limiting | `--no-rate-limit` |
|
|
91
|
+
| `--no-docker` | Skip Docker configuration | `--no-docker` |
|
|
92
|
+
| `--k8s` | Include Kubernetes/Helm | `--k8s` |
|
|
93
|
+
| `--logging [loguru|structlog|none]` | Choose logging library | `--logging structlog` |
|
|
94
|
+
| `-y, --yes` | Skip all confirmation prompts | `-y` |
|
|
95
|
+
|
|
96
|
+
## Tech Stack
|
|
97
|
+
|
|
98
|
+
- Python 3.12+
|
|
99
|
+
- FastAPI
|
|
100
|
+
- SQLAlchemy 2 with async support
|
|
101
|
+
- PostgreSQL / SQLite compatibility
|
|
102
|
+
- Pydantic v2
|
|
103
|
+
- Redis
|
|
104
|
+
- Alembic
|
|
105
|
+
- JWT + bcrypt + pyotp
|
|
106
|
+
- Docker and Docker Compose
|
|
107
|
+
- pytest
|
|
108
|
+
|
|
109
|
+
## Architecture
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
app/
|
|
113
|
+
├── api/
|
|
114
|
+
│ ├── deps/
|
|
115
|
+
│ └── v1/
|
|
116
|
+
│ ├── endpoints/
|
|
117
|
+
│ └── routers/
|
|
118
|
+
├── core/
|
|
119
|
+
│ ├── config/
|
|
120
|
+
│ ├── exceptions/
|
|
121
|
+
│ ├── middleware/
|
|
122
|
+
│ └── security/
|
|
123
|
+
├── db/
|
|
124
|
+
│ └── migrations/
|
|
125
|
+
├── models/
|
|
126
|
+
│ ├── domain/
|
|
127
|
+
│ └── schemas/
|
|
128
|
+
├── repositories/
|
|
129
|
+
├── services/
|
|
130
|
+
├── tests/
|
|
131
|
+
├── main.py
|
|
132
|
+
├── __init__.py
|
|
133
|
+
|
|
134
|
+
scripts/
|
|
135
|
+
├── create_admin.py
|
|
136
|
+
├── run_migrations.py
|
|
137
|
+
├── seed_data.py
|
|
138
|
+
|
|
139
|
+
docker/
|
|
140
|
+
├── Dockerfile
|
|
141
|
+
├── docker-compose.yml
|
|
142
|
+
|
|
143
|
+
alembic.ini
|
|
144
|
+
pyproject.toml
|
|
145
|
+
requirements.txt
|
|
146
|
+
requirements-dev.txt
|
|
147
|
+
.env.example
|
|
148
|
+
README.md
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Quick Start
|
|
152
|
+
|
|
153
|
+
### Prerequisites
|
|
154
|
+
|
|
155
|
+
- Python 3.12+
|
|
156
|
+
- PostgreSQL or Docker
|
|
157
|
+
- Redis or Docker
|
|
158
|
+
- Git
|
|
159
|
+
|
|
160
|
+
### 1. Clone the repository
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
git clone <repository-url>
|
|
164
|
+
cd hinbert_fastapi
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 2. Create a virtual environment
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
python -m venv .venv
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
On Windows PowerShell:
|
|
174
|
+
|
|
175
|
+
```powershell
|
|
176
|
+
.\.venv\Scripts\Activate.ps1
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
On macOS/Linux:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
source .venv/bin/activate
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 3. Install dependencies
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
pip install -r requirements.txt
|
|
189
|
+
pip install -r requirements-dev.txt
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 4. Configure environment variables
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
copy .env.example .env
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
or:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
cp .env.example .env
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Update the values in `.env` for your database, Redis, JWT secret, SMTP settings, and OAuth credentials.
|
|
205
|
+
|
|
206
|
+
### 5. Run database migrations
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
python -m scripts.run_migrations
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 6. Start the API
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Once running, the app is available at:
|
|
219
|
+
|
|
220
|
+
- API: http://localhost:8000
|
|
221
|
+
- Swagger UI: http://localhost:8000/docs
|
|
222
|
+
- ReDoc: http://localhost:8000/redoc
|
|
223
|
+
- Health: http://localhost:8000/health
|
|
224
|
+
|
|
225
|
+
## Docker Setup
|
|
226
|
+
|
|
227
|
+
This project includes a Docker Compose setup for local development.
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
docker compose -f docker/docker-compose.yml up --build
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
To stop it:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
docker compose -f docker/docker-compose.yml down
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## API Highlights
|
|
240
|
+
|
|
241
|
+
The application exposes a versioned API under `/api/v1`.
|
|
242
|
+
|
|
243
|
+
### Auth endpoints
|
|
244
|
+
|
|
245
|
+
- `/api/v1/auth/signup`
|
|
246
|
+
- `/api/v1/auth/login`
|
|
247
|
+
- `/api/v1/auth/refresh`
|
|
248
|
+
- `/api/v1/auth/logout`
|
|
249
|
+
- `/api/v1/auth/forgot-password`
|
|
250
|
+
- `/api/v1/auth/reset-password`
|
|
251
|
+
- `/api/v1/auth/totp/setup`
|
|
252
|
+
- `/api/v1/auth/totp/verify`
|
|
253
|
+
- `/api/v1/auth/google`
|
|
254
|
+
- `/api/v1/auth/facebook`
|
|
255
|
+
|
|
256
|
+
### Product endpoints
|
|
257
|
+
|
|
258
|
+
- `/api/v1/products`
|
|
259
|
+
- `/api/v1/products/{product_id}`
|
|
260
|
+
|
|
261
|
+
### User endpoints
|
|
262
|
+
|
|
263
|
+
- `/api/v1/users/me`
|
|
264
|
+
- admin/user management routes where applicable
|
|
265
|
+
|
|
266
|
+
## Example Authentication Flow
|
|
267
|
+
|
|
268
|
+
```json
|
|
269
|
+
{
|
|
270
|
+
"email": "user@example.com",
|
|
271
|
+
"password": "StrongPassword!123"
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The login response returns both an access token and refresh token:
|
|
276
|
+
|
|
277
|
+
```http
|
|
278
|
+
Authorization: Bearer <access_token>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Environment Configuration
|
|
282
|
+
|
|
283
|
+
The project reads configuration using Pydantic settings from `.env` and supports values such as:
|
|
284
|
+
|
|
285
|
+
- `DATABASE_URL`
|
|
286
|
+
- `REDIS_URL`
|
|
287
|
+
- `SECRET_KEY`
|
|
288
|
+
- `ALGORITHM`
|
|
289
|
+
- `ACCESS_TOKEN_EXPIRE_MINUTES`
|
|
290
|
+
- `REFRESH_TOKEN_EXPIRE_DAYS`
|
|
291
|
+
- `SMTP_HOST`
|
|
292
|
+
- `SMTP_PORT`
|
|
293
|
+
- `EMAIL_FROM`
|
|
294
|
+
- `GOOGLE_CLIENT_ID`
|
|
295
|
+
- `FACEBOOK_CLIENT_ID`
|
|
296
|
+
- `BACKEND_CORS_ORIGINS`
|
|
297
|
+
|
|
298
|
+
## Testing
|
|
299
|
+
|
|
300
|
+
Run the test suite with:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
pytest
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Targeted test folders:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
pytest app/tests/unit
|
|
310
|
+
pytest app/tests/integration
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Security Notes
|
|
314
|
+
|
|
315
|
+
This project includes strong defaults for a starter backend, but production deployments should still:
|
|
316
|
+
|
|
317
|
+
- replace the default JWT secret with a secure secret manager value
|
|
318
|
+
- restrict CORS origins to trusted domains
|
|
319
|
+
- protect database credentials and infrastructure endpoints
|
|
320
|
+
- use HTTPS behind a reverse proxy or load balancer
|
|
321
|
+
- configure valid SMTP and OAuth provider credentials
|
|
322
|
+
- enable monitoring, backups, and secure deployment policies
|
|
323
|
+
|
|
324
|
+
## Contributing
|
|
325
|
+
|
|
326
|
+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md).
|
|
327
|
+
|
|
328
|
+
## License
|
|
329
|
+
|
|
330
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
331
|
+
|
|
332
|
+
## Support
|
|
333
|
+
|
|
334
|
+
If you find this useful, please give it a ⭐ on GitHub!
|
|
335
|
+
|
|
336
|
+
|