Files
bot-telegram/api/routers.py
2025-09-14 22:09:39 +05:00

259 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
API маршруты для работы с пользователями, сообщениями и настройками
"""
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from typing import List, Optional
import sys
import os
# Добавляем путь к корневой директории проекта
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from database.database import db
from database.models import User, Message, BotSettings
from api.schemas import (
UserCreate, UserUpdate, UserResponse,
MessageCreate, MessageResponse,
BotSettingCreate, BotSettingUpdate, BotSettingResponse,
MessageResponseModel, ErrorResponse
)
# Зависимость для получения сессии БД
def get_db():
"""Получение сессии базы данных"""
session = db.get_session_sync()
try:
yield session
finally:
session.close()
# Роутер для работы с пользователями
users_router = APIRouter(prefix="/users", tags=["Users"])
@users_router.get("/{telegram_id}", response_model=UserResponse)
async def get_user_by_telegram_id(telegram_id: int, db_session: Session = Depends(get_db)):
"""Получение пользователя по Telegram ID"""
user = db_session.query(User).filter(User.telegram_id == telegram_id).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Пользователь не найден"
)
return user
@users_router.get("/", response_model=List[UserResponse])
async def get_all_users(
limit: int = Query(default=100, ge=1, le=1000),
offset: int = Query(default=0, ge=0),
is_active: Optional[bool] = Query(default=None),
db_session: Session = Depends(get_db)
):
"""Получение списка всех пользователей с фильтрацией"""
query = db_session.query(User)
if is_active is not None:
query = query.filter(User.is_active == is_active)
users = query.offset(offset).limit(limit).all()
return users
@users_router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def create_user(user_data: UserCreate, db_session: Session = Depends(get_db)):
"""Создание нового пользователя"""
# Проверяем, существует ли уже пользователь
existing_user = db_session.query(User).filter(User.telegram_id == user_data.telegram_id).first()
if existing_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Пользователь уже существует"
)
# Создаем нового пользователя
new_user = User(**user_data.model_dump())
db_session.add(new_user)
db_session.commit()
db_session.refresh(new_user)
return new_user
@users_router.put("/{telegram_id}", response_model=UserResponse)
async def update_user(
telegram_id: int,
user_data: UserUpdate,
db_session: Session = Depends(get_db)
):
"""Обновление данных пользователя"""
user = db_session.query(User).filter(User.telegram_id == telegram_id).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Пользователь не найден"
)
# Обновляем только переданные поля
update_data = user_data.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(user, field, value)
db_session.commit()
db_session.refresh(user)
return user
@users_router.delete("/{telegram_id}", response_model=MessageResponseModel)
async def delete_user(telegram_id: int, db_session: Session = Depends(get_db)):
"""Деактивация пользователя (мягкое удаление)"""
user = db_session.query(User).filter(User.telegram_id == telegram_id).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Пользователь не найден"
)
user.is_active = False
db_session.commit()
return MessageResponseModel(message="Пользователь деактивирован")
# Роутер для работы с сообщениями
messages_router = APIRouter(prefix="/messages", tags=["Messages"])
@messages_router.get("/", response_model=List[MessageResponse])
async def get_messages(
user_id: Optional[int] = Query(default=None),
message_type: Optional[str] = Query(default=None),
limit: int = Query(default=100, ge=1, le=1000),
offset: int = Query(default=0, ge=0),
db_session: Session = Depends(get_db)
):
"""Получение сообщений с фильтрацией"""
query = db_session.query(Message)
if user_id:
query = query.filter(Message.user_id == user_id)
if message_type:
query = query.filter(Message.message_type == message_type)
messages = query.order_by(Message.created_at.desc()).offset(offset).limit(limit).all()
return messages
@messages_router.get("/{message_id}", response_model=MessageResponse)
async def get_message(message_id: int, db_session: Session = Depends(get_db)):
"""Получение конкретного сообщения по ID"""
message = db_session.query(Message).filter(Message.id == message_id).first()
if not message:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Сообщение не найдено"
)
return message
@messages_router.post("/", response_model=MessageResponse, status_code=status.HTTP_201_CREATED)
async def create_message(message_data: MessageCreate, db_session: Session = Depends(get_db)):
"""Создание нового сообщения"""
# Проверяем, существует ли пользователь
user = db_session.query(User).filter(User.id == message_data.user_id).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Пользователь не найден"
)
new_message = Message(**message_data.model_dump())
db_session.add(new_message)
db_session.commit()
db_session.refresh(new_message)
return new_message
# Роутер для работы с настройками бота
settings_router = APIRouter(prefix="/settings", tags=["Bot Settings"])
@settings_router.get("/", response_model=dict)
async def get_all_settings(db_session: Session = Depends(get_db)):
"""Получение всех настроек бота в виде словаря"""
settings = db_session.query(BotSettings).all()
return {setting.key: setting.value for setting in settings}
@settings_router.get("/list", response_model=List[BotSettingResponse])
async def get_all_settings_list(db_session: Session = Depends(get_db)):
"""Получение всех настроек бота в виде списка объектов"""
settings = db_session.query(BotSettings).all()
return settings
@settings_router.get("/{key}", response_model=BotSettingResponse)
async def get_setting(key: str, db_session: Session = Depends(get_db)):
"""Получение конкретной настройки по ключу"""
setting = db_session.query(BotSettings).filter(BotSettings.key == key).first()
if not setting:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Настройка не найдена"
)
return setting
@settings_router.post("/", response_model=BotSettingResponse, status_code=status.HTTP_201_CREATED)
async def create_or_update_setting(
setting_data: BotSettingCreate,
db_session: Session = Depends(get_db)
):
"""Создание или обновление настройки"""
existing_setting = db_session.query(BotSettings).filter(BotSettings.key == setting_data.key).first()
if existing_setting:
# Обновляем существующую настройку
update_data = setting_data.model_dump(exclude={"key"})
for field, value in update_data.items():
if value is not None:
setattr(existing_setting, field, value)
db_session.commit()
db_session.refresh(existing_setting)
return existing_setting
else:
# Создаем новую настройку
new_setting = BotSettings(**setting_data.model_dump())
db_session.add(new_setting)
db_session.commit()
db_session.refresh(new_setting)
return new_setting
@settings_router.put("/{key}", response_model=BotSettingResponse)
async def update_setting(
key: str,
setting_data: BotSettingUpdate,
db_session: Session = Depends(get_db)
):
"""Обновление существующей настройки"""
setting = db_session.query(BotSettings).filter(BotSettings.key == key).first()
if not setting:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Настройка не найдена"
)
update_data = setting_data.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(setting, field, value)
db_session.commit()
db_session.refresh(setting)
return setting
@settings_router.delete("/{key}", response_model=MessageResponseModel)
async def delete_setting(key: str, db_session: Session = Depends(get_db)):
"""Удаление настройки"""
setting = db_session.query(BotSettings).filter(BotSettings.key == key).first()
if not setting:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Настройка не найдена"
)
db_session.delete(setting)
db_session.commit()
return MessageResponseModel(message=f"Настройка '{key}' удалена")