Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
23 changes: 23 additions & 0 deletions Shops/pizzeria/homeworks/fastapi_hw/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from fastapi import FastAPI
from models import RequestInfo, ResponseInfo
from services import process_request, make_response
import uvicorn

app = FastAPI(title='Funny facts about Cats and Dogs')


@app.post(
'/info',
description='Get funny facts about Cats nd Dogs',
)
async def get_info(request: RequestInfo) -> ResponseInfo:
data = await process_request(request=request.dict())
return make_response(data=data)


if __name__ == "__main__":
uvicorn.run(
app=app,
host='127.0.0.1',
port=8000
)
28 changes: 28 additions & 0 deletions Shops/pizzeria/homeworks/fastapi_hw/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from pydantic import BaseModel, ValidationError, validator


class RequestInfo(BaseModel):
cats: int
dogs: int
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Позволь пользователю вообще не задавать что-то, вдруг ему не интересны факты о собаках


@validator('*')
def num_of_facts(cls, value):
if value > 5:
raise ValidationError('Too many facts you want to know')
elif value <= 0:
raise ValidationError('Facts number can`t be less or equal zero')
return value


class DogsFactsResponse(BaseModel):
facts: tuple[str, ...]
success: bool


class CatsFactsResponse(BaseModel):
data: tuple[str, ...]


class ResponseInfo(BaseModel):
cats: tuple[str, ...]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну этот тупо может содержать либо строку либо ничего, в модели этого не видно

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А как тогда правильно? list[str] ?

dogs: tuple[str, ...]
49 changes: 49 additions & 0 deletions Shops/pizzeria/homeworks/fastapi_hw/services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import aiohttp
from models import CatsFactsResponse, DogsFactsResponse, ResponseInfo

CATS_URL = 'https://meowfacts.herokuapp.com/'
DOGS_URL = 'http://dog-api.kinduff.com/api/facts'


async def get_facts(url: str, params: dict = None):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

обычно в сигнатуре функций в проекте с FastAPI принято писать Optional[dict] или Union[dict, None], а не задавать явно None

async with aiohttp.ClientSession() as session:
async with session.get(url=url, params=params, timeout=5) as response:
response = await response.json()
return response


async def get_cats_facts(facts_number: int = None) -> CatsFactsResponse:
params = None
if facts_number:
params = {'count': facts_number}
response = await get_facts(CATS_URL, params)
return CatsFactsResponse(**response)


async def get_dogs_facts(facts_number: int = None) -> DogsFactsResponse:
params = None
if facts_number:
params = {'number': facts_number}
response = await get_facts(DOGS_URL, params)
return DogsFactsResponse(**response)


facts_about_animals = {
'cats': get_cats_facts,
'dogs': get_dogs_facts
}


async def process_request(request: dict):
result = {}
for animal, facts_num in request.items():
result[animal] = await facts_about_animals.get(animal)(facts_num)
return result


def make_response(data: dict) -> ResponseInfo:
result = {
'cats': data.get('cats').data,
'dogs': data.get('dogs').facts
}
return ResponseInfo(**result)