Update sanic example

This commit is contained in:
Roman Mogylatov 2021-09-30 18:56:29 -04:00
parent e670377bb3
commit 31bed0651f
7 changed files with 58 additions and 51 deletions

View File

@ -98,8 +98,8 @@ The output should be something like:
.. code-block:: .. code-block::
platform darwin -- Python 3.8.3, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 platform darwin -- Python 3.9.5, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
plugins: cov-2.10.0, sanic-1.6.1 plugins: cov-2.12.1, sanic-1.8.1, anyio-3.3.2
collected 3 items collected 3 items
giphynavigator/tests.py ... [100%] giphynavigator/tests.py ... [100%]
@ -114,6 +114,6 @@ The output should be something like:
giphynavigator/giphy.py 14 9 36% giphynavigator/giphy.py 14 9 36%
giphynavigator/handlers.py 11 0 100% giphynavigator/handlers.py 11 0 100%
giphynavigator/services.py 9 1 89% giphynavigator/services.py 9 1 89%
giphynavigator/tests.py 34 0 100% giphynavigator/tests.py 39 0 100%
--------------------------------------------------- ---------------------------------------------------
TOTAL 90 14 84% TOTAL 95 14 85%

View File

@ -3,6 +3,6 @@
from .application import create_app from .application import create_app
if __name__ == '__main__': if __name__ == "__main__":
app = create_app() app = create_app()
app.run(host='0.0.0.0', port=8000, debug=True) app.run(host="0.0.0.0", port=8000, debug=True)

View File

@ -9,11 +9,11 @@ from . import handlers
def create_app() -> Sanic: def create_app() -> Sanic:
"""Create and return Sanic application.""" """Create and return Sanic application."""
container = Container() container = Container()
container.config.from_yaml('config.yml') container.config.from_yaml("config.yml")
container.config.giphy.api_key.from_env('GIPHY_API_KEY') container.config.giphy.api_key.from_env("GIPHY_API_KEY")
container.wire(modules=[handlers]) container.wire(modules=[handlers])
app = Sanic('Giphy Navigator') app = Sanic("giphy-navigator")
app.container = container app.ctx.container = container
app.add_route(handlers.index, '/') app.add_route(handlers.index, "/")
return app return app

View File

@ -5,7 +5,7 @@ from aiohttp import ClientSession, ClientTimeout
class GiphyClient: class GiphyClient:
API_URL = 'https://api.giphy.com/v1' API_URL = "https://api.giphy.com/v1"
def __init__(self, api_key, timeout): def __init__(self, api_key, timeout):
self._api_key = api_key self._api_key = api_key
@ -13,11 +13,11 @@ class GiphyClient:
async def search(self, query, limit): async def search(self, query, limit):
"""Make search API call and return result.""" """Make search API call and return result."""
url = f'{self.API_URL}/gifs/search' url = f"{self.API_URL}/gifs/search"
params = { params = {
'q': query, "q": query,
'api_key': self._api_key, "api_key": self._api_key,
'limit': limit, "limit": limit,
} }
async with ClientSession(timeout=self._timeout) as session: async with ClientSession(timeout=self._timeout) as session:
async with session.get(url, params=params) as response: async with session.get(url, params=params) as response:

View File

@ -15,15 +15,15 @@ async def index(
default_query: str = Provide[Container.config.default.query], default_query: str = Provide[Container.config.default.query],
default_limit: int = Provide[Container.config.default.limit.as_int()], default_limit: int = Provide[Container.config.default.limit.as_int()],
) -> HTTPResponse: ) -> HTTPResponse:
query = request.args.get('query', default_query) query = request.args.get("query", default_query)
limit = int(request.args.get('limit', default_limit)) limit = int(request.args.get("limit", default_limit))
gifs = await search_service.search(query, limit) gifs = await search_service.search(query, limit)
return json( return json(
{ {
'query': query, "query": query,
'limit': limit, "limit": limit,
'gifs': gifs, "gifs": gifs,
}, },
) )

View File

@ -15,4 +15,4 @@ class SearchService:
result = await self._giphy_client.search(query, limit) result = await self._giphy_client.search(query, limit)
return [{'url': gif['url']} for gif in result['data']] return [{"url": gif["url"]} for gif in result["data"]]

View File

@ -3,6 +3,7 @@
from unittest import mock from unittest import mock
import pytest import pytest
from sanic import Sanic
from giphynavigator.application import create_app from giphynavigator.application import create_app
from giphynavigator.giphy import GiphyClient from giphynavigator.giphy import GiphyClient
@ -10,65 +11,71 @@ from giphynavigator.giphy import GiphyClient
@pytest.fixture @pytest.fixture
def app(): def app():
Sanic.test_mode = True
app = create_app() app = create_app()
yield app yield app
app.container.unwire() app.ctx.container.unwire()
async def test_index(app): @pytest.fixture
def test_client(loop, app, sanic_client):
return loop.run_until_complete(sanic_client(app))
async def test_index(app, test_client):
giphy_client_mock = mock.AsyncMock(spec=GiphyClient) giphy_client_mock = mock.AsyncMock(spec=GiphyClient)
giphy_client_mock.search.return_value = { giphy_client_mock.search.return_value = {
'data': [ "data": [
{'url': 'https://giphy.com/gif1.gif'}, {"url": "https://giphy.com/gif1.gif"},
{'url': 'https://giphy.com/gif2.gif'}, {"url": "https://giphy.com/gif2.gif"},
], ],
} }
with app.container.giphy_client.override(giphy_client_mock): with app.ctx.container.giphy_client.override(giphy_client_mock):
_, response = await app.asgi_client.get( response = await test_client.get(
'/', "/",
params={ params={
'query': 'test', "query": "test",
'limit': 10, "limit": 10,
}, },
) )
assert response.status == 200 assert response.status_code == 200
data = response.json() data = response.json()
assert data == { assert data == {
'query': 'test', "query": "test",
'limit': 10, "limit": 10,
'gifs': [ "gifs": [
{'url': 'https://giphy.com/gif1.gif'}, {"url": "https://giphy.com/gif1.gif"},
{'url': 'https://giphy.com/gif2.gif'}, {"url": "https://giphy.com/gif2.gif"},
], ],
} }
async def test_index_no_data(app): async def test_index_no_data(app, test_client):
giphy_client_mock = mock.AsyncMock(spec=GiphyClient) giphy_client_mock = mock.AsyncMock(spec=GiphyClient)
giphy_client_mock.search.return_value = { giphy_client_mock.search.return_value = {
'data': [], "data": [],
} }
with app.container.giphy_client.override(giphy_client_mock): with app.ctx.container.giphy_client.override(giphy_client_mock):
_, response = await app.asgi_client.get('/') response = await test_client.get("/")
assert response.status == 200 assert response.status_code == 200
data = response.json() data = response.json()
assert data['gifs'] == [] assert data["gifs"] == []
async def test_index_default_params(app): async def test_index_default_params(app, test_client):
giphy_client_mock = mock.AsyncMock(spec=GiphyClient) giphy_client_mock = mock.AsyncMock(spec=GiphyClient)
giphy_client_mock.search.return_value = { giphy_client_mock.search.return_value = {
'data': [], "data": [],
} }
with app.container.giphy_client.override(giphy_client_mock): with app.ctx.container.giphy_client.override(giphy_client_mock):
_, response = await app.asgi_client.get('/') response = await test_client.get("/")
assert response.status == 200 assert response.status_code == 200
data = response.json() data = response.json()
assert data['query'] == app.container.config.default.query() assert data["query"] == app.ctx.container.config.default.query()
assert data['limit'] == app.container.config.default.limit() assert data["limit"] == app.ctx.container.config.default.limit()