Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added app/crud/__init__.py
Empty file.
53 changes: 53 additions & 0 deletions app/crud/words.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import logging

from sqlalchemy import or_, select
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.words import Word
from app.schemas.words import WordCreateSchema

logger = logging.getLogger(__name__)


class CRUDWord:

async def create_word(self, word: WordCreateSchema, session: AsyncSession):
try:
new_word = Word(**word.model_dump())
session.add(new_word)
await session.flush()
await session.commit()
await session.refresh(new_word)
logger.info(f"Добавлеено слово {new_word}")
return new_word
except SQLAlchemyError as e:
logger.error(f"Ошибка при добавлении слова: {e}")
raise

async def get_all_words(self, session: AsyncSession):
try:
query = select(Word)
result = await session.execute(query)
words = result.scalars().all()
logger.info("Получен список всех слов")
return words
except SQLAlchemyError as e:
logger.error(f"Ошибка при получении списка слов: {e}")
raise

async def get_word(self, word: str, session: AsyncSession):
try:
query = select(Word).where(
or_(Word.english == word, Word.russian == word)
)
result = await session.execute(query)
find_word = result.scalars().first()
if find_word:
logger.info(f"Получено слово: '{find_word}'")
else:
logger.warning(f"Слово '{word}' не найдено в базе")
return find_word
except SQLAlchemyError as e:
logger.error(f"Ошибка при получении слова {word}: {e}")
raise
5 changes: 5 additions & 0 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

from app.core.config import settings
from app.core.logging import setup_logging
from app.routers.questions import question_router
from app.routers.words import word_router

setup_logging()

Expand All @@ -23,3 +25,6 @@ async def lifespan(app: FastAPI):
description=settings.description,
lifespan=lifespan,
)

app.include_router(word_router)
app.include_router(question_router)
53 changes: 53 additions & 0 deletions app/routers/questions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import random

from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.database import get_session
from app.crud.words import CRUDWord
from app.schemas.words import QuestionResponseSchema

question_router = APIRouter(
prefix="/questions",
tags=[
"Вопросы",
],
)

word_crud = CRUDWord()


@question_router.get(
"", response_model=QuestionResponseSchema, summary="Получение вопроса"
)
async def get_question(
session: AsyncSession = Depends(get_session),
) -> QuestionResponseSchema:
words = await word_crud.get_all_words(session)
if len(words) < 4:
return {"error": "В базее должно быть минимум 4 слова"}

correct_word = random.choice(words)
options_words = random.sample(words, 4)
direction = random.choice(["en-ru", "ru-en"])

if direction == "en-ru":
question_word = correct_word.english
correct_answer = correct_word.russian
options = [w.russian for w in options_words]
else:
question_word = correct_word.russian
correct_answer = correct_word.english
options = [w.english for w in options_words]

if correct_answer not in options:
options[0] = correct_answer

random.shuffle(options)

return {
"word": question_word,
"options": options,
"correct": correct_answer,
"direction": direction,
}
69 changes: 69 additions & 0 deletions app/routers/words.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.database import get_session
from app.crud.words import CRUDWord
from app.schemas.words import WordCreateSchema, WordReadSchema

word_router = APIRouter(
prefix="/words",
tags=[
"Слова",
],
)

word_crud = CRUDWord()


@word_router.post(
"",
response_model=WordReadSchema,
summary="Добавление слова",
)
async def add_word(
word: WordCreateSchema, session: AsyncSession = Depends(get_session)
) -> WordReadSchema:
try:
add_word = await word_crud.create_word(word, session)
return add_word
except Exception as e:
raise e


@word_router.get(
"/all",
response_model=list[WordReadSchema],
summary="Получение списка всех слов",
)
async def get_all_words(
session: AsyncSession = Depends(get_session),
) -> list[WordReadSchema]:
try:
words = await word_crud.get_all_words(session)
if not words:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Список слов отсутсттвует",
)
return words
except Exception as e:
raise e


@word_router.get(
"/{word}", response_model=WordReadSchema, summary="Получение слова"
)
async def get_word(
word: str, session: AsyncSession = Depends(get_session)
) -> WordReadSchema:
try:
word = word.lower()
find_word = await word_crud.get_word(word, session)
if not find_word:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Слово не найдено",
)
return find_word
except Exception as e:
raise e
2 changes: 1 addition & 1 deletion app/schemas/words.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from pydantic import BaseModel


class QuestionResponse(BaseModel):
class QuestionResponseSchema(BaseModel):
word: str
options: list[str]
correct: str
Expand Down