You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+85-85Lines changed: 85 additions & 85 deletions
Original file line number
Diff line number
Diff line change
@@ -64,7 +64,7 @@ cd your_project_name
64
64
poetry install
65
65
```
66
66
67
-
Note, be sure to use `python3.12` with this template with either poetry or standard venv & pip, if you need to stick to some earlier python version, you should adapt it yourself (remove new versions specific syntax for example `str | int` for python < 3.10 or `tomllib` for python < 3.11)
67
+
Note, be sure to use `python3.12` with this template with either poetry or standard venv & pip, if you need to stick to some earlier python version, you should adapt it yourself (remove new versions specific syntax for example `str | int` for python < 3.10)
68
68
69
69
### 3. Setup database and migrations
70
70
@@ -84,11 +84,11 @@ uvicorn app.main:app --reload
84
84
85
85
```
86
86
87
-
You should then use `git init` to initialize git repository and access OpenAPI spec at http://localhost:8000/ by default. To customize docs url, cors and allowed hosts settings, read section about it.
87
+
You should then use `git init`(if needed) to initialize git repository and access OpenAPI spec at http://localhost:8000/ by default. To customize docs url, cors and allowed hosts settings, read [section about it](#docs-url-cors-and-allowed-hosts).
88
88
89
89
### 5. Activate pre-commit
90
90
91
-
[pre-commit](https://pre-commit.com/) is de facto standard now for pre push activities like isort or black or its replacement ruff.
91
+
[pre-commit](https://pre-commit.com/) is de facto standard now for pre push activities like isort or black or its nowadays replacement ruff.
92
92
93
93
Refer to `.pre-commit-config.yaml` file to see my current opinionated choices.
94
94
@@ -119,6 +119,14 @@ This project is heavily based on the official template https://github.com/tiango
119
119
120
120
`2.0` style SQLAlchemy API is good enough so there is no need to write everything in `crud` and waste our time... The `core` folder was also rewritten. There is great base for writting tests in `tests`, but I didn't want to write hundreds of them, I noticed that usually after changes in the structure of the project, auto tests are useless and you have to write them from scratch anyway (delete old ones...), hence less than more. Similarly with the `User` model, it is very modest, with just `id` (uuid), `email` and `password_hash`, because it will be adapted to the project anyway.
121
121
122
+
2024 update:
123
+
124
+
The template was adpoted to my current style and knowledge, the test based expanded to cover more, added mypy, ruff and test setup was completly rewritten to have three things:
125
+
126
+
- run test in paraller in many processes for speed
127
+
- transactions rollback after every test
128
+
- create test databases instead of having another in docker-compose.yml
129
+
122
130
<br>
123
131
124
132
## Step by step example - POST and GET endpoints
@@ -132,48 +140,25 @@ I always enjoy to have some kind of an example in templates (even if I don't lik
132
140
133
141
### 1. Create SQLAlchemy model
134
142
135
-
We will add Pet model to `app/models.py`. To keep things clear, below is full result of models.py file.
143
+
We will add `Pet` model to `app/models.py`.
136
144
137
145
```python
138
146
# app/models.py
139
147
140
-
import uuid
141
-
142
-
from sqlalchemy import ForeignKey, Integer, String
143
-
from sqlalchemy.dialects.postgresql importUUID
144
-
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
Note, we are using super powerful SQLAlchemy feature here - Mapped and mapped_column were first introduced in SQLAlchemy 2.0 on Feb 26, if this syntax is new for you, read carefully "what's new" part of documentation https://docs.sqlalchemy.org/en/20/changelog/whatsnew_20.html.
161
+
Note, we are using super powerful SQLAlchemy feature here - Mapped and mapped_column were first introduced in SQLAlchemy 2.0, if this syntax is new for you, read carefully "what's new" part of documentation https://docs.sqlalchemy.org/en/20/changelog/whatsnew_20.html.
177
162
178
163
<br>
179
164
@@ -199,15 +184,13 @@ alembic upgrade head
199
184
# INFO [alembic.runtime.migration] Running upgrade d1252175c146 -> 44b7b689ea5f, create_pet_model
200
185
```
201
186
202
-
PS. Note, alembic is configured in a way that it work with async setup and also detects specific column changes.
187
+
PS. Note, alembic is configured in a way that it work with async setup and also detects specific column changes if using `--autogenerate` flag.
203
188
204
189
<br>
205
190
206
191
### 3. Create request and response schemas
207
192
208
-
I personally lately (after seeing clear benefits at work in Samsung) prefer less files than a lot of them for things like schemas.
209
-
210
-
Thats why there are only 2 files: `requests.py` and `responses.py` in `schemas` folder and I would keep it that way even for few dozen of endpoints. Not to mention this is opinionated.
193
+
There are only 2 files: `requests.py` and `responses.py` in `schemas` folder and I would keep it that way even for few dozen of endpoints. Not to mention this is opinionated.
211
194
212
195
```python
213
196
# app/schemas/requests.py
@@ -238,9 +221,9 @@ class PetResponse(BaseResponse):
238
221
### 4. Create endpoints
239
222
240
223
```python
241
-
#/app/api/endpoints/pets.py
224
+
# app/api/endpoints/pets.py
242
225
243
-
from fastapi import APIRouter, Depends
226
+
from fastapi import APIRouter, Depends, status
244
227
from sqlalchemy import select
245
228
from sqlalchemy.ext.asyncio import AsyncSession
246
229
@@ -252,46 +235,54 @@ from app.schemas.responses import PetResponse
Docs page is simpy `/` (by default in FastAPI it is `/docs`). Title, version and description are taken directly from `config` and then directly from `pyproject.toml` file. You can change it completely for the project, remove or use environment variables `PROJECT_NAME`, `VERSION`, `DESCRIPTION`.
381
+
Docs page is simpy `/` (by default in FastAPI it is`/docs`). You can change it completely for the project, just as title, version, etc.
382
382
383
383
2. CORS
384
384
385
-
```python
386
-
app.add_middleware(
387
-
CORSMiddleware,
388
-
allow_origins=[str(origin) for origin in config.settings.BACKEND_CORS_ORIGINS],
389
-
allow_credentials=True,
390
-
allow_methods=["*"],
391
-
allow_headers=["*"],
392
-
)
393
-
```
385
+
```python
386
+
app.add_middleware(
387
+
CORSMiddleware,
388
+
allow_origins=[str(origin) for origin in config.settings.BACKEND_CORS_ORIGINS],
389
+
allow_credentials=True,
390
+
allow_methods=["*"],
391
+
allow_headers=["*"],
392
+
)
393
+
```
394
394
395
395
If you are not sure what are CORSfor, follow https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS. React and most frontend frameworks nowadays operate on `http://localhost:3000` thats why it's included in `BACKEND_CORS_ORIGINS` in .env file, before going production be sure to include your frontend domain here, like `https://my-fontend-app.example.com`.
0 commit comments