Skip to content

Commit 9453d28

Browse files
authored
Merge pull request #9 from sumaro2101/develop
readme
2 parents 2834255 + 93d43f1 commit 9453d28

7 files changed

Lines changed: 193 additions & 3 deletions

File tree

README.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# Title
2+
Данный шаблон был разработан для одной цели - облегчения и повышения качества
3+
выполненых тестовых заданий в рамках **FastAPI**.
4+
5+
# Quick start
6+
Для тех кто уже знаком с реализацией и всеми деталями - могут приступить к установке.
7+
## Enviroments
8+
Необходимо заполнить **.env.sample** и в последствии перемеиновать его в **.env**
9+
```python
10+
# .env.sample
11+
POSTGRES_PASSWORD=password # Пароль от базы данных (Настройка)
12+
DB_PASSWORD=password # Пароль от базы данных (Использование)
13+
TEST_POSTGRES_PASSWORD=password # Пароль от тестовой базы данный (Настройка)
14+
TEST_DB_PASSWORD=password # Пароль от тестовой базы данных (Использование)
15+
```
16+
## Docker
17+
Шаблон находится под системой управления и контеризации - **Docker**.
18+
Если у вас нет Docker - вы можете установить его с официального сайта: [Docker](https://www.docker.com/get-started/)
19+
- Вам необходимо сделать "Билд"
20+
```bash
21+
docker compose build
22+
```
23+
- Вам необходимо запустить окружение
24+
```bash
25+
docker compose up
26+
```
27+
- После успешного запуска приложение будет доступно по адрессу: http://localhost:8080
28+
- Grafana: http://localhost:3000
29+
- Flower: http://localhost:5555
30+
31+
# View
32+
Обзор и детали данного шаблона
33+
## Найболее используемые
34+
Найболее используемые конструкции с которыми приходится часто взаимодействовать.
35+
### Registration Routers
36+
- В каждом приложений необходимо инициализировать router
37+
```python
38+
# api/users/views.py
39+
from fastapi import APIRouter
40+
41+
42+
router = APIRouter(
43+
prefix='/users',
44+
tags=['Users'],
45+
)
46+
```
47+
- Затем зарегистрировать роутер
48+
```python
49+
# api_v1/routers.py
50+
from api_v1.users.views import router as users
51+
from config import settings
52+
53+
54+
# В этой функции нужно по порядку регистрировать routers
55+
def register_routers(app: FastAPI) -> None:
56+
app.include_router(
57+
router=users,
58+
prefix=settings.API_PREFIX,
59+
)
60+
```
61+
После регистрации данные маршруты будут доступны.
62+
63+
### Registration Logs
64+
- Логи захватывают все исключения возникшие в системе
65+
и с помошью дисперичизации распределяется по нужным **file.log**
66+
```python
67+
# app_includes/logs_errors.py
68+
from fastapi import FastAPI
69+
from api_v1.exeptions import ValidationError
70+
71+
72+
# В данной функции регистрируются все исключения для захватывания Логами
73+
def register_errors(app: FastAPI) -> None:
74+
@app.exception_handler(ValidationError)
75+
async def validation_error_handler(
76+
request: Request,
77+
exc: ValidationError,
78+
):
79+
logger.opt(exception=True).warning(exc)
80+
response = dict(
81+
status=False,
82+
error_code=exc.status_code,
83+
message=exc.detail,
84+
)
85+
return JSONResponse(response)
86+
```
87+
- Если вы пишете пользовательское исключение например:
88+
```python
89+
from starlette.exceptions import HTTPException
90+
91+
92+
class ValidationError(HTTPException):
93+
94+
pass
95+
```
96+
То вам нужно его зарегистрировать как было показанно выше,
97+
иначе logs не смогут выявить данное исключение и данные будут утеряны.
98+
99+
### Registration Middlaware
100+
- Для регистрации Middlaware вам нужно добавить его в функцию
101+
```python
102+
from fastapi.middleware.cors import CORSMiddleware
103+
from fastapi import FastAPI
104+
105+
from config import settings
106+
107+
108+
# Данная функция регистрирует все middleware
109+
def register_middlewares(app: FastAPI) -> None:
110+
app.add_middleware(
111+
CORSMiddleware,
112+
allow_origins=[
113+
settings.CURRENT_ORIGIN,
114+
],
115+
allow_credentials=True,
116+
allow_methods=['*'],
117+
allow_headers=['*'],
118+
)
119+
```
120+
- При появлении новых middleware добавляйте их по порядку в эту функцию
121+
122+
### Celery
123+
- Для регистрации task вам нужно создать файл с именем **tasks.py** в вашем приложении:
124+
```python
125+
# api_v1/users/tasks.py
126+
from config import celery_app
127+
import asyncio
128+
129+
130+
@celery_app.task
131+
async def time_sleep_task():
132+
"""
133+
Тестовая задача для Celery
134+
"""
135+
await asyncio.sleep(2.0)
136+
return 'Task is done'
137+
```
138+
- Затем добавить этот файл в список пакетов Celery
139+
```python
140+
# confin.celery.connection.py
141+
142+
app = Celery(__name__)
143+
app.conf.broker_url = settings.rabbit.broker_url
144+
# Регистрация до окружения где находится tasks.py
145+
app.autodiscover_tasks(packages=['api_v1.users'])
146+
```
147+
- После этих действий ваша task будет зарегистрирована
148+
149+
### Test
150+
- Для тестирования у вас есть тестовая база данных, а так же
151+
уже инициализированный отдельный клиент.
152+
Cпособ реализации в **api_v1/tests/conftest.py**
153+
- Что бы написать тестовую функцию которой нужен доступ к API,
154+
вам нужно использовать fixture - client.
155+
> [!NOTE]
156+
> Для асинхронных тестов используйте **@pytest.mark.asyncio**
157+
158+
```python
159+
# api_v1.tests.test_users.py
160+
import pytest
161+
162+
163+
@pytest.mark.asyncio
164+
async def test_get_user_error(client: AsyncClient):
165+
response = await client.get(
166+
'/users/get',
167+
)
168+
assert response.status_code == 400
169+
```
170+
- Для запуска используйте команду
171+
```bash
172+
pytest
173+
```

api_v1/routers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66

77
def register_routers(app: FastAPI) -> None:
8+
"""
9+
Функция по регистрации роутеров
10+
"""
811
app.include_router(
912
router=users,
1013
prefix=settings.API_PREFIX,

api_v1/users/tasks.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from config import celery_app
2+
import asyncio
3+
4+
5+
@celery_app.task
6+
async def time_sleep_task():
7+
"""
8+
Тестовая задача для Celery
9+
"""
10+
await asyncio.sleep(2.0)
11+
return 'Task is done'

app_includes/logs_errors.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010

1111

1212
def register_errors(app: FastAPI) -> None:
13+
"""
14+
Крючек для логирования различных исключений
15+
"""
1316
@app.exception_handler(ValidationError)
1417
async def validation_error_handler(
1518
request: Request,

config/celery/connection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class Celery(celery.Celery):
1111
"""
12-
Инициализация Celery
12+
Инициализация асинхронного Celery
1313
"""
1414

1515
def __init__(self, *args, **kwargs) -> None:
@@ -41,4 +41,4 @@ def wrapper(*args,
4141

4242
app = Celery(__name__)
4343
app.conf.broker_url = settings.rabbit.broker_url
44-
app.autodiscover_tasks(packages=[])
44+
app.autodiscover_tasks(packages=['api_v1.users'])

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ services:
105105
image: prom/alertmanager:v0.20.0
106106
container_name: alertmanager
107107
volumes:
108-
- ./docker/alertmanager:/etc/alertmanager
108+
- ./alertmanager:/etc/alertmanager
109109
command:
110110
- '--config.file=/etc/alertmanager/config.yml'
111111
- '--storage.path=/alertmanager'

0 commit comments

Comments
 (0)