diff --git a/Shops/pizzeria/homeworks/fastapi_hw/main.py b/Shops/pizzeria/homeworks/fastapi_hw/main.py new file mode 100644 index 0000000..27a0fa9 --- /dev/null +++ b/Shops/pizzeria/homeworks/fastapi_hw/main.py @@ -0,0 +1,30 @@ +from fastapi import FastAPI, HTTPException +from http import HTTPStatus +from models import RequestInfo, ResponseInfo +from services import process_request +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) -> dict: + try: + data = await process_request(request=request.dict()) + except Exception as error: + raise HTTPException( + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + detail=error.__class__.__name__, + ) + return ResponseInfo(**data).dict(exclude_none=True) + + +if __name__ == "__main__": + uvicorn.run( + app=app, + host='127.0.0.1', + port=8000 + ) diff --git a/Shops/pizzeria/homeworks/fastapi_hw/models.py b/Shops/pizzeria/homeworks/fastapi_hw/models.py new file mode 100644 index 0000000..d5c7089 --- /dev/null +++ b/Shops/pizzeria/homeworks/fastapi_hw/models.py @@ -0,0 +1,33 @@ +from pydantic import BaseModel, ValidationError, validator, Field +from typing import Optional + + +class RequestInfo(BaseModel): + cats: Optional[int] + dogs: Optional[int] + + @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 TranslateResponse(BaseModel): + translated_text: str = Field(alias='translatedText') + + +class ResponseInfo(BaseModel): + cats: Optional[tuple[str, ...]] + dogs: Optional[tuple[str, ...]] diff --git a/Shops/pizzeria/homeworks/fastapi_hw/services.py b/Shops/pizzeria/homeworks/fastapi_hw/services.py new file mode 100644 index 0000000..4f7128f --- /dev/null +++ b/Shops/pizzeria/homeworks/fastapi_hw/services.py @@ -0,0 +1,66 @@ +import aiohttp +from typing import Optional +from models import CatsFactsResponse, DogsFactsResponse, TranslateResponse + +CATS_URL = 'https://meowfacts.herokuapp.com/' +DOGS_URL = 'http://dog-api.kinduff.com/api/facts' +TRANSLATION_URL = 'https://libretranslate.de/translate' + + +async def get_data_from_api(url: str, params: Optional[dict], method: str): + async with aiohttp.ClientSession() as session: + if method == 'get': + async with session.get(url=url, params=params, timeout=5) as response: + response = await response.json() + elif method == 'post': + async with session.post(url=url, json=params, timeout=5) as response: + response = await response.json() + return response + + +async def prepare_data_to_translation(animal_facts: tuple[str, ...], source: str, target: str): + result = [] + for fact in animal_facts: + params = { + 'q': fact, + 'source': source, + 'target': target, + 'format': 'text', + } + translated_response = await get_data_from_api(url=TRANSLATION_URL, params=params, method='post') + result.append(TranslateResponse(**translated_response).translated_text) + return result + + +async def get_cats_facts(facts_number: Optional[int]) -> tuple: + params = None + if facts_number: + params = {'count': facts_number} + response = await get_data_from_api(CATS_URL, params, method='get') + return CatsFactsResponse(**response).data + + +async def get_dogs_facts(facts_number: Optional[int]) -> tuple: + params = None + if facts_number: + params = {'number': facts_number} + response = await get_data_from_api(DOGS_URL, params, method='get') + return DogsFactsResponse(**response).facts + + +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(): + if facts_num is not None: + result[animal] = await prepare_data_to_translation( + await facts_about_animals.get(animal)(facts_num), + source='en', + target='ru', + ) + return result