Add giphynav-aiohttp app

This commit is contained in:
Roman Mogylatov 2020-07-26 22:39:01 -04:00
parent 418bba1666
commit f8255e820d
10 changed files with 145 additions and 0 deletions

View File

@ -0,0 +1,5 @@
giphy:
request_timeout: 10
search:
default_query: "Dependency Injector"
default_limit: 10

View File

@ -0,0 +1 @@
"""Top-level package."""

View File

@ -0,0 +1,10 @@
"""Main module."""
from aiohttp import web
from .application import create_app
if __name__ == '__main__':
app = create_app()
web.run_app(app)

View File

@ -0,0 +1,21 @@
"""Application module."""
from aiohttp import web
from .containers import ApplicationContainer
def create_app():
"""Create and return Flask application."""
container = ApplicationContainer()
container.config.from_yaml('config.yml')
container.config.giphy.api_key.from_env('GIPHY_API_KEY')
app: web.Application = container.app()
app.container = container
app.add_routes([
web.get('/', container.index_view.as_view()),
])
return app

View File

@ -0,0 +1,33 @@
"""Application containers module."""
from dependency_injector import containers, providers
from dependency_injector.ext import aiohttp
from aiohttp import web
from . import giphy, services, views
class ApplicationContainer(containers.DeclarativeContainer):
"""Application container."""
app = aiohttp.Application(web.Application)
config = providers.Configuration()
giphy_client = providers.Factory(
giphy.GiphyClient,
api_key=config.giphy.api_key,
timeout=config.giphy.request_timeout,
)
search_service = providers.Factory(
services.SearchService,
giphy_client=giphy_client,
)
index_view = aiohttp.View(
views.index,
search_service=search_service,
default_query=config.search.default_query,
default_limit=config.search.default_limit,
)

View File

@ -0,0 +1,28 @@
"""Giphy client module."""
from aiohttp import ClientSession, ClientTimeout
class GiphyClient:
API_URL = 'http://api.giphy.com/v1'
def __init__(self, api_key, timeout):
self._api_key = api_key
self._timeout = ClientTimeout(timeout)
async def search(self, query, limit):
if not query:
return []
url = f'{self.API_URL}/gifs/search'
params = {
'q': query,
'api_key': self._api_key,
'limit': limit,
}
async with ClientSession(timeout=self._timeout) as session:
async with session.get(url, params=params) as response:
if response.status != 200:
response.raise_for_status()
return await response.json()

View File

@ -0,0 +1,18 @@
"""Services module."""
from .giphy import GiphyClient
class SearchService:
def __init__(self, giphy_client: GiphyClient):
self._giphy_client = giphy_client
async def search(self, query, limit):
if not query:
return []
result = await self._giphy_client.search(query, limit)
print(result.keys())
return [{'url': gif['url']} for gif in result['data']]

View File

@ -0,0 +1,25 @@
"""Views module."""
from aiohttp import web
from .services import SearchService
async def index(
request: web.Request,
search_service: SearchService,
default_query: str,
default_limit: int,
) -> web.Response:
query = request.query.get('query', default_query)
limit = request.query.get('limit', default_limit)
gifs = await search_service.search(query, limit)
return web.json_response(
{
'query': query,
'limit': limit,
'gifs': gifs,
},
)

View File

@ -0,0 +1,4 @@
dependency-injector
aiohttp
aiohttp-devtools
pyyaml