mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-02-21 14:05:11 +03:00
Update asyncio-daemon example and tutorial
This commit is contained in:
parent
29d0900970
commit
0bd4dc58ed
|
@ -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::
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user