From 91ab38efc7f9de252c354dc8a3cbac0fd5b72487 Mon Sep 17 00:00:00 2001 From: Arduinum Date: Sun, 28 Dec 2025 15:25:51 +0300 Subject: [PATCH] added: base for backend on fastapi --- .env.example | 5 +++ .pre-commit-config.yaml | 2 ++ pyproject.toml | 2 +- src/kawai_focus_v2/api/__init__.py | 0 src/kawai_focus_v2/api/timers/__init__.py | 0 src/kawai_focus_v2/api/timers/router.py | 43 +++++++++++++++++++++++ src/kawai_focus_v2/core/settings.py | 9 +++++ src/kawai_focus_v2/database/cruds.py | 15 ++++---- src/kawai_focus_v2/database/data.py | 6 ++-- src/kawai_focus_v2/database/seed.py | 4 +-- src/kawai_focus_v2/main.py | 6 ++++ src/kawai_focus_v2/schemas/timer.py | 22 +++++++++++- src/kawai_focus_v2/start_app.py | 12 +++++++ 13 files changed, 111 insertions(+), 15 deletions(-) create mode 100644 src/kawai_focus_v2/api/__init__.py create mode 100644 src/kawai_focus_v2/api/timers/__init__.py create mode 100644 src/kawai_focus_v2/api/timers/router.py create mode 100644 src/kawai_focus_v2/main.py create mode 100644 src/kawai_focus_v2/start_app.py diff --git a/.env.example b/.env.example index f410128..04a0bf0 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,8 @@ # настройки для бд NAME_DB = "название бд" ECHO_DB = "булево значение для дебага бд" + +# настройки бекенда +HOST_APP=ip или доменное имя для app +PORT_APP=порт для app +IS_RELOAD=True для разработки, False для обычного использования diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b8babd2..2844f16 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,3 +28,5 @@ repos: - sqlalchemy - alembic - pydantic-settings + - fastapi + - uvicorn diff --git a/pyproject.toml b/pyproject.toml index cc51283..5b2e28f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ dependencies = [ ] [project.scripts] -kawai-focus-v2 = "kawai_focus_v2:main" +kawai-focus = "kawai_focus_v2.start_app:run" filling-timers = "kawai_focus_v2.database.seed:start_filling_data" [build-system] diff --git a/src/kawai_focus_v2/api/__init__.py b/src/kawai_focus_v2/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/kawai_focus_v2/api/timers/__init__.py b/src/kawai_focus_v2/api/timers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/kawai_focus_v2/api/timers/router.py b/src/kawai_focus_v2/api/timers/router.py new file mode 100644 index 0000000..8b5c476 --- /dev/null +++ b/src/kawai_focus_v2/api/timers/router.py @@ -0,0 +1,43 @@ +from fastapi import APIRouter, Depends, status + +from kawai_focus_v2.database.cruds import get_timers, get_timer, new_timer, update_timer, del_timer +from kawai_focus_v2.schemas.timer import TimerModel, TimerListModel, NewTimerModel, UpdateTimerModel +from kawai_focus_v2.database.db import get_db_instance, SessionDB + + +router = APIRouter(prefix='/timers', tags=['timers']) + + +@router.get('/', response_model=list[TimerListModel], status_code=status.HTTP_200_OK) +def list_timers(db: SessionDB = Depends(get_db_instance)) -> list[TimerListModel]: + """Ручка для получения списка таймеров""" + + return get_timers(db=db) + + +@router.get('/{id}', response_model=TimerModel, status_code=status.HTTP_200_OK) +def timer(id: int, db: SessionDB = Depends(get_db_instance)) -> TimerModel: + """Ручка для получения таймера""" + + return get_timer(timer_id=id, db=db) + + +@router.post('/new', response_model=TimerModel, status_code=status.HTTP_201_CREATED) +def add_timer(data: NewTimerModel, db: SessionDB = Depends(get_db_instance)) -> TimerModel: + """Ручка для создания нового таймера""" + + return new_timer(data=data, db=db) + + +@router.patch('/{id}', response_model=TimerModel, status_code=status.HTTP_200_OK) +def update_data_timer(id: int, data: UpdateTimerModel, db: SessionDB = Depends(get_db_instance)) -> TimerModel: + """Ручка для обновления таймера""" + + return update_timer(timer_id=id, data=data, db=db) + + +@router.delete('/{id}', status_code=status.HTTP_204_NO_CONTENT) +def delete_timer(id: int, db: SessionDB = Depends(get_db_instance)) -> None: + """Ручка для удаления таймера""" + + del_timer(timer_id=id, db=db) diff --git a/src/kawai_focus_v2/core/settings.py b/src/kawai_focus_v2/core/settings.py index 79a7b24..a6e834b 100644 --- a/src/kawai_focus_v2/core/settings.py +++ b/src/kawai_focus_v2/core/settings.py @@ -25,9 +25,18 @@ class SettingsDB(ModelConfig): return f'sqlite:///{self.name_db}' +class SettingsApp(ModelConfig): + """Настройки для приложения""" + + port_app: int + host_app: str + is_reload: bool + + class Settings(ModelConfig): """Класс для данных конфига""" + app_settings: SettingsApp = Field(default_factory=SettingsApp) db_settings: SettingsDB = Field(default_factory=SettingsDB) diff --git a/src/kawai_focus_v2/database/cruds.py b/src/kawai_focus_v2/database/cruds.py index abec8d1..402a97d 100644 --- a/src/kawai_focus_v2/database/cruds.py +++ b/src/kawai_focus_v2/database/cruds.py @@ -1,11 +1,11 @@ from sqlalchemy import select from kawai_focus_v2.database.models import Timer -from kawai_focus_v2.schemas.timer import TimerModel, TimerListModel +from kawai_focus_v2.schemas.timer import TimerModel, TimerListModel, UpdateTimerModel, NewTimerModel from kawai_focus_v2.database.db import get_db_instance, SessionDB -def get_timer(timer_id: int) -> TimerModel: +def get_timer(timer_id: int, db: SessionDB) -> TimerModel: """Функция для получения данных таймера""" db = get_db_instance() @@ -14,10 +14,9 @@ def get_timer(timer_id: int) -> TimerModel: return TimerModel.model_validate(timer, from_attributes=True) -def list_timers() -> list[TimerListModel]: +def get_timers(db: SessionDB) -> list[TimerListModel]: """Функция для получения списка таймеров""" - db = get_db_instance() with db.get_session() as session: timers = session.execute( select(Timer.id, Timer.title, Timer.pomodoro_time, Timer.count_pomodoro) @@ -26,7 +25,7 @@ def list_timers() -> list[TimerListModel]: return [TimerListModel.model_validate(timer, from_attributes=True) for timer in timers] -def new_timer(data: TimerModel, db: SessionDB) -> TimerModel: +def new_timer(data: NewTimerModel, db: SessionDB) -> TimerModel: """Функция для создания нового таймера""" with db.get_session() as session: @@ -38,13 +37,13 @@ def new_timer(data: TimerModel, db: SessionDB) -> TimerModel: return TimerModel.model_validate(timer, from_attributes=True) -def update_timer(data: TimerModel, db: SessionDB) -> TimerModel: +def update_timer(timer_id: int, data: UpdateTimerModel, db: SessionDB) -> TimerModel: """Функция для обновления таймера""" with db.get_session() as session: - timer = session.get(Timer, data.id) + timer = session.get(Timer, timer_id) - for field, value in data.model_dump(exclude={'id'}).items(): + for field, value in data.model_dump(exclude_unset=True).items(): setattr(timer, field, value) session.commit() diff --git a/src/kawai_focus_v2/database/data.py b/src/kawai_focus_v2/database/data.py index ed9c497..84a47a4 100644 --- a/src/kawai_focus_v2/database/data.py +++ b/src/kawai_focus_v2/database/data.py @@ -1,15 +1,15 @@ -from kawai_focus_v2.schemas.timer import TimerModel +from kawai_focus_v2.schemas.timer import NewTimerModel data_timers = [ - TimerModel( + NewTimerModel( title='Timer mini example', pomodoro_time=10, break_time=3, break_long_time=15, count_pomodoro=2 ), - TimerModel( + NewTimerModel( title='Timer max example', pomodoro_time=90, break_time=10, diff --git a/src/kawai_focus_v2/database/seed.py b/src/kawai_focus_v2/database/seed.py index fbf489c..5927385 100644 --- a/src/kawai_focus_v2/database/seed.py +++ b/src/kawai_focus_v2/database/seed.py @@ -1,10 +1,10 @@ -from kawai_focus_v2.schemas.timer import TimerModel +from kawai_focus_v2.schemas.timer import NewTimerModel from kawai_focus_v2.database.cruds import new_timer from kawai_focus_v2.database.db import get_db_instance from kawai_focus_v2.database.data import data_timers -def new_temers(data: list[TimerModel]) -> None: +def new_temers(data: list[NewTimerModel]) -> None: """Заполняет базу данных образцами таймеров""" db = get_db_instance() diff --git a/src/kawai_focus_v2/main.py b/src/kawai_focus_v2/main.py new file mode 100644 index 0000000..2cf7a63 --- /dev/null +++ b/src/kawai_focus_v2/main.py @@ -0,0 +1,6 @@ +from fastapi import FastAPI +from kawai_focus_v2.api.timers.router import router as timers_router + + +app = FastAPI(title='Kawai-Focus') +app.include_router(timers_router, prefix='/api') diff --git a/src/kawai_focus_v2/schemas/timer.py b/src/kawai_focus_v2/schemas/timer.py index 62ace44..e2b37ee 100644 --- a/src/kawai_focus_v2/schemas/timer.py +++ b/src/kawai_focus_v2/schemas/timer.py @@ -5,7 +5,7 @@ from kawai_focus_v2.core.messages.errors import ErrorMessage class TimerModel(BaseModel): """Модель схемы данных таймера""" - id: int | None = None + id: int title: str pomodoro_time: int break_time: int @@ -13,6 +13,26 @@ class TimerModel(BaseModel): count_pomodoro: int +class NewTimerModel(BaseModel): + """Модель схемы нового таймера""" + + title: str + pomodoro_time: int + break_time: int + break_long_time: int + count_pomodoro: int + + +class UpdateTimerModel(BaseModel): + """Модель схемы обновления данных таймера""" + + title: str | None = None + pomodoro_time: int | None = None + break_time: int | None = None + break_long_time: int | None = None + count_pomodoro: int | None = None + + class TimerListModel(BaseModel): """Модель схемы данных таймера для списка""" diff --git a/src/kawai_focus_v2/start_app.py b/src/kawai_focus_v2/start_app.py new file mode 100644 index 0000000..a01f8fa --- /dev/null +++ b/src/kawai_focus_v2/start_app.py @@ -0,0 +1,12 @@ +from kawai_focus_v2.core.settings import settings + +import uvicorn + + +def run(): + uvicorn.run( + 'kawai_focus_v2.main:app', + host=settings.app_settings.host_app, + port=settings.app_settings.port_app, + reload=settings.app_settings.is_reload + )