From 29d09009701d2c0fa8948963c9e0719ce05eb471 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Sun, 31 Oct 2021 17:46:23 -0400 Subject: [PATCH] Update aiohttp example and tutorial --- docs/tutorials/aiohttp.rst | 119 +++++++++--------- examples/miniapps/aiohttp/README.rst | 20 +-- .../aiohttp/giphynavigator/application.py | 7 +- .../aiohttp/giphynavigator/containers.py | 4 +- examples/miniapps/aiohttp/requirements.txt | 1 - 5 files changed, 76 insertions(+), 75 deletions(-) diff --git a/docs/tutorials/aiohttp.rst b/docs/tutorials/aiohttp.rst index 77de49a1..f77bb4d8 100644 --- a/docs/tutorials/aiohttp.rst +++ b/docs/tutorials/aiohttp.rst @@ -127,8 +127,6 @@ Now it's time to install the project requirements. We will use next packages: - ``dependency-injector`` - the dependency injection framework - ``aiohttp`` - the web framework -- ``aiohttp-devtools`` - the helper library that will provide a development server with live - reloading - ``pyyaml`` - the YAML files parsing library, used for the reading of the configuration files - ``pytest-aiohttp`` - the helper library for the testing of the ``aiohttp`` application - ``pytest-cov`` - the helper library for measuring the test coverage @@ -139,7 +137,6 @@ Put next lines into the ``requirements.txt`` file: dependency-injector aiohttp - aiohttp-devtools pyyaml pytest-aiohttp pytest-cov @@ -232,26 +229,31 @@ Put next into the ``application.py``: ]) return app + + if __name__ == "__main__": + app = create_app() + web.run_app(app) + Now we're ready to run our application Do next in the terminal: .. code-block:: bash - adev runserver giphynavigator/application.py --livereload + python -m giphynavigator.application The output should be something like: .. code-block:: bash - [18:52:59] Starting aux server at http://localhost:8001 ◆ - [18:52:59] Starting dev server at http://localhost:8000 ● + ======== Running on http://0.0.0.0:8080 ======== + (Press CTRL+C to quit) Let's check that it works. Open another terminal session and use ``httpie``: .. code-block:: bash - http http://127.0.0.1:8000/ + http http://0.0.0.0:8080/ You should see: @@ -261,7 +263,7 @@ You should see: Content-Length: 844 Content-Type: application/json; charset=utf-8 Date: Wed, 29 Jul 2020 21:01:50 GMT - Server: Python/3.9 aiohttp/3.6.2 + Server: Python/3.10 aiohttp/3.6.2 { "gifs": [], @@ -328,8 +330,10 @@ Now we need to add ``GiphyClient`` into the container. The ``GiphyClient`` has t that have to be injected: the API key and the request timeout. We will need to use two more providers from the ``dependency_injector.providers`` module: -- ``Factory`` provider that will create the ``GiphyClient`` client. -- ``Configuration`` provider that will provide the API key and the request timeout. +- ``Factory`` provider. It will create a ``GiphyClient`` client. +- ``Configuration`` provider. It will provide an API key and a request timeout for the ``GiphyClient`` + client. We will specify the location of the configuration file. The configuration provider will parse + the configuration file when we create a container instance. Edit ``containers.py``: @@ -345,7 +349,7 @@ Edit ``containers.py``: class Container(containers.DeclarativeContainer): - config = providers.Configuration() + config = providers.Configuration(yaml_files=["config.yml"]) giphy_client = providers.Factory( giphy.GiphyClient, @@ -353,18 +357,8 @@ Edit ``containers.py``: timeout=config.giphy.request_timeout, ) -.. note:: - - We have used the configuration value before it was defined. That's the principle how the - ``Configuration`` provider works. - - Use first, define later. - -Now let's add the configuration file. - -We will use YAML. - -Create an empty file ``config.yml`` in the root root of the project: +Now let's add the configuration file. We will use YAML. Create an empty file ``config.yml`` in +the root root of the project: .. code-block:: bash :emphasize-lines: 9 @@ -387,17 +381,14 @@ and put next into it: giphy: request_timeout: 10 -We will use an environment variable ``GIPHY_API_KEY`` to provide the API key. -Now we need to edit ``create_app()`` to make two things when application starts: - -- Load the configuration file the ``config.yml``. -- Load the API key from the ``GIPHY_API_KEY`` environment variable. +We will use the ``GIPHY_API_KEY`` environment variable to provide the API key. Let’s edit +``create_app()`` to fetch the key value from it. Edit ``application.py``: .. code-block:: python - :emphasize-lines: 11-12 + :emphasize-lines: 11 """Application module.""" @@ -409,7 +400,6 @@ Edit ``application.py``: def create_app() -> web.Application: container = Container() - container.config.from_yaml("config.yml") container.config.giphy.api_key.from_env("GIPHY_API_KEY") app = web.Application() @@ -420,6 +410,10 @@ Edit ``application.py``: return app + if __name__ == "__main__": + app = create_app() + web.run_app(app) + Now we need to create an API key and set it to the environment variable. As for now, don’t worry, just take this one: @@ -502,7 +496,7 @@ Edit ``containers.py``: class Container(containers.DeclarativeContainer): - config = providers.Configuration() + config = providers.Configuration(yaml_files=["config.yml"]) giphy_client = providers.Factory( giphy.GiphyClient, @@ -555,47 +549,50 @@ Edit ``handlers.py``: }, ) -To make the injection work we need to wire the container instance with the ``handlers`` module. -This needs to be done once. After it's done we can use ``Provide`` markers to specify as many -injections as needed for any handler. +To make the injection work we need to wire the container with the ``handlers`` module. +Let's configure the container to automatically make wiring with the ``handlers`` module when we +create a container instance. -Edit ``application.py``: +Edit ``containers.py``: .. code-block:: python - :emphasize-lines: 13 + :emphasize-lines: 10 - """Application module.""" + """Containers module.""" - from aiohttp import web + from dependency_injector import containers, providers - from .containers import Container - from . import handlers + from . import giphy, services - def create_app() -> web.Application: - container = Container() - container.config.from_yaml("config.yml") - container.config.giphy.api_key.from_env("GIPHY_API_KEY") - container.wire(modules=[handlers]) + class Container(containers.DeclarativeContainer): - app = web.Application() - app.container = container - app.add_routes([ - web.get("/", handlers.index), - ]) - return app + wiring_config = containers.WiringConfiguration(modules=[".handlers"]) -Make sure the app is running or use: + config = providers.Configuration(yaml_files=["config.yml"]) + + 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, + ) + +Make sure the app is running: .. code-block:: bash - adev runserver giphynavigator/application.py --livereload + python -m giphynavigator.application and make a request to the API in the terminal: .. code-block:: bash - http http://localhost:8000/ query=="wow,it works" limit==5 + http http://0.0.0.0:8080/ query=="wow,it works" limit==5 You should see: @@ -605,7 +602,7 @@ You should see: Content-Length: 492 Content-Type: application/json; charset=utf-8 Date: Fri, 09 Oct 2020 01:35:48 GMT - Server: Python/3.9 aiohttp/3.6.2 + Server: Python/3.10 aiohttp/3.6.2 { "gifs": [ @@ -810,24 +807,24 @@ You should see: .. code-block:: - platform darwin -- Python 3.9, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 - plugins: cov-2.10.0, aiohttp-0.3.0, asyncio-0.14.0 + platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 + plugins: asyncio-0.16.0, anyio-3.3.4, aiohttp-0.3.0, cov-3.0.0 collected 3 items giphynavigator/tests.py ... [100%] - ---------- coverage: platform darwin, python 3.9 ----------- + ---------- coverage: platform darwin, python 3.10.0-final-0 ---------- Name Stmts Miss Cover --------------------------------------------------- giphynavigator/__init__.py 0 0 100% - giphynavigator/application.py 12 0 100% - giphynavigator/containers.py 6 0 100% + giphynavigator/application.py 13 2 85% + giphynavigator/containers.py 7 0 100% giphynavigator/giphy.py 14 9 36% giphynavigator/handlers.py 10 0 100% giphynavigator/services.py 9 1 89% giphynavigator/tests.py 37 0 100% --------------------------------------------------- - TOTAL 88 10 89% + TOTAL 90 12 87% .. note:: diff --git a/examples/miniapps/aiohttp/README.rst b/examples/miniapps/aiohttp/README.rst index 962812f8..10464017 100644 --- a/examples/miniapps/aiohttp/README.rst +++ b/examples/miniapps/aiohttp/README.rst @@ -27,16 +27,16 @@ To run the application do: .. code-block:: bash export GIPHY_API_KEY=wBJ2wZG7SRqfrU9nPgPiWvORmloDyuL0 - adev runserver giphynavigator/application.py --livereload + python -m giphynavigator.application The output should be something like: .. code-block:: - [18:52:59] Starting aux server at http://localhost:8001 ◆ - [18:52:59] Starting dev server at http://localhost:8000 ● + ======== Running on http://0.0.0.0:8080 ======== + (Press CTRL+C to quit) -After that visit http://127.0.0.1:8000/ in your browser or use CLI command (``curl``, ``httpie``, +After that visit http://0.0.0.0:8080/ in your browser or use CLI command (``curl``, ``httpie``, etc). You should see something like: .. code-block:: json @@ -98,21 +98,21 @@ The output should be something like: .. code-block:: - platform darwin -- Python 3.9, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 - plugins: cov-2.10.0, aiohttp-0.3.0, asyncio-0.14.0 + platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 + plugins: asyncio-0.16.0, anyio-3.3.4, aiohttp-0.3.0, cov-3.0.0 collected 3 items giphynavigator/tests.py ... [100%] - ---------- coverage: platform darwin, python 3.9 ----------- + ---------- coverage: platform darwin, python 3.10.0-final-0 ---------- Name Stmts Miss Cover --------------------------------------------------- giphynavigator/__init__.py 0 0 100% - giphynavigator/application.py 12 0 100% - giphynavigator/containers.py 6 0 100% + giphynavigator/application.py 13 2 85% + giphynavigator/containers.py 7 0 100% giphynavigator/giphy.py 14 9 36% giphynavigator/handlers.py 10 0 100% giphynavigator/services.py 9 1 89% giphynavigator/tests.py 37 0 100% --------------------------------------------------- - TOTAL 88 10 89% + TOTAL 90 12 87% diff --git a/examples/miniapps/aiohttp/giphynavigator/application.py b/examples/miniapps/aiohttp/giphynavigator/application.py index 36b18c93..3ad404cf 100644 --- a/examples/miniapps/aiohttp/giphynavigator/application.py +++ b/examples/miniapps/aiohttp/giphynavigator/application.py @@ -8,9 +8,7 @@ from . import handlers def create_app() -> web.Application: container = Container() - container.config.from_yaml("config.yml") container.config.giphy.api_key.from_env("GIPHY_API_KEY") - container.wire(modules=[handlers]) app = web.Application() app.container = container @@ -18,3 +16,8 @@ def create_app() -> web.Application: web.get("/", handlers.index), ]) return app + + +if __name__ == "__main__": + app = create_app() + web.run_app(app) diff --git a/examples/miniapps/aiohttp/giphynavigator/containers.py b/examples/miniapps/aiohttp/giphynavigator/containers.py index 730c162e..19dc5de7 100644 --- a/examples/miniapps/aiohttp/giphynavigator/containers.py +++ b/examples/miniapps/aiohttp/giphynavigator/containers.py @@ -7,7 +7,9 @@ from . import giphy, services class Container(containers.DeclarativeContainer): - config = providers.Configuration() + wiring_config = containers.WiringConfiguration(modules=[".handlers"]) + + config = providers.Configuration(yaml_files=["config.yml"]) giphy_client = providers.Factory( giphy.GiphyClient, diff --git a/examples/miniapps/aiohttp/requirements.txt b/examples/miniapps/aiohttp/requirements.txt index e849f0dc..e84f6b89 100644 --- a/examples/miniapps/aiohttp/requirements.txt +++ b/examples/miniapps/aiohttp/requirements.txt @@ -1,6 +1,5 @@ dependency-injector aiohttp -aiohttp-devtools pyyaml pytest-aiohttp pytest-cov