Skip to content
Open
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
81 changes: 69 additions & 12 deletions task-fastapi/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import time
from enum import Enum
from typing import Optional
from typing import Optional, Dict

from fastapi import FastAPI, Query, HTTPException, status
from pydantic import BaseModel, Field
Expand All @@ -26,6 +26,9 @@ class Dog(BaseModel):
pk: Optional[int] = Field(None, title="Идентификатор")
name: str = Field(..., title="Имя собаки")
kind: DogType = Field(..., title="Порода собаки")
age: Optional[int] = Field(None, title="Возраст собаки", ge=0)
owner: Optional[str] = Field(None, title="Имя владельца")
vaccinated: bool = Field(False, title="Привит ли")


class Timestamp(BaseModel):
Expand Down Expand Up @@ -94,10 +97,31 @@ def create_dog(dog: Dog) -> Dog:
else:
pk = 1

DB_DOGS[pk] = Dog(pk=pk, name=dog.name, kind=dog.kind)
DB_DOGS[pk] = Dog(
pk=pk,
name=dog.name,
kind=dog.kind,
age=dog.age,
owner=dog.owner,
vaccinated=dog.vaccinated,
)

return DB_DOGS[pk]

@app.get("/dog/search", response_model=list[Dog])
def search_dog_by_name(name: str = Query(..., title="Имя собаки")) -> list[Dog]:
"""
Поиск собак по имени.

:param name: Имя собаки.
:return: Список собак с совпадающим именем.
"""
result = [dog for dog in DB_DOGS.values() if dog.name.lower() == name.lower()]
if not result:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Собаки с таким именем не найдены."
)
return result

@app.get("/dog/{pk}", response_model=Dog)
def get_dog_by_pk(pk: int) -> Optional[Dog]:
Expand All @@ -117,21 +141,54 @@ def get_dog_by_pk(pk: int) -> Optional[Dog]:


@app.patch("/dog/{pk}", response_model=Dog)
def update_dog(pk: int, dog: Dog) -> Optional[Dog]:
def update_dog(pk: int, update_data: Dict[str, Optional[str]]) -> Dog:
"""
Обновление собаки по идентификатору.

:param pk: Идентификатор.
:param dog: Данные собаки для обновления.
:return:
:param update_data: Словарь с полями для обновления.
:return: Обновлённые данные собаки.
"""

if pk in DB_DOGS:
values = dog.dict(exclude={"pk"}, exclude_none=True)
DB_DOGS[pk] = DB_DOGS[pk].copy(update=values)
if pk not in DB_DOGS:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Собака с таким идентификатором не найдена.",
)

return DB_DOGS[pk]
current_dog = DB_DOGS[pk]

raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Объект не найден."
)
# Проверяем переданные поля
invalid_keys = [key for key in update_data.keys() if not hasattr(current_dog, key)]
if invalid_keys:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Недопустимые поля: {', '.join(invalid_keys)}"
)

# Обновляем только переданные поля
for key, value in update_data.items():
if hasattr(current_dog, key) and value is not None:
setattr(current_dog, key, value)

DB_DOGS[pk] = current_dog

return current_dog
@app.delete("/dog/{pk}", response_model=Dog)
def delete_dog(pk: int) -> Dog:
"""
Удаление собаки по идентификатору.

:param pk: Идентификатор собаки.
:return: Удалённая собака.
"""
if pk not in DB_DOGS:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Собака с таким идентификатором не найдена.",
)

# Удаление собаки из базы данных
deleted_dog = DB_DOGS.pop(pk)

return deleted_dog