ΠΠ°Π½Π½ΡΠΉ ΠΏΡΠΎΠ΅ΠΊΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅Π»Π΅Π³ΡΠ°ΠΌ-Π±ΠΎΡΠΎΠΌ Π΄Π»Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΡ ΡΠ°ΡΠΎΠ². ΠΠΎΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ Π½Π° ΡΡΠ΅ΠΊΠ΅:
- python version 3.11.0
- SQLAlchemy Π΄Π»Ρ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡ Ρ ΠΠ
- Alembic Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΌΠΈΠ³ΡΠ°ΡΠΈΠΉ Π² ΠΠ
- FastAPI ΠΊΠ°ΠΊ Π²Π΅Π±-ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ
- Pydantic ΠΊΠ°ΠΊ ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΎΡ ΠΈ Π²Π°Π»ΠΈΠ΄Π°ΡΠΎΡ Π΄Π°Π½Π½ΡΡ
- Opensensus ΠΊΠ°ΠΊ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π΄Π»Ρ ΡΠ΅Π»Π΅ΠΌΠ΅ΡΡΠΈΠΈ ΠΈ ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΠΈ
- ΠΏΠ°ΠΊΠ΅Ρ
main
- Π¦Π΅Π½ΡΡΠ°Π»ΡΠ½ΡΠΉ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΉ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ, ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π²Π΅Π±-ΡΡΠ°ΠΉΠΌΠ²ΠΎΡΠΊΠ°, celery- ΠΏΠ°ΠΊΠ΅Ρ
settings
- Π‘ΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.- ΠΌΠΎΠ΄ΡΠ»Ρ init.py - Π’ΠΎΡΠΊΠ° Π²Ρ ΠΎΠ΄Π° Π² Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ
- ΠΌΠΎΠ΄ΡΠ»Ρ default.py - ΠΠΎΠ΄ΡΠ»Ρ, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉ ΠΎΡΠ½ΠΎΠ²Π½ΡΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
database
ΠΠ°ΠΊΠ΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡ Π΄Π»Ρ ΡΠΏΡΠΎΡΠ΅Π½ΠΈΡ ΠΈ ΡΠ»ΡΡΡΠ΅Π½ΠΈΡ ΡΠ°Π±ΠΎΡΡ Ρ ORM- ΠΌΠΎΠ΄ΡΠ»Ρ webserver.py - Π¦Π΅Π½ΡΡΠ°Π»ΡΠ½Π°Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ FastApi ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
- ΠΏΠ°ΠΊΠ΅Ρ
- ΠΏΠ°ΠΊΠ΅Ρ tests - Π’Π΅ΡΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
- ΠΏΠ°ΠΊΠ΅Ρ
alembic
- ΡΡΠΎ ΡΠ΅Π½ΡΡΠ°Π»ΡΠ½ΡΠΉ ΠΏΠ°ΠΊΠ΅Ρ Π΄Π»Ρ ΠΎΡΡΡΠ΅ΡΡΠ²Π»Π΅Π½ΠΈΡ Π°Π²ΡΠΎΠ³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ ΠΌΠΈΠ³ΡΠ°ΡΠΈΠΉ/ΠΌΠΈΠ³ΡΠ°ΡΠΈΠΉ/ΠΎΡΠΊΠ°ΡΠ° ΠΌΠΈΠ³ΡΠ°ΡΠΈΠΉ Π² ΠΠ. ΠΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΈΡΠ°ΡΡ Π·Π΄Π΅ΡΡ ΠΏΡΠΎ Π΄Π°Π½Π½ΡΠΉ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ- ΠΏΠ°ΠΊΠ΅Ρ
versions
- ΠΏΠ°ΠΊΠ΅Ρ Ρ ΠΌΠΈΠ³ΡΠ°ΡΠΈΡΠΌΠΈ ΡΠ°ΠΉΠ»ΠΎΠ² - ΠΌΠΎΠ΄ΡΠ»Ρ env.py - ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΡΠΉ ΠΌΠΎΠ΄ΡΠ»Ρ Π΄Π»Ρ ΠΌΠΈΠ³ΡΠ°ΡΠΈΠΉ
- ΠΏΠ°ΠΊΠ΅Ρ
- ΠΏΠ°ΠΊΠ΅Ρ-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
my_app
- ΠΡΠΎ ΠΏΠ°ΠΊΠ΅Ρ-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ. Π‘ΠΎΠ·Π΄Π°Π½Π½Π°Ρ Π΄Π»Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ°. ΠΠ΄Π΅ΡΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²ΡΠ²Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΠΌΠ°ΡΡΡΡΡΡ ΠΈ Π±ΠΈΠ·Π½Π΅Ρ-Π»ΠΎΠ³ΠΈΠΊΡ Ρ ΡΡΡΠ½ΠΎΡΡΡΠΌΠΈ Π±ΠΈΠ·Π½Π΅Ρ-Π»ΠΎΠ³ΠΈΠΊΠΈ.- ΠΏΠ°ΠΊΠ΅Ρ
models
- ΠΏΠ°ΠΊΠ΅Ρ Ρ ΠΌΠΎΠ΄ΡΠ»ΡΠΌΠΈ-ΠΊΠ»Π°ΡΡΠ°ΠΌΠΈ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ ΠΠ - ΠΏΠ°ΠΊΠ΅Ρ
routes
- ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΌΠ°ΡΡΡΡΡΡ Π΄Π»Ρ api ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ Π±ΠΈΠ·Π½Π΅Ρ-Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ - ΠΏΠ°ΠΊΠ΅Ρ
schemas
- ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΡ Π΅ΠΌΡ ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ/Π΄Π΅ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π±ΠΈΠ·Π½Π΅Ρ-ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ Pydantic
- ΠΏΠ°ΠΊΠ΅Ρ
- ΠΏΠ°ΠΊΠ΅Ρ-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
auth
- ΠΠ°ΠΊΠ΅Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΠΌΠΈ, Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΎΠ½Π½ΡΠΌΠΈ ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌΠΈ, ΡΠΏΠΎΡΠΎΠ±Π°ΠΌΠΈ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ, ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΠΎΠΊΠ΅Π½ΠΎΠ² OAuth2 by JWT utils
- ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ ΠΏΠ°ΠΊΠ΅Ρ Ρ ΠΏΡΠΈΠΊΠ»Π°Π΄Π½ΡΠΌΠΈ ΡΡΠΈΠ»ΠΈΡΠ°ΠΌΠΈ- ΠΌΠΎΠ΄ΡΠ»Ρ base_client.py ΡΠ²Π»ΡΠ΅ΡΡΡ Π°Π±ΡΡΡΠ°ΠΊΡΠ½ΡΠΌ ΠΊΠ»Π°ΡΡΠΎΠΌ-ΡΠΎΠ΄ΠΈΡΠ΅Π»Π΅ΠΉ Π΄Π»Ρ Π²ΡΠ΅Ρ http-ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠ² (Π‘ΠΊΠΎΡΠΎ Π±ΡΠ΄Π΅Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½. Π ΠΏΡΠΎΡΠ΅ΡΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΠΎ ΠΏΠ°ΡΡΠ΅ΡΠ½Ρ Π€Π°Π±ΡΠΈΠΊΠ°)
- ΠΌΠΎΠ΄ΡΠ»Ρ custom_json_logger.py ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΊΠ»Π°ΡΡΡ-ΡΠΎΡΠΌΠ°ΡΡΠ΅ΡΡ Π»ΠΎΠ³ΠΎΠ² Π΄Π»Ρ ΡΠ΅Π½ΡΡΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π»ΠΎΠ³ΠΎΠ² Π² json ΡΠΎΡΠΌΠ°Ρ
- ΠΌΠΎΠ΄ΡΠ»Ρ middlewares.py ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΏΠ΅ΡΠ΅ΡΠ΅Π½Ρ Middleware-ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π΄Π»Ρ Π·Π°ΠΏΡΠΎΡΠΎΠ² ΠΏΠΎ HTTP Π² ΡΠ΅ΡΠ²Π΅Ρ. (ΠΠΎΠ³Π³Π΅Ρ Π·Π°ΠΏΡΠΎΡΠΎΠ², Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ)
- ΠΌΠΎΠ΄ΡΠ»Ρ dependencies.py ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΊΠ»Π°ΡΡΡ ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠ΅ΠΉ Π΄Π»Ρ Π°Π΄ΡΠ΅ΡΠΎΠ² ΡΠ΅ΡΠ²ΠΈΡΠ° (ΠΡΠΈΠΌΠ΅ΡΠΈ ΡΠ΅ΡΡΠΈΠΈ ΠΠ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ)
- ΠΌΠΎΠ΄ΡΠ»Ρ structs.py Π·Π΄Π΅ΡΡ Π±ΡΠ΄ΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡΡΡ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠ½ΡΠ΅ Π΄Π»Ρ ΠΏΡΠΎΠ΅ΠΊΡΠ°(Π½ΠΎ Π½Π΅ Π΄Π»Ρ ΠΏΠ°ΠΊΠ΅ΡΠ° Ρ Π±ΠΈΠ·Π½Π΅Ρ-ΡΡΡΠ½ΠΎΡΡΡΡ) ΡΡΡΡΠΊΡΡΡΡ Π΄Π»Ρ ΡΠ΄ΠΎΠ±ΡΡΠ²Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ
- ΠΌΠΎΠ΄ΡΠ»Ρ server.py Π·Π°ΠΏΡΡΠΊΠ°Π΅Ρ Π½Π°ΡΡΡΠΎΠ΅Π½Π½ΡΠΉ Π²Π΅Π±-ΡΠ΅ΡΠ²Π΅Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
- ΠΏΠ°ΠΏΠΊΠ°
requirements
- ΠΏΠ°ΠΏΠΊΠ° Ρ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΡΠΌΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠ° - ΡΠ°ΠΉΠ» tox.ini - ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π΄Π»Ρ codestyle ΠΏΡΠΎΠ΅ΠΊΡΠ°
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° Π²ΠΎΡΠΊΠ΅ΡΠΎΠ² FastAPI, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ Π·Π°ΠΏΡΡΠ΅Π½Ρ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠ΅:
import os
WORKERS_COUNT = int(os.getenv('WORKERS_COUNT', 1))
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΠΠ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
import os
DATABASE_SETTINGS = {
'default': {
'database': os.getenv('DB_NAME', 'bread_bot'),
'user': os.getenv('DB_USER', 'bread_bot'),
'password': os.getenv('DB_PASSWORD', 'bread_bot'),
'host': os.getenv('DB_HOST', '127.0.0.1'),
'port': os.getenv('DB_PORT', '5432'),
}
}
SQLAlchemy ΡΠ°ΠΌΠ° ΠΎΡΠ³Π°Π½ΠΈΠ·ΡΠ΅Ρ, ΠΊΠ°ΠΊΠΈΠΌ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎΠΌ ΠΏΡΠ»ΠΎΠ² ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ ΠΎΠΏΠ΅ΡΠΈΡΠΎΠ²Π°ΡΡ. ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π·Π°Π΄Π°Π²Π°ΡΡ Π½Π°ΡΡΡΠΎΠΉΠΊΡ, ΠΊΠ°ΠΊΠΎΠΉ ΠΌΠ°ΠΊΡΠΈΠΌΡΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΠΏΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡΠΌ:
import os
DB_MAX_POOL = int(os.getenv('DB_MAX_POOL', 20))
ΠΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅: ΠΡΠΎ ΠΎΠ±ΡΠ΅Π΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π²ΠΎΡΠΊΠ΅ΡΠΎΠ² Π½Π° Π²ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Π½Π° Π²ΡΠ΅ Π²ΠΎΡΠΊΠ΅ΡΡ. Π’ΠΎ Π΅ΡΡΡ, ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡ Π²ΠΎΡΠΊΠ΅ΡΡ Π±ΡΠ΄Π΅Ρ Π²ΡΠ΄Π΅Π»Π΅Π½Π° ΡΠ°ΡΡΡ ΡΠ΅ΡΡΠΈΠΉ, Π° Π½Π΅ Π²ΡΠ΅ ΠΎΠ±ΡΠ΅Π΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ. ΠΠ½Π°ΡΠ΅ Π³ΠΎΠ²ΠΎΡΡ Π² ΠΊΠΎΠ΄Π΅ Π½ΠΈΠΆΠ΅ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡ ΠΈΠ· 10ΡΠΈ Π²ΠΎΡΠΊΠ΅ΡΠΎΠ² Π±ΡΠ΄Π΅Ρ ΠΏΡΠ΅Π΄ΡΡΠ²Π»Π΅Π½ΠΎ ΠΏΠΎ 5 ΡΠ°Π±ΠΎΡΠΈΡ ΡΠ΅ΡΡΠΈΠΉ ΠΠ:
import math
WORKERS_COUNT = 10
DB_MAX_POOL = 50
DB_POOL_SIZE = max(math.ceil(DB_MAX_POOL / WORKERS_COUNT), 1)
Π’Π°ΠΊΠΆΠ΅, Π΅ΡΠ»ΠΈ Π΅ΡΡΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡ, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π½ΠΈΠΌΠ°ΡΡΡΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΠ΅ΡΡΠΈΠΉ Ρ ΠΏΠΎΠΌΠΎΡΡΡ pgbouncer. Π€Π°ΠΉΠ» Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ pgbouncer: pgbouncer.ini
ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ Π²ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π² ΠΏΡΠΎΠ΅ΠΊΡΠ΅ (ΠΊΠ°ΠΊ Π² django)
APP_MODULES = [
'my_app',
'auth',
]
FastAPI ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π²Π΅Π±-ΡΠ΅ΡΠ²Π΅ΡΠ° uvicorn. ΠΡΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ² Π·Π°ΠΏΡΡΠΊΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ:
uvicorn bread_bot.main.webserver:app
python server.py
ΠΠ΅ ΡΠ΅ΠΊΡΠ΅Ρ, ΡΡΠΎ fastapi ΡΠΌΠ΅Π΅Ρ Π°Π²ΡΠΎΠ΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°ΡΡ Π² swagger, redoc, openapi.json Π²ΡΠ΅ ΠΌΠ°ΡΡΡΡΡΡ ΠΈ ΡΠΎΡΠΊΠΈ Π²Ρ ΠΎΠ΄Π°. ΠΠΎΡΡΠΎΠΌΡ ΠΌΠΎΠΉ ΡΠΎΠ²Π΅Ρ ΠΊΠ°ΠΊ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΡΡΠ°ΡΠ΅Π»ΡΠ½ΠΎ ΠΎΠΏΠΈΡΡΠ²Π°ΡΡ ΡΡ Π΅ΠΌΡ Pydantic Π΄Π»Ρ ΡΠ΄ΠΎΠ±ΡΡΠ²Π° ΠΈ ΡΠΈΡΠ°Π±Π΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠ°. ΠΠ΅Π»Π°ΡΠ΅Π»ΡΠ½ΠΎ Ρ ΠΊΠ΅ΠΉΡΠ°ΠΌΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ. ΠΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ Π² ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΠ°.
Π Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ CRUDMixin Π΄Π»Ρ ΠΎΠΏΠ΅ΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΎΡΡΡΠΌΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌΠΈ ΠΊΠ°ΠΊ get, filter, first, create, update, ΠΈΡΠ΄ ΠΈΡΠΏ. Π’Π°ΠΊΠΆΠ΅ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΡΠ΅ Π°Π½Π°Π»ΠΎΠ³ΠΈ Π΄Π°Π½Π½ΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ². Π Π°ΡΡΠΈΡΡΡΡ Π΄Π°Π½Π½ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΡΡΠΈ
Π‘Π°ΠΌΠ°Ρ Π³Π»Π°Π²Π½Π°Ρ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΡ - ΡΡΠΎ poetry
pip install poetry
ΠΠ°Π»Π΅Π΅ ΠΎΠΏΠ΅ΡΠΈΡΡΠ΅ΡΡΡ Π²ΡΡ ΡΠ°Π±ΠΎΡΠ° Ρ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΡΠΌΠΈ ΡΠ΅ΡΠ΅Π· Π½Π΅Π³ΠΎ:
poetry add requests
poetry add pytest --dev
poetry install
poetry install --only main
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° Π²Π΅Π·Π΄Π΅, Π³Π΄Π΅ ΠΡ Π²ΠΈΠ΄ΠΈΡΠ΅ ΡΠ»ΠΎΠ²ΠΎ bread_bot
- ΡΡΡ ΠΌΠΎΠΆΠ΅Ρ ΠΎΠΊΠ°Π·Π°ΡΡΡΡ Π½Π°ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Π°ΡΠ΅Π³ΠΎ ΠΌΠΈΠΊΡΠΎΡΠ΅ΡΠ²ΠΈΡΠ°. ΠΡ Π»ΠΎΠ³ΠΈΡΠ½ΠΎ,
Π΄Π°?
ΠΠ΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π²ΡΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ Π² ΠΏΡΠΎΠ΅ΠΊΡΠ΅:
pip install poetry && poetry install
ΠΡΠ΅Π΄ΡΡΠ°Π²ΡΡΠ΅ Π½Π° ΡΠ΅ΠΊΡΠ½Π΄Ρ, ΡΡΠΎ Π²Ρ ΡΠΆΠ΅ ΠΏΠΎΡΡΠ°Π²ΠΈΠ»ΠΈ PostgreSQL. Π ΡΠ΅ΠΏΠ΅ΡΡ Π½ΡΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΠΠ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΌ ΠΈ ΠΏΠ°ΡΠΎΠ»Π΅ΠΌ:
CREATE DATABASE bread_bot;
CREATE ROLE bread_bot with LOGIN PASSWORD 'my_password';
GRANT ALL PRIVILEGES ON DATABASE bread_bot TO bread_bot;
ΠΠΈΠ³ΡΠ°ΡΠΈΡ ΡΡ Π΅ΠΌΡ Π±Π°Π· Π΄Π°Π½Π½ΡΡ
alembic upgrade head
ΠΡΠΊΠ°Ρ ΠΌΠΈΠ³ΡΠ°ΡΠΈΠΈ Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ
alembic downgrade -1
ΠΠ²ΡΠΎ-Π³Π΅Π½Π΅ΡΠ°ΡΠΈΡ ΡΡ Π΅ΠΌΡ Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ
alembic revision --autogenerate -m 'my migration message'
ΠΠ°ΠΏΡΡΠΊΠ°Π΅ΠΌ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ Π²Π΅Π±-ΡΠ΅ΡΠ²Π΅Ρ
uvicorn bread_bot.main.webserver:app --reload
ΠΈΠ»ΠΈ ΡΠ°ΠΊ:
python server.py
ΠΠ°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ codestyle ΠΏΡΠΎΠ΅ΠΊΡΠ° (Π ΡΡΠ° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π±ΡΠ΄Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΈ ΠΏΡΠΈ CI)
flake8
ΠΠ°ΠΏΡΡΡΠΈΡΡ ΡΠ΅ΡΡΡ:
pytest bread_bot/tests
ΠΠ°ΠΏΡΡΡΠΈΡΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π΄Π°Π½Π½ΡΡ ΠΏΠΎ ΠΏΠΎΠΊΡΡΡΠΈΡ ΡΠ΅ΡΡΠ°ΠΌΠΈ
coverage run -m pytest bread_bot/tests
ΠΠ°ΠΏΡΡΡΠΈΡΡ Π²ΡΠ²ΠΎΠ΄ ΠΎΡΡΠ΅ΡΠ° ΠΏΠΎ ΠΏΠΎΠΊΡΡΡΠΈΡ ΡΠ΅ΡΡΠ°ΠΌΠΈ
coverage report -m
ΠΠ°ΠΏΡΡΡΠΈΡΡ Π²ΡΠ²ΠΎΠ΄ ΠΎΡΡΠ΅ΡΠ° Π² html ΡΠΎΡΠΌΠ°ΡΠ΅
coverage html
Π£Π΄Π°Π»ΠΈΡΡ Π΄Π°Π½Π½ΡΠ΅ ΠΎΡΡΠ΅ΡΠ°
coverage erase
ΠΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ:
coverage erase && coverage run pytest bread_bot/tests && coverage html
Π€ΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΡ Π±ΠΎΡΠ° ΠΎΠΏΠΈΡΠ°Π½Π° Π² About.md