mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-25 02:53:56 +03:00
Update examples to use config __init__ args (#527)
* Update application-single-container example * Update application-multiple-containers example * Update decoupled-packages example * Update movie lister example * Update CLI tutorial * Update sanic example * Update sanic example with wiring_config * Update fastapi example * Update fastapi-simple example * Update fastapi-sqlalchemy example * Update flask-blueprints example * Update flask example and tutorial * Update aiohttp example and tutorial * Update asyncio-daemon example and tutorial
This commit is contained in:
parent
6030950596
commit
fe01ad41d9
|
@ -127,8 +127,6 @@ Now it's time to install the project requirements. We will use next packages:
|
||||||
|
|
||||||
- ``dependency-injector`` - the dependency injection framework
|
- ``dependency-injector`` - the dependency injection framework
|
||||||
- ``aiohttp`` - the web 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
|
- ``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-aiohttp`` - the helper library for the testing of the ``aiohttp`` application
|
||||||
- ``pytest-cov`` - the helper library for measuring the test coverage
|
- ``pytest-cov`` - the helper library for measuring the test coverage
|
||||||
|
@ -139,7 +137,6 @@ Put next lines into the ``requirements.txt`` file:
|
||||||
|
|
||||||
dependency-injector
|
dependency-injector
|
||||||
aiohttp
|
aiohttp
|
||||||
aiohttp-devtools
|
|
||||||
pyyaml
|
pyyaml
|
||||||
pytest-aiohttp
|
pytest-aiohttp
|
||||||
pytest-cov
|
pytest-cov
|
||||||
|
@ -232,26 +229,31 @@ Put next into the ``application.py``:
|
||||||
])
|
])
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = create_app()
|
||||||
|
web.run_app(app)
|
||||||
|
|
||||||
Now we're ready to run our application
|
Now we're ready to run our application
|
||||||
|
|
||||||
Do next in the terminal:
|
Do next in the terminal:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
adev runserver giphynavigator/application.py --livereload
|
python -m giphynavigator.application
|
||||||
|
|
||||||
The output should be something like:
|
The output should be something like:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
[18:52:59] Starting aux server at http://localhost:8001 ◆
|
======== Running on http://0.0.0.0:8080 ========
|
||||||
[18:52:59] Starting dev server at http://localhost:8000 ●
|
(Press CTRL+C to quit)
|
||||||
|
|
||||||
Let's check that it works. Open another terminal session and use ``httpie``:
|
Let's check that it works. Open another terminal session and use ``httpie``:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
http http://127.0.0.1:8000/
|
http http://0.0.0.0:8080/
|
||||||
|
|
||||||
You should see:
|
You should see:
|
||||||
|
|
||||||
|
@ -261,7 +263,7 @@ You should see:
|
||||||
Content-Length: 844
|
Content-Length: 844
|
||||||
Content-Type: application/json; charset=utf-8
|
Content-Type: application/json; charset=utf-8
|
||||||
Date: Wed, 29 Jul 2020 21:01:50 GMT
|
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": [],
|
"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
|
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:
|
providers from the ``dependency_injector.providers`` module:
|
||||||
|
|
||||||
- ``Factory`` provider that will create the ``GiphyClient`` client.
|
- ``Factory`` provider. It will create a ``GiphyClient`` client.
|
||||||
- ``Configuration`` provider that will provide the API key and the request timeout.
|
- ``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``:
|
Edit ``containers.py``:
|
||||||
|
|
||||||
|
@ -345,7 +349,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
giphy_client = providers.Factory(
|
giphy_client = providers.Factory(
|
||||||
giphy.GiphyClient,
|
giphy.GiphyClient,
|
||||||
|
@ -353,18 +357,8 @@ Edit ``containers.py``:
|
||||||
timeout=config.giphy.request_timeout,
|
timeout=config.giphy.request_timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
.. note::
|
Now let's add the configuration file. We will use YAML. Create an empty file ``config.yml`` in
|
||||||
|
the root root of the project:
|
||||||
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:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
:emphasize-lines: 9
|
:emphasize-lines: 9
|
||||||
|
@ -387,17 +381,14 @@ and put next into it:
|
||||||
giphy:
|
giphy:
|
||||||
request_timeout: 10
|
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:
|
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.
|
||||||
- Load the configuration file the ``config.yml``.
|
|
||||||
- Load the API key from the ``GIPHY_API_KEY`` environment variable.
|
|
||||||
|
|
||||||
Edit ``application.py``:
|
Edit ``application.py``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 11-12
|
:emphasize-lines: 11
|
||||||
|
|
||||||
"""Application module."""
|
"""Application module."""
|
||||||
|
|
||||||
|
@ -409,7 +400,6 @@ Edit ``application.py``:
|
||||||
|
|
||||||
def create_app() -> web.Application:
|
def create_app() -> web.Application:
|
||||||
container = Container()
|
container = Container()
|
||||||
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")
|
||||||
|
|
||||||
app = web.Application()
|
app = web.Application()
|
||||||
|
@ -420,6 +410,10 @@ Edit ``application.py``:
|
||||||
return app
|
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.
|
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:
|
As for now, don’t worry, just take this one:
|
||||||
|
@ -502,7 +496,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
giphy_client = providers.Factory(
|
giphy_client = providers.Factory(
|
||||||
giphy.GiphyClient,
|
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.
|
To make the injection work we need to wire the container with the ``handlers`` module.
|
||||||
This needs to be done once. After it's done we can use ``Provide`` markers to specify as many
|
Let's configure the container to automatically make wiring with the ``handlers`` module when we
|
||||||
injections as needed for any handler.
|
create a container instance.
|
||||||
|
|
||||||
Edit ``application.py``:
|
Edit ``containers.py``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. 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 giphy, services
|
||||||
from . import handlers
|
|
||||||
|
|
||||||
|
|
||||||
def create_app() -> web.Application:
|
class Container(containers.DeclarativeContainer):
|
||||||
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()
|
wiring_config = containers.WiringConfiguration(modules=[".handlers"])
|
||||||
app.container = container
|
|
||||||
app.add_routes([
|
|
||||||
web.get("/", handlers.index),
|
|
||||||
])
|
|
||||||
return app
|
|
||||||
|
|
||||||
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
|
.. code-block:: bash
|
||||||
|
|
||||||
adev runserver giphynavigator/application.py --livereload
|
python -m giphynavigator.application
|
||||||
|
|
||||||
and make a request to the API in the terminal:
|
and make a request to the API in the terminal:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. 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:
|
You should see:
|
||||||
|
|
||||||
|
@ -605,7 +602,7 @@ You should see:
|
||||||
Content-Length: 492
|
Content-Length: 492
|
||||||
Content-Type: application/json; charset=utf-8
|
Content-Type: application/json; charset=utf-8
|
||||||
Date: Fri, 09 Oct 2020 01:35:48 GMT
|
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": [
|
"gifs": [
|
||||||
|
@ -810,24 +807,24 @@ You should see:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
platform darwin -- Python 3.9, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
|
platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
plugins: cov-2.10.0, aiohttp-0.3.0, asyncio-0.14.0
|
plugins: asyncio-0.16.0, anyio-3.3.4, aiohttp-0.3.0, cov-3.0.0
|
||||||
collected 3 items
|
collected 3 items
|
||||||
|
|
||||||
giphynavigator/tests.py ... [100%]
|
giphynavigator/tests.py ... [100%]
|
||||||
|
|
||||||
---------- coverage: platform darwin, python 3.9 -----------
|
---------- coverage: platform darwin, python 3.10.0-final-0 ----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
giphynavigator/__init__.py 0 0 100%
|
giphynavigator/__init__.py 0 0 100%
|
||||||
giphynavigator/application.py 12 0 100%
|
giphynavigator/application.py 13 2 85%
|
||||||
giphynavigator/containers.py 6 0 100%
|
giphynavigator/containers.py 7 0 100%
|
||||||
giphynavigator/giphy.py 14 9 36%
|
giphynavigator/giphy.py 14 9 36%
|
||||||
giphynavigator/handlers.py 10 0 100%
|
giphynavigator/handlers.py 10 0 100%
|
||||||
giphynavigator/services.py 9 1 89%
|
giphynavigator/services.py 9 1 89%
|
||||||
giphynavigator/tests.py 37 0 100%
|
giphynavigator/tests.py 37 0 100%
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
TOTAL 88 10 89%
|
TOTAL 90 12 87%
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ Put next lines into the ``Dockerfile`` file:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
FROM python:3.9-buster
|
FROM python:3.10-buster
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
@ -204,11 +204,11 @@ Logging and configuration
|
||||||
|
|
||||||
In this section we will configure the logging and configuration file parsing.
|
In this section we will configure the logging and configuration file parsing.
|
||||||
|
|
||||||
Let's start with the the main part of our application - the container. Container will keep all of
|
Let's start with the the main part of our application – the container. Container will keep all of
|
||||||
the application components and their dependencies.
|
the application components and their dependencies.
|
||||||
|
|
||||||
First two components that we're going to add are the config object and the provider for
|
First two components that we're going to add are the configuration provider and the resource provider
|
||||||
configuring the logging.
|
for configuring the logging.
|
||||||
|
|
||||||
Put next lines into the ``containers.py`` file:
|
Put next lines into the ``containers.py`` file:
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ Put next lines into the ``containers.py`` file:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
logging = providers.Resource(
|
logging = providers.Resource(
|
||||||
logging.basicConfig,
|
logging.basicConfig,
|
||||||
|
@ -233,16 +233,7 @@ Put next lines into the ``containers.py`` file:
|
||||||
format=config.log.format,
|
format=config.log.format,
|
||||||
)
|
)
|
||||||
|
|
||||||
.. note::
|
The configuration file will keep the logging settings. Put next lines into the ``config.yml`` file:
|
||||||
|
|
||||||
We have used the configuration value before it was defined. That's the principle how the
|
|
||||||
``Configuration`` provider works.
|
|
||||||
|
|
||||||
Use first, define later.
|
|
||||||
|
|
||||||
The configuration file will keep the logging settings.
|
|
||||||
|
|
||||||
Put next lines into the ``config.yml`` file:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
@ -250,9 +241,10 @@ Put next lines into the ``config.yml`` file:
|
||||||
level: "INFO"
|
level: "INFO"
|
||||||
format: "[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s"
|
format: "[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s"
|
||||||
|
|
||||||
Now let's create the function that will run our daemon. It's traditionally called
|
Now let's create the function that will run our daemon. It's traditionally called ``main()``.
|
||||||
``main()``. The ``main()`` function will create the container. Then it will use the container
|
The ``main()`` function will start the dispatcher, but we will keep it empty for now.
|
||||||
to parse the ``config.yml`` file and call the logging configuration provider.
|
We will create the container instance before calling ``main()`` in ``if __name__ == "__main__"``.
|
||||||
|
Container instance will parse ``config.yml`` and then we will call the logging configuration provider.
|
||||||
|
|
||||||
Put next lines into the ``__main__.py`` file:
|
Put next lines into the ``__main__.py`` file:
|
||||||
|
|
||||||
|
@ -269,7 +261,6 @@ Put next lines into the ``__main__.py`` file:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.init_resources()
|
container.init_resources()
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
@ -419,7 +410,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
logging = providers.Resource(
|
logging = providers.Resource(
|
||||||
logging.basicConfig,
|
logging.basicConfig,
|
||||||
|
@ -442,7 +433,7 @@ and call the ``run()`` method. We will use :ref:`wiring` feature.
|
||||||
Edit ``__main__.py``:
|
Edit ``__main__.py``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 3-5,9-11,18
|
:emphasize-lines: 3-5,9-11,17
|
||||||
|
|
||||||
"""Main module."""
|
"""Main module."""
|
||||||
|
|
||||||
|
@ -459,7 +450,6 @@ Edit ``__main__.py``:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.init_resources()
|
container.init_resources()
|
||||||
container.wire(modules=[__name__])
|
container.wire(modules=[__name__])
|
||||||
|
|
||||||
|
@ -559,7 +549,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
logging = providers.Resource(
|
logging = providers.Resource(
|
||||||
logging.basicConfig,
|
logging.basicConfig,
|
||||||
|
@ -664,7 +654,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
logging = providers.Resource(
|
logging = providers.Resource(
|
||||||
logging.basicConfig,
|
logging.basicConfig,
|
||||||
|
@ -763,7 +753,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
logging = providers.Resource(
|
logging = providers.Resource(
|
||||||
logging.basicConfig,
|
logging.basicConfig,
|
||||||
|
@ -888,7 +878,7 @@ Create ``tests.py`` in the ``monitoringdaemon`` package:
|
||||||
and put next into it:
|
and put next into it:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 54,70-71
|
:emphasize-lines: 54,70-73
|
||||||
|
|
||||||
"""Tests module."""
|
"""Tests module."""
|
||||||
|
|
||||||
|
@ -909,28 +899,28 @@ and put next into it:
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def container():
|
def container():
|
||||||
container = Container()
|
return Container(
|
||||||
container.config.from_dict({
|
config={
|
||||||
"log": {
|
"log": {
|
||||||
"level": "INFO",
|
"level": "INFO",
|
||||||
"formant": "[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s",
|
"formant": "[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s",
|
||||||
},
|
|
||||||
"monitors": {
|
|
||||||
"example": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "http://fake-example.com",
|
|
||||||
"timeout": 1,
|
|
||||||
"check_every": 1,
|
|
||||||
},
|
},
|
||||||
"httpbin": {
|
"monitors": {
|
||||||
"method": "GET",
|
"example": {
|
||||||
"url": "https://fake-httpbin.org/get",
|
"method": "GET",
|
||||||
"timeout": 1,
|
"url": "http://fake-example.com",
|
||||||
"check_every": 1,
|
"timeout": 1,
|
||||||
|
"check_every": 1,
|
||||||
|
},
|
||||||
|
"httpbin": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "https://fake-httpbin.org/get",
|
||||||
|
"timeout": 1,
|
||||||
|
"check_every": 1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
})
|
)
|
||||||
return container
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
@ -959,9 +949,10 @@ and put next into it:
|
||||||
example_monitor_mock = mock.AsyncMock()
|
example_monitor_mock = mock.AsyncMock()
|
||||||
httpbin_monitor_mock = mock.AsyncMock()
|
httpbin_monitor_mock = mock.AsyncMock()
|
||||||
|
|
||||||
with container.example_monitor.override(example_monitor_mock), \
|
with container.override_providers(
|
||||||
container.httpbin_monitor.override(httpbin_monitor_mock):
|
example_monitor=example_monitor_mock,
|
||||||
|
httpbin_monitor=httpbin_monitor_mock,
|
||||||
|
):
|
||||||
dispatcher = container.dispatcher()
|
dispatcher = container.dispatcher()
|
||||||
event_loop.create_task(dispatcher.start())
|
event_loop.create_task(dispatcher.start())
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
|
@ -980,25 +971,25 @@ You should see:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
platform linux -- Python 3.9, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
|
platform linux -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
rootdir: /code
|
rootdir: /code
|
||||||
plugins: asyncio-0.14.0, cov-2.10.0
|
plugins: asyncio-0.16.0, cov-3.0.0
|
||||||
collected 2 items
|
collected 2 items
|
||||||
|
|
||||||
monitoringdaemon/tests.py .. [100%]
|
monitoringdaemon/tests.py .. [100%]
|
||||||
|
|
||||||
----------- coverage: platform linux, python 3.9 -----------
|
---------- coverage: platform linux, python 3.10.0-final-0 -----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
monitoringdaemon/__init__.py 0 0 100%
|
monitoringdaemon/__init__.py 0 0 100%
|
||||||
monitoringdaemon/__main__.py 13 13 0%
|
monitoringdaemon/__main__.py 11 11 0%
|
||||||
monitoringdaemon/containers.py 11 0 100%
|
monitoringdaemon/containers.py 11 0 100%
|
||||||
monitoringdaemon/dispatcher.py 44 5 89%
|
monitoringdaemon/dispatcher.py 45 5 89%
|
||||||
monitoringdaemon/http.py 6 3 50%
|
monitoringdaemon/http.py 6 3 50%
|
||||||
monitoringdaemon/monitors.py 23 1 96%
|
monitoringdaemon/monitors.py 23 1 96%
|
||||||
monitoringdaemon/tests.py 37 0 100%
|
monitoringdaemon/tests.py 35 0 100%
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
TOTAL 134 22 84%
|
TOTAL 131 20 85%
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
|
@ -428,7 +428,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
movie = providers.Factory(entities.Movie)
|
movie = providers.Factory(entities.Movie)
|
||||||
|
|
||||||
|
@ -445,15 +445,9 @@ This is also called the delegation of the provider. If we just pass the movie fa
|
||||||
as the dependency, it will be called when csv finder is created and the ``Movie`` instance will
|
as the dependency, it will be called when csv finder is created and the ``Movie`` instance will
|
||||||
be injected. With the ``.provider`` attribute the provider itself will be injected.
|
be injected. With the ``.provider`` attribute the provider itself will be injected.
|
||||||
|
|
||||||
The csv finder also has a few dependencies on the configuration options. We added configuration
|
The csv finder also has a few dependencies on the configuration options. We added a configuration
|
||||||
provider to provide these dependencies.
|
provider to provide these dependencies and specified the location of the configuration file.
|
||||||
|
The configuration provider will parse the configuration file when we create a container instance.
|
||||||
.. note::
|
|
||||||
|
|
||||||
We have used the configuration value before it was defined. That's the principle how the
|
|
||||||
Configuration provider works.
|
|
||||||
|
|
||||||
Use first, define later.
|
|
||||||
|
|
||||||
Not let's define the configuration values.
|
Not let's define the configuration values.
|
||||||
|
|
||||||
|
@ -467,29 +461,7 @@ Edit ``config.yml``:
|
||||||
path: "data/movies.csv"
|
path: "data/movies.csv"
|
||||||
delimiter: ","
|
delimiter: ","
|
||||||
|
|
||||||
The configuration file is ready. Now let's update the ``main()`` function to specify its location.
|
The configuration file is ready. Move on to the lister.
|
||||||
|
|
||||||
Edit ``__main__.py``:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
:emphasize-lines: 12
|
|
||||||
|
|
||||||
"""Main module."""
|
|
||||||
|
|
||||||
from .containers import Container
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
container = Container()
|
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|
||||||
Move on to the lister.
|
|
||||||
|
|
||||||
Create the ``listers.py`` in the ``movies`` package:
|
Create the ``listers.py`` in the ``movies`` package:
|
||||||
|
|
||||||
|
@ -552,7 +524,7 @@ and edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
movie = providers.Factory(entities.Movie)
|
movie = providers.Factory(entities.Movie)
|
||||||
|
|
||||||
|
@ -575,7 +547,7 @@ Let's inject the ``lister`` into the ``main()`` function.
|
||||||
Edit ``__main__.py``:
|
Edit ``__main__.py``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 3-5,9-10,17
|
:emphasize-lines: 3-5,9-10,16
|
||||||
|
|
||||||
"""Main module."""
|
"""Main module."""
|
||||||
|
|
||||||
|
@ -592,7 +564,6 @@ Edit ``__main__.py``:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.wire(modules=[__name__])
|
container.wire(modules=[__name__])
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
@ -628,7 +599,6 @@ Edit ``__main__.py``:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.wire(modules=[__name__])
|
container.wire(modules=[__name__])
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
@ -733,7 +703,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
movie = providers.Factory(entities.Movie)
|
movie = providers.Factory(entities.Movie)
|
||||||
|
|
||||||
|
@ -822,7 +792,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
movie = providers.Factory(entities.Movie)
|
movie = providers.Factory(entities.Movie)
|
||||||
|
|
||||||
|
@ -859,7 +829,7 @@ Now we need to read the value of the ``config.finder.type`` option from the envi
|
||||||
Edit ``__main__.py``:
|
Edit ``__main__.py``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 23
|
:emphasize-lines: 22
|
||||||
|
|
||||||
"""Main module."""
|
"""Main module."""
|
||||||
|
|
||||||
|
@ -882,7 +852,6 @@ Edit ``__main__.py``:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.config.finder.type.from_env("MOVIE_FINDER_TYPE")
|
container.config.finder.type.from_env("MOVIE_FINDER_TYPE")
|
||||||
container.wire(modules=[sys.modules[__name__]])
|
container.wire(modules=[sys.modules[__name__]])
|
||||||
|
|
||||||
|
@ -942,7 +911,7 @@ Create ``tests.py`` in the ``movies`` package:
|
||||||
and put next into it:
|
and put next into it:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 35,50
|
:emphasize-lines: 36,51
|
||||||
|
|
||||||
"""Tests module."""
|
"""Tests module."""
|
||||||
|
|
||||||
|
@ -955,19 +924,20 @@ and put next into it:
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def container():
|
def container():
|
||||||
container = Container()
|
container = Container(
|
||||||
container.config.from_dict({
|
config={
|
||||||
"finder": {
|
"finder": {
|
||||||
"type": "csv",
|
"type": "csv",
|
||||||
"csv": {
|
"csv": {
|
||||||
"path": "/fake-movies.csv",
|
"path": "/fake-movies.csv",
|
||||||
"delimiter": ",",
|
"delimiter": ",",
|
||||||
},
|
},
|
||||||
"sqlite": {
|
"sqlite": {
|
||||||
"path": "/fake-movies.db",
|
"path": "/fake-movies.db",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
)
|
||||||
return container
|
return container
|
||||||
|
|
||||||
|
|
||||||
|
@ -1010,24 +980,24 @@ You should see:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
platform darwin -- Python 3.9, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
|
platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
plugins: cov-2.10.0
|
plugins: cov-3.0.0
|
||||||
collected 2 items
|
collected 2 items
|
||||||
|
|
||||||
movies/tests.py .. [100%]
|
movies/tests.py .. [100%]
|
||||||
|
|
||||||
---------- coverage: platform darwin, python 3.9 -----------
|
---------- coverage: platform darwin, python 3.10 -----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
movies/__init__.py 0 0 100%
|
movies/__init__.py 0 0 100%
|
||||||
movies/__main__.py 18 18 0%
|
movies/__main__.py 16 16 0%
|
||||||
movies/containers.py 9 0 100%
|
movies/containers.py 9 0 100%
|
||||||
movies/entities.py 7 1 86%
|
movies/entities.py 7 1 86%
|
||||||
movies/finders.py 26 13 50%
|
movies/finders.py 26 13 50%
|
||||||
movies/listers.py 8 0 100%
|
movies/listers.py 8 0 100%
|
||||||
movies/tests.py 24 0 100%
|
movies/tests.py 23 0 100%
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
TOTAL 92 32 65%
|
TOTAL 89 30 66%
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -1047,7 +1017,7 @@ We've used the ``Dependency Injector`` as a dependency injection framework.
|
||||||
With a help of :ref:`containers` and :ref:`providers` we have defined how to assemble application components.
|
With a help of :ref:`containers` and :ref:`providers` we have defined how to assemble application components.
|
||||||
|
|
||||||
``Selector`` provider served as a switch for selecting the database format based on a configuration.
|
``Selector`` provider served as a switch for selecting the database format based on a configuration.
|
||||||
:ref:`configuration-provider` helped to deal with reading YAML file and environment variable.
|
:ref:`configuration-provider` helped to deal with reading a YAML file and environment variables.
|
||||||
|
|
||||||
We used :ref:`wiring` feature to inject the dependencies into the ``main()`` function.
|
We used :ref:`wiring` feature to inject the dependencies into the ``main()`` function.
|
||||||
:ref:`provider-overriding` feature helped in testing.
|
:ref:`provider-overriding` feature helped in testing.
|
||||||
|
|
|
@ -112,7 +112,7 @@ You should see something like:
|
||||||
(venv) $ python -c "import dependency_injector; print(dependency_injector.__version__)"
|
(venv) $ python -c "import dependency_injector; print(dependency_injector.__version__)"
|
||||||
4.37.0
|
4.37.0
|
||||||
(venv) $ python -c "import flask; print(flask.__version__)"
|
(venv) $ python -c "import flask; print(flask.__version__)"
|
||||||
1.1.2
|
2.0.2
|
||||||
|
|
||||||
*Versions can be different. That's fine.*
|
*Versions can be different. That's fine.*
|
||||||
|
|
||||||
|
@ -444,9 +444,10 @@ and run in the terminal:
|
||||||
Now we need to add Github API client the container. We will need to add two more providers from
|
Now we need to add Github API client the container. We will need to add two more providers from
|
||||||
the ``dependency_injector.providers`` module:
|
the ``dependency_injector.providers`` module:
|
||||||
|
|
||||||
- ``Factory`` provider that will create ``Github`` client.
|
- ``Factory`` provider. It will create a ``Github`` client.
|
||||||
- ``Configuration`` provider that will be used for providing the API token and the request timeout
|
- ``Configuration`` provider. It will provide an API token and a request timeout for the ``Github`` client.
|
||||||
for the ``Github`` 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``:
|
Edit ``containers.py``:
|
||||||
|
|
||||||
|
@ -461,7 +462,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
github_client = providers.Factory(
|
github_client = providers.Factory(
|
||||||
Github,
|
Github,
|
||||||
|
@ -469,23 +470,14 @@ Edit ``containers.py``:
|
||||||
timeout=config.github.request_timeout,
|
timeout=config.github.request_timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
We have used the configuration value before it was defined. That's the principle how
|
|
||||||
``Configuration`` provider works.
|
|
||||||
|
|
||||||
Use first, define later.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Don't forget to remove the Ellipsis ``...`` from the container. We don't need it anymore
|
Don't forget to remove the Ellipsis ``...`` from the container. We don't need it anymore
|
||||||
since we container is not empty.
|
since we container is not empty.
|
||||||
|
|
||||||
Now let's add the configuration file.
|
Now let's add the configuration file. We will use YAML. Create an empty file ``config.yml``
|
||||||
|
in the root of the project:
|
||||||
We will use YAML.
|
|
||||||
|
|
||||||
Create an empty file ``config.yml`` in the root of the project:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
:emphasize-lines: 11
|
:emphasize-lines: 11
|
||||||
|
@ -530,17 +522,13 @@ and install it:
|
||||||
|
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
|
||||||
We will use environment variable ``GITHUB_TOKEN`` to provide the API token.
|
We will use the ``GITHUB_TOKEN`` environment variable to provide the API token. Let's edit
|
||||||
|
``create_app()`` to fetch the token value from it.
|
||||||
Now we need to edit ``create_app()`` to make two things when application starts:
|
|
||||||
|
|
||||||
- Load the configuration file the ``config.yml``.
|
|
||||||
- Load the API token from the ``GITHUB_TOKEN`` environment variable.
|
|
||||||
|
|
||||||
Edit ``application.py``:
|
Edit ``application.py``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 12-13
|
:emphasize-lines: 12
|
||||||
|
|
||||||
"""Application module."""
|
"""Application module."""
|
||||||
|
|
||||||
|
@ -553,7 +541,6 @@ Edit ``application.py``:
|
||||||
|
|
||||||
def create_app() -> Flask:
|
def create_app() -> Flask:
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.config.github.auth_token.from_env("GITHUB_TOKEN")
|
container.config.github.auth_token.from_env("GITHUB_TOKEN")
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
@ -684,7 +671,7 @@ Edit ``containers.py``:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
github_client = providers.Factory(
|
github_client = providers.Factory(
|
||||||
Github,
|
Github,
|
||||||
|
@ -732,38 +719,39 @@ Edit ``views.py``:
|
||||||
repositories=repositories,
|
repositories=repositories,
|
||||||
)
|
)
|
||||||
|
|
||||||
To make the injection work we need to wire the container instance with the ``views`` module.
|
To make the injection work we need to wire the container with the ``views`` module.
|
||||||
This needs to be done once. After it's done we can use ``Provide`` markers to specify as many
|
Let's configure the container to automatically make wiring with the ``views`` module when we
|
||||||
injections as needed for any view.
|
create a container instance.
|
||||||
|
|
||||||
Edit ``application.py``:
|
Edit ``containers.py``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 14
|
:emphasize-lines: 11
|
||||||
|
|
||||||
"""Application module."""
|
"""Containers module."""
|
||||||
|
|
||||||
from flask import Flask
|
from dependency_injector import containers, providers
|
||||||
from flask_bootstrap import Bootstrap
|
from github import Github
|
||||||
|
|
||||||
from .containers import Container
|
from . import services
|
||||||
from . import views
|
|
||||||
|
|
||||||
|
|
||||||
def create_app() -> Flask:
|
class Container(containers.DeclarativeContainer):
|
||||||
container = Container()
|
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.config.github.auth_token.from_env("GITHUB_TOKEN")
|
|
||||||
container.wire(modules=[views])
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
wiring_config = containers.WiringConfiguration(modules=[".views"])
|
||||||
app.container = container
|
|
||||||
app.add_url_rule("/", "index", views.index)
|
|
||||||
|
|
||||||
bootstrap = Bootstrap()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
bootstrap.init_app(app)
|
|
||||||
|
|
||||||
return app
|
github_client = providers.Factory(
|
||||||
|
Github,
|
||||||
|
login_or_token=config.github.auth_token,
|
||||||
|
timeout=config.github.request_timeout,
|
||||||
|
)
|
||||||
|
|
||||||
|
search_service = providers.Factory(
|
||||||
|
services.SearchService,
|
||||||
|
github_client=github_client,
|
||||||
|
)
|
||||||
|
|
||||||
Make sure the app is running or use ``flask run`` and open ``http://127.0.0.1:5000/``.
|
Make sure the app is running or use ``flask run`` and open ``http://127.0.0.1:5000/``.
|
||||||
|
|
||||||
|
@ -960,23 +948,23 @@ You should see:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
platform darwin -- Python 3.9, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
|
platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
plugins: flask-1.0.0, cov-2.10.0
|
plugins: cov-3.0.0, flask-1.2.0
|
||||||
collected 2 items
|
collected 2 items
|
||||||
|
|
||||||
githubnavigator/tests.py .. [100%]
|
githubnavigator/tests.py .. [100%]
|
||||||
|
|
||||||
---------- coverage: platform darwin, python 3.9 -----------
|
---------- coverage: platform darwin, python 3.10.0-final-0 ----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
githubnavigator/__init__.py 0 0 100%
|
githubnavigator/__init__.py 0 0 100%
|
||||||
githubnavigator/application.py 15 0 100%
|
githubnavigator/application.py 13 0 100%
|
||||||
githubnavigator/containers.py 7 0 100%
|
githubnavigator/containers.py 8 0 100%
|
||||||
githubnavigator/services.py 14 0 100%
|
githubnavigator/services.py 14 0 100%
|
||||||
githubnavigator/tests.py 34 0 100%
|
githubnavigator/tests.py 34 0 100%
|
||||||
githubnavigator/views.py 10 0 100%
|
githubnavigator/views.py 10 0 100%
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
TOTAL 80 0 100%
|
TOTAL 79 0 100%
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,16 @@ To run the application do:
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
export GIPHY_API_KEY=wBJ2wZG7SRqfrU9nPgPiWvORmloDyuL0
|
export GIPHY_API_KEY=wBJ2wZG7SRqfrU9nPgPiWvORmloDyuL0
|
||||||
adev runserver giphynavigator/application.py --livereload
|
python -m giphynavigator.application
|
||||||
|
|
||||||
The output should be something like:
|
The output should be something like:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
[18:52:59] Starting aux server at http://localhost:8001 ◆
|
======== Running on http://0.0.0.0:8080 ========
|
||||||
[18:52:59] Starting dev server at http://localhost:8000 ●
|
(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:
|
etc). You should see something like:
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
@ -98,21 +98,21 @@ The output should be something like:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
platform darwin -- Python 3.9, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
|
platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
plugins: cov-2.10.0, aiohttp-0.3.0, asyncio-0.14.0
|
plugins: asyncio-0.16.0, anyio-3.3.4, aiohttp-0.3.0, cov-3.0.0
|
||||||
collected 3 items
|
collected 3 items
|
||||||
|
|
||||||
giphynavigator/tests.py ... [100%]
|
giphynavigator/tests.py ... [100%]
|
||||||
|
|
||||||
---------- coverage: platform darwin, python 3.9 -----------
|
---------- coverage: platform darwin, python 3.10.0-final-0 ----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
giphynavigator/__init__.py 0 0 100%
|
giphynavigator/__init__.py 0 0 100%
|
||||||
giphynavigator/application.py 12 0 100%
|
giphynavigator/application.py 13 2 85%
|
||||||
giphynavigator/containers.py 6 0 100%
|
giphynavigator/containers.py 7 0 100%
|
||||||
giphynavigator/giphy.py 14 9 36%
|
giphynavigator/giphy.py 14 9 36%
|
||||||
giphynavigator/handlers.py 10 0 100%
|
giphynavigator/handlers.py 10 0 100%
|
||||||
giphynavigator/services.py 9 1 89%
|
giphynavigator/services.py 9 1 89%
|
||||||
giphynavigator/tests.py 37 0 100%
|
giphynavigator/tests.py 37 0 100%
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
TOTAL 88 10 89%
|
TOTAL 90 12 87%
|
||||||
|
|
|
@ -8,9 +8,7 @@ from . import handlers
|
||||||
|
|
||||||
def create_app() -> web.Application:
|
def create_app() -> web.Application:
|
||||||
container = Container()
|
container = Container()
|
||||||
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])
|
|
||||||
|
|
||||||
app = web.Application()
|
app = web.Application()
|
||||||
app.container = container
|
app.container = container
|
||||||
|
@ -18,3 +16,8 @@ def create_app() -> web.Application:
|
||||||
web.get("/", handlers.index),
|
web.get("/", handlers.index),
|
||||||
])
|
])
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = create_app()
|
||||||
|
web.run_app(app)
|
||||||
|
|
|
@ -7,7 +7,9 @@ from . import giphy, services
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
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_client = providers.Factory(
|
||||||
giphy.GiphyClient,
|
giphy.GiphyClient,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
dependency-injector
|
dependency-injector
|
||||||
aiohttp
|
aiohttp
|
||||||
aiohttp-devtools
|
|
||||||
pyyaml
|
pyyaml
|
||||||
pytest-aiohttp
|
pytest-aiohttp
|
||||||
pytest-cov
|
pytest-cov
|
||||||
|
|
|
@ -24,7 +24,6 @@ def main(
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
application = Application()
|
application = Application()
|
||||||
application.config.from_yaml("config.yml")
|
|
||||||
application.core.init_resources()
|
application.core.init_resources()
|
||||||
application.wire(modules=[__name__])
|
application.wire(modules=[__name__])
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ class Services(containers.DeclarativeContainer):
|
||||||
|
|
||||||
class Application(containers.DeclarativeContainer):
|
class Application(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
core = providers.Container(
|
core = providers.Container(
|
||||||
Core,
|
Core,
|
||||||
|
|
|
@ -25,7 +25,6 @@ def main(
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
container = Container()
|
container = Container()
|
||||||
container.init_resources()
|
container.init_resources()
|
||||||
container.config.from_ini("config.ini")
|
|
||||||
container.wire(modules=[__name__])
|
container.wire(modules=[__name__])
|
||||||
|
|
||||||
main(*sys.argv[1:])
|
main(*sys.argv[1:])
|
||||||
|
|
|
@ -11,7 +11,7 @@ from . import services
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(ini_files=["config.ini"])
|
||||||
|
|
||||||
logging = providers.Resource(
|
logging = providers.Resource(
|
||||||
logging.config.fileConfig,
|
logging.config.fileConfig,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM python:3.9-buster
|
FROM python:3.10-buster
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
|
|
@ -65,22 +65,22 @@ The output should be something like:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
platform linux -- Python 3.9, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
|
platform linux -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
rootdir: /code
|
rootdir: /code
|
||||||
plugins: asyncio-0.14.0, cov-2.10.0
|
plugins: asyncio-0.16.0, cov-3.0.0
|
||||||
collected 2 items
|
collected 2 items
|
||||||
|
|
||||||
monitoringdaemon/tests.py .. [100%]
|
monitoringdaemon/tests.py .. [100%]
|
||||||
|
|
||||||
----------- coverage: platform linux, python 3.9 -----------
|
---------- coverage: platform linux, python 3.10.0-final-0 -----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
monitoringdaemon/__init__.py 0 0 100%
|
monitoringdaemon/__init__.py 0 0 100%
|
||||||
monitoringdaemon/__main__.py 13 13 0%
|
monitoringdaemon/__main__.py 11 11 0%
|
||||||
monitoringdaemon/containers.py 11 0 100%
|
monitoringdaemon/containers.py 11 0 100%
|
||||||
monitoringdaemon/dispatcher.py 44 5 89%
|
monitoringdaemon/dispatcher.py 45 5 89%
|
||||||
monitoringdaemon/http.py 6 3 50%
|
monitoringdaemon/http.py 6 3 50%
|
||||||
monitoringdaemon/monitors.py 23 1 96%
|
monitoringdaemon/monitors.py 23 1 96%
|
||||||
monitoringdaemon/tests.py 37 0 100%
|
monitoringdaemon/tests.py 35 0 100%
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
TOTAL 134 22 84%
|
TOTAL 131 20 85%
|
||||||
|
|
|
@ -13,7 +13,6 @@ def main(dispatcher: Dispatcher = Provide[Container.dispatcher]) -> None:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.init_resources()
|
container.init_resources()
|
||||||
container.wire(modules=[__name__])
|
container.wire(modules=[__name__])
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ from . import http, monitors, dispatcher
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
logging = providers.Resource(
|
logging = providers.Resource(
|
||||||
logging.basicConfig,
|
logging.basicConfig,
|
||||||
|
|
|
@ -17,28 +17,28 @@ class RequestStub:
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def container():
|
def container():
|
||||||
container = Container()
|
return Container(
|
||||||
container.config.from_dict({
|
config={
|
||||||
"log": {
|
"log": {
|
||||||
"level": "INFO",
|
"level": "INFO",
|
||||||
"formant": "[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s",
|
"formant": "[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s",
|
||||||
},
|
|
||||||
"monitors": {
|
|
||||||
"example": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "http://fake-example.com",
|
|
||||||
"timeout": 1,
|
|
||||||
"check_every": 1,
|
|
||||||
},
|
},
|
||||||
"httpbin": {
|
"monitors": {
|
||||||
"method": "GET",
|
"example": {
|
||||||
"url": "https://fake-httpbin.org/get",
|
"method": "GET",
|
||||||
"timeout": 1,
|
"url": "http://fake-example.com",
|
||||||
"check_every": 1,
|
"timeout": 1,
|
||||||
|
"check_every": 1,
|
||||||
|
},
|
||||||
|
"httpbin": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "https://fake-httpbin.org/get",
|
||||||
|
"timeout": 1,
|
||||||
|
"check_every": 1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
})
|
)
|
||||||
return container
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
@ -67,9 +67,10 @@ async def test_dispatcher(container, caplog, event_loop):
|
||||||
example_monitor_mock = mock.AsyncMock()
|
example_monitor_mock = mock.AsyncMock()
|
||||||
httpbin_monitor_mock = mock.AsyncMock()
|
httpbin_monitor_mock = mock.AsyncMock()
|
||||||
|
|
||||||
with container.example_monitor.override(example_monitor_mock), \
|
with container.override_providers(
|
||||||
container.httpbin_monitor.override(httpbin_monitor_mock):
|
example_monitor=example_monitor_mock,
|
||||||
|
httpbin_monitor=httpbin_monitor_mock,
|
||||||
|
):
|
||||||
dispatcher = container.dispatcher()
|
dispatcher = container.dispatcher()
|
||||||
event_loop.create_task(dispatcher.start())
|
event_loop.create_task(dispatcher.start())
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
|
|
|
@ -35,7 +35,6 @@ def main(
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
application = ApplicationContainer()
|
application = ApplicationContainer()
|
||||||
application.config.from_ini("config.ini")
|
|
||||||
application.wire(modules=[__name__])
|
application.wire(modules=[__name__])
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -12,7 +12,7 @@ from .analytics.containers import AnalyticsContainer
|
||||||
|
|
||||||
class ApplicationContainer(containers.DeclarativeContainer):
|
class ApplicationContainer(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(ini_files=["config.ini"])
|
||||||
|
|
||||||
sqlite = providers.Singleton(sqlite3.connect, config.database.dsn)
|
sqlite = providers.Singleton(sqlite3.connect, config.database.dsn)
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,9 @@ from fastapi_di_example import app, container, Service
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def client(event_loop):
|
async def client(event_loop):
|
||||||
client = AsyncClient(app=app, base_url="http://test")
|
async with AsyncClient(app=app, base_url="http://test") as client:
|
||||||
yield client
|
yield client
|
||||||
event_loop.run_until_complete(client.aclose())
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM python:3.9-buster
|
FROM python:3.10-buster
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
ENV HOST=0.0.0.0
|
ENV HOST=0.0.0.0
|
||||||
|
|
|
@ -73,19 +73,19 @@ The output should be something like:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
platform linux -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
|
platform linux -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
rootdir: /code
|
rootdir: /code
|
||||||
plugins: cov-2.11.1
|
plugins: cov-3.0.0
|
||||||
collected 7 items
|
collected 7 items
|
||||||
|
|
||||||
webapp/tests.py ....... [100%]
|
webapp/tests.py ....... [100%]
|
||||||
|
|
||||||
----------- coverage: platform linux, python 3.9.1-final-0 -----------
|
---------- coverage: platform linux, python 3.10.0-final-0 ----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
webapp/__init__.py 0 0 100%
|
webapp/__init__.py 0 0 100%
|
||||||
webapp/application.py 14 0 100%
|
webapp/application.py 12 0 100%
|
||||||
webapp/containers.py 9 0 100%
|
webapp/containers.py 10 0 100%
|
||||||
webapp/database.py 24 8 67%
|
webapp/database.py 24 8 67%
|
||||||
webapp/endpoints.py 32 0 100%
|
webapp/endpoints.py 32 0 100%
|
||||||
webapp/models.py 10 1 90%
|
webapp/models.py 10 1 90%
|
||||||
|
@ -93,4 +93,4 @@ The output should be something like:
|
||||||
webapp/services.py 16 0 100%
|
webapp/services.py 16 0 100%
|
||||||
webapp/tests.py 59 0 100%
|
webapp/tests.py 59 0 100%
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
TOTAL 200 29 86%
|
TOTAL 199 29 85%
|
||||||
|
|
|
@ -8,8 +8,6 @@ from . import endpoints
|
||||||
|
|
||||||
def create_app() -> FastAPI:
|
def create_app() -> FastAPI:
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.wire(modules=[endpoints])
|
|
||||||
|
|
||||||
db = container.db()
|
db = container.db()
|
||||||
db.create_database()
|
db.create_database()
|
||||||
|
|
|
@ -9,7 +9,9 @@ from .services import UserService
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
wiring_config = containers.WiringConfiguration(modules=[".endpoints"])
|
||||||
|
|
||||||
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
db = providers.Singleton(Database, db_url=config.db.url)
|
db = providers.Singleton(Database, db_url=config.db.url)
|
||||||
|
|
||||||
|
|
|
@ -101,21 +101,21 @@ The output should be something like:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
platform darwin -- Python 3.9, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
|
platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
plugins: cov-2.10.0, asyncio-0.14.0
|
plugins: asyncio-0.16.0, cov-3.0.0
|
||||||
collected 3 items
|
collected 3 items
|
||||||
|
|
||||||
giphynavigator/tests.py ... [100%]
|
giphynavigator/tests.py ... [100%]
|
||||||
|
|
||||||
---------- coverage: platform darwin, python 3.9 -----------
|
---------- coverage: platform darwin, python 3.10.0-final-0 ----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
giphynavigator/__init__.py 0 0 100%
|
giphynavigator/__init__.py 0 0 100%
|
||||||
giphynavigator/application.py 13 0 100%
|
giphynavigator/application.py 11 0 100%
|
||||||
giphynavigator/containers.py 6 0 100%
|
giphynavigator/containers.py 7 0 100%
|
||||||
giphynavigator/endpoints.py 20 0 100%
|
giphynavigator/endpoints.py 20 0 100%
|
||||||
giphynavigator/giphy.py 14 9 36%
|
giphynavigator/giphy.py 14 9 36%
|
||||||
giphynavigator/services.py 9 1 89%
|
giphynavigator/services.py 9 1 89%
|
||||||
giphynavigator/tests.py 38 0 100%
|
giphynavigator/tests.py 37 0 100%
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
TOTAL 100 10 90%
|
TOTAL 98 10 90%
|
||||||
|
|
|
@ -8,9 +8,7 @@ from . import endpoints
|
||||||
|
|
||||||
def create_app() -> FastAPI:
|
def create_app() -> FastAPI:
|
||||||
container = Container()
|
container = Container()
|
||||||
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=[endpoints])
|
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
app.container = container
|
app.container = container
|
||||||
|
|
|
@ -7,7 +7,9 @@ from . import giphy, services
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
wiring_config = containers.WiringConfiguration(modules=[".endpoints"])
|
||||||
|
|
||||||
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
giphy_client = providers.Factory(
|
giphy_client = providers.Factory(
|
||||||
giphy.GiphyClient,
|
giphy.GiphyClient,
|
||||||
|
|
|
@ -10,10 +10,9 @@ from giphynavigator.giphy import GiphyClient
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def client(event_loop):
|
async def client():
|
||||||
client = AsyncClient(app=app, base_url="http://test")
|
async with AsyncClient(app=app, base_url="http://test") as client:
|
||||||
yield client
|
yield client
|
||||||
event_loop.run_until_complete(client.aclose())
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|
|
@ -81,20 +81,21 @@ The output should be something like:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
platform darwin -- Python 3.9, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
|
platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
plugins: flask-1.0.0, cov-2.10.0
|
plugins: cov-3.0.0, flask-1.2.0
|
||||||
collected 2 items
|
collected 2 items
|
||||||
|
|
||||||
githubnavigator/tests.py .. [100%]
|
githubnavigator/tests.py .. [100%]
|
||||||
|
|
||||||
---------- coverage: platform darwin, python 3.9 -----------
|
---------- coverage: platform darwin, python 3.10.0-final-0 ----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
----------------------------------------------------
|
------------------------------------------------------------
|
||||||
githubnavigator/__init__.py 0 0 100%
|
githubnavigator/__init__.py 0 0 100%
|
||||||
githubnavigator/application.py 15 0 100%
|
githubnavigator/application.py 13 0 100%
|
||||||
githubnavigator/blueprints/example.py 12 0 100%
|
githubnavigator/blueprints/__init__.py 0 0 100%
|
||||||
githubnavigator/containers.py 7 0 100%
|
githubnavigator/blueprints/example.py 12 0 100%
|
||||||
githubnavigator/services.py 14 0 100%
|
githubnavigator/containers.py 8 0 100%
|
||||||
githubnavigator/tests.py 34 0 100%
|
githubnavigator/services.py 14 0 100%
|
||||||
-----------------------------------------------------------
|
githubnavigator/tests.py 34 0 100%
|
||||||
TOTAL 82 0 100%
|
------------------------------------------------------------
|
||||||
|
TOTAL 81 0 100%
|
||||||
|
|
|
@ -9,9 +9,7 @@ from .blueprints import example
|
||||||
|
|
||||||
def create_app() -> Flask:
|
def create_app() -> Flask:
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.config.github.auth_token.from_env("GITHUB_TOKEN")
|
container.config.github.auth_token.from_env("GITHUB_TOKEN")
|
||||||
container.wire(modules=[example])
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.container = container
|
app.container = container
|
||||||
|
|
|
@ -8,7 +8,9 @@ from . import services
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
wiring_config = containers.WiringConfiguration(packages=[".blueprints"])
|
||||||
|
|
||||||
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
github_client = providers.Factory(
|
github_client = providers.Factory(
|
||||||
Github,
|
Github,
|
||||||
|
|
|
@ -81,20 +81,20 @@ The output should be something like:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
platform darwin -- Python 3.9, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
|
platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
plugins: flask-1.0.0, cov-2.10.0
|
plugins: cov-3.0.0, flask-1.2.0
|
||||||
collected 2 items
|
collected 2 items
|
||||||
|
|
||||||
githubnavigator/tests.py .. [100%]
|
githubnavigator/tests.py .. [100%]
|
||||||
|
|
||||||
---------- coverage: platform darwin, python 3.9 -----------
|
---------- coverage: platform darwin, python 3.10.0-final-0 ----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
githubnavigator/__init__.py 0 0 100%
|
githubnavigator/__init__.py 0 0 100%
|
||||||
githubnavigator/application.py 15 0 100%
|
githubnavigator/application.py 13 0 100%
|
||||||
githubnavigator/containers.py 7 0 100%
|
githubnavigator/containers.py 8 0 100%
|
||||||
githubnavigator/services.py 14 0 100%
|
githubnavigator/services.py 14 0 100%
|
||||||
githubnavigator/tests.py 34 0 100%
|
githubnavigator/tests.py 34 0 100%
|
||||||
githubnavigator/views.py 10 0 100%
|
githubnavigator/views.py 10 0 100%
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
TOTAL 80 0 100%
|
TOTAL 79 0 100%
|
||||||
|
|
|
@ -9,9 +9,7 @@ from . import views
|
||||||
|
|
||||||
def create_app() -> Flask:
|
def create_app() -> Flask:
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.config.github.auth_token.from_env("GITHUB_TOKEN")
|
container.config.github.auth_token.from_env("GITHUB_TOKEN")
|
||||||
container.wire(modules=[views])
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.container = container
|
app.container = container
|
||||||
|
|
|
@ -8,7 +8,9 @@ from . import services
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
wiring_config = containers.WiringConfiguration(modules=[".views"])
|
||||||
|
|
||||||
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
github_client = providers.Factory(
|
github_client = providers.Factory(
|
||||||
Github,
|
Github,
|
||||||
|
|
|
@ -58,21 +58,21 @@ The output should be something like:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
platform darwin -- Python 3.9, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
|
platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
plugins: cov-2.10.0
|
plugins: cov-3.0.0
|
||||||
collected 2 items
|
collected 2 items
|
||||||
|
|
||||||
movies/tests.py .. [100%]
|
movies/tests.py .. [100%]
|
||||||
|
|
||||||
---------- coverage: platform darwin, python 3.9 -----------
|
---------- coverage: platform darwin, python 3.10 -----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
movies/__init__.py 0 0 100%
|
movies/__init__.py 0 0 100%
|
||||||
movies/__main__.py 18 18 0%
|
movies/__main__.py 16 16 0%
|
||||||
movies/containers.py 9 0 100%
|
movies/containers.py 9 0 100%
|
||||||
movies/entities.py 7 1 86%
|
movies/entities.py 7 1 86%
|
||||||
movies/finders.py 26 13 50%
|
movies/finders.py 26 13 50%
|
||||||
movies/listers.py 8 0 100%
|
movies/listers.py 8 0 100%
|
||||||
movies/tests.py 24 0 100%
|
movies/tests.py 23 0 100%
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
TOTAL 92 32 65%
|
TOTAL 89 30 66%
|
||||||
|
|
|
@ -19,7 +19,6 @@ def main(lister: MovieLister = Provide[Container.lister]) -> None:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
container = Container()
|
container = Container()
|
||||||
container.config.from_yaml("config.yml")
|
|
||||||
container.config.finder.type.from_env("MOVIE_FINDER_TYPE")
|
container.config.finder.type.from_env("MOVIE_FINDER_TYPE")
|
||||||
container.wire(modules=[__name__])
|
container.wire(modules=[__name__])
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ from . import finders, listers, entities
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration(yaml_files=["config.yml"])
|
||||||
|
|
||||||
movie = providers.Factory(entities.Movie)
|
movie = providers.Factory(entities.Movie)
|
||||||
|
|
||||||
|
|
|
@ -9,19 +9,20 @@ from .containers import Container
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def container():
|
def container():
|
||||||
container = Container()
|
container = Container(
|
||||||
container.config.from_dict({
|
config={
|
||||||
"finder": {
|
"finder": {
|
||||||
"type": "csv",
|
"type": "csv",
|
||||||
"csv": {
|
"csv": {
|
||||||
"path": "/fake-movies.csv",
|
"path": "/fake-movies.csv",
|
||||||
"delimiter": ",",
|
"delimiter": ",",
|
||||||
},
|
},
|
||||||
"sqlite": {
|
"sqlite": {
|
||||||
"path": "/fake-movies.db",
|
"path": "/fake-movies.db",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
)
|
||||||
return container
|
return container
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -98,22 +98,22 @@ The output should be something like:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
platform darwin -- Python 3.9, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
|
platform darwin -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
|
||||||
plugins: cov-2.12.1, sanic-1.8.1, anyio-3.3.2
|
plugins: sanic-1.9.1, anyio-3.3.4, cov-3.0.0
|
||||||
collected 3 items
|
collected 3 items
|
||||||
|
|
||||||
giphynavigator/tests.py ... [100%]
|
giphynavigator/tests.py ... [100%]
|
||||||
|
|
||||||
---------- coverage: platform darwin, python 3.9 -----------
|
---------- coverage: platform darwin, python 3.10.0-final-0 ----------
|
||||||
Name Stmts Miss Cover
|
Name Stmts Miss Cover
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
giphynavigator/__init__.py 0 0 100%
|
giphynavigator/__init__.py 0 0 100%
|
||||||
giphynavigator/__main__.py 4 4 0%
|
giphynavigator/__main__.py 4 4 0%
|
||||||
giphynavigator/application.py 12 0 100%
|
giphynavigator/application.py 10 0 100%
|
||||||
giphynavigator/containers.py 6 0 100%
|
giphynavigator/containers.py 7 0 100%
|
||||||
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 39 0 100%
|
giphynavigator/tests.py 39 0 100%
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
TOTAL 95 14 85%
|
TOTAL 94 14 85%
|
||||||
|
|
|
@ -9,9 +9,7 @@ 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.giphy.api_key.from_env("GIPHY_API_KEY")
|
container.config.giphy.api_key.from_env("GIPHY_API_KEY")
|
||||||
container.wire(modules=[handlers])
|
|
||||||
|
|
||||||
app = Sanic("giphy-navigator")
|
app = Sanic("giphy-navigator")
|
||||||
app.ctx.container = container
|
app.ctx.container = container
|
||||||
|
|
|
@ -7,7 +7,9 @@ from . import giphy, services
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
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_client = providers.Factory(
|
||||||
giphy.GiphyClient,
|
giphy.GiphyClient,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
dependency-injector
|
dependency-injector
|
||||||
sanic
|
sanic<=21.6
|
||||||
aiohttp
|
aiohttp
|
||||||
pyyaml
|
pyyaml
|
||||||
pytest-sanic
|
pytest-sanic
|
||||||
|
|
Loading…
Reference in New Issue
Block a user