Add docs for the use cases example

This commit is contained in:
Roman Mogylatov 2020-09-07 12:31:59 -04:00
parent f84d3e6f4e
commit 36ece67586
15 changed files with 164 additions and 150 deletions

View File

@ -13,7 +13,7 @@ This sections contains assorted ``Dependency Injector`` examples.
.. toctree::
:maxdepth: 2
use_cases_miniapp
use-cases
password-hashing
chained_factories
factory_of_factories

View File

@ -3,6 +3,8 @@ Password hashing example
This example demonstrates an injection of the ``Callable`` provider.
The source code is available on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/password-hashing>`_.
Listing of the ``example.py``:
.. literalinclude:: ../../examples/miniapps/password-hashing/example.py
@ -14,6 +16,4 @@ Instructions for running:
python example.py
You can find the source code on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/password-hashing>`_.
.. disqus::

View File

@ -0,0 +1,71 @@
Use cases example
=================
.. currentmodule:: dependency_injector.providers
This example demonstrates a usage of the ``DependenciesContainer`` provider.
The source code is available on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/decoupled-packages>`_.
Application structure
---------------------
Example application has next structure:
.. code-block:: bash
./
└── example/
├── __init__.py
├── __main__.py
├── adapters.py
├── containers.py
└── usecases.py
Containers
----------
Listing of the ``example/containers.py``:
.. literalinclude:: ../../examples/miniapps/use-cases/example/containers.py
:language: python
Main module
-----------
Listing of the ``example/__main__.py``:
.. literalinclude:: ../../examples/miniapps/use-cases/example/__main__.py
:language: python
Run the application
-------------------
Instructions for running in the "test" mode:
.. code-block:: bash
python run.py test example@example.com
Instructions for running in the "prod" mode:
.. code-block:: bash
python run.py prod example@example.com
Adapters and use cases
----------------------
Listing of the ``example/adapters.py``:
.. literalinclude:: ../../examples/miniapps/use-cases/example/adapters.py
:language: python
Listing of the ``example/usecases.py``:
.. literalinclude:: ../../examples/miniapps/use-cases/example/usecases.py
:language: python
.. disqus::

View File

@ -1,55 +0,0 @@
Use cases mini application example
----------------------------------
.. currentmodule:: dependency_injector.providers
"Use cases" miniapp demonstrate usage of :py:class:`DependenciesContainer`
provider.
Example application
~~~~~~~~~~~~~~~~~~~
"Use cases" mini application has next structure:
.. code-block:: bash
use_cases/
example/ <-- Example package
__init__.py
adapters.py
use_cases.py
containers.py <-- Dependency injection containers
run.py <-- Entrypoint
IoC containers
~~~~~~~~~~~~~~
Listing of ``use_cases/containers.py``:
.. literalinclude:: ../../examples/miniapps/use_cases/containers.py
:language: python
Run application
~~~~~~~~~~~~~~~
Listing of ``run.py``:
.. literalinclude:: ../../examples/miniapps/use_cases/run.py
:language: python
Instructions for running:
.. code-block:: bash
python run.py prod example@example.com # Running in "production" environment
python run.py test example@example.com # Running in "testing" environment
Links
~~~~~
+ `Dependency Injector <https://github.com/ets-labs/python-dependency-injector/>`_
+ `Full example sources <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/use_cases>`_
.. disqus::

View File

@ -0,0 +1,11 @@
Use cases
=========
This example demonstrates a usage of the ``DependenciesContainer`` provider.
Instructions for running:
.. code-block:: bash
python -m example prod example@example.com
python -m example test example@example.com

View File

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

View File

@ -1,19 +1,23 @@
"""Run 'Use Cases' example application."""
"""Main module."""
import sys
from containers import Adapters, TestAdapters, UseCases
from .containers import UseCases, Adapters, TestAdapters
if __name__ == '__main__':
environment, email = sys.argv[1:]
def main(environment: str, email: str) -> None:
if environment == 'prod':
adapters = Adapters()
elif environment == 'test':
adapters = TestAdapters()
else:
raise RuntimeError('Unknown environment')
use_cases = UseCases(adapters=adapters)
use_case = use_cases.signup()
use_case.execute(email)
if __name__ == '__main__':
main(*sys.argv[1:])

View File

@ -0,0 +1,22 @@
"""Adapters module."""
import abc
class EmailSender(metaclass=abc.ABCMeta):
@abc.abstractmethod
def send(self, to: str, body: str) -> None:
...
class SmtpEmailSender:
def send(self, to: str, body: str) -> None:
print(f'Sending an email to {to} over SMTP, body="{body}"')
class EchoEmailSender:
def send(self, to: str, body: str) -> None:
print(f'Fake sending an email to {to}, body="{body}"')

View File

@ -0,0 +1,25 @@
"""Containers module."""
from dependency_injector import containers, providers
from . import adapters, usecases
class Adapters(containers.DeclarativeContainer):
email_sender = providers.Singleton(adapters.SmtpEmailSender)
class TestAdapters(containers.DeclarativeContainer):
email_sender = providers.Singleton(adapters.EchoEmailSender)
class UseCases(containers.DeclarativeContainer):
adapters = providers.DependenciesContainer()
signup = providers.Factory(
usecases.SignupUseCase,
email_sender=adapters.email_sender,
)

View File

@ -0,0 +1,22 @@
"""Use cases module."""
import abc
from .adapters import EmailSender
class UseCase(metaclass=abc.ABCMeta):
@abc.abstractmethod
def execute(self) -> None:
...
class SignupUseCase:
def __init__(self, email_sender: EmailSender) -> None:
self.email_sender = email_sender
def execute(self, email: str) -> None:
print(f'Sign up user {email}')
self.email_sender.send(email, f'Welcome, {email}')

View File

@ -1,9 +0,0 @@
Dependency Injector Use Cases example
=====================================
Instructions for running
.. code-block:: bash
python run.py prod example@example.com # Running in "production" environment
python run.py test example@example.com # Running in "testing" environment

View File

@ -1,30 +0,0 @@
"""Dependency injection containers for 'Use Cases' example application."""
from dependency_injector import containers, providers
from example.adapters import SmtpEmailSender, EchoEmailSender
from example.use_cases import SignupUseCase
class Adapters(containers.DeclarativeContainer):
"""Adapters container."""
email_sender = providers.Singleton(SmtpEmailSender)
class TestAdapters(containers.DeclarativeContainer):
"""Adapters container.
This container is used for testing purposes.
"""
email_sender = providers.Singleton(EchoEmailSender)
class UseCases(containers.DeclarativeContainer):
"""Use cases container."""
adapters = providers.DependenciesContainer()
signup = providers.Factory(SignupUseCase,
email_sender=adapters.email_sender)

View File

@ -1 +0,0 @@
"""Example top-level package."""

View File

@ -1,25 +0,0 @@
"""Example adapters package."""
class EmailSender:
"""Abstract email sender."""
def send(self, to, body):
"""Send email to specified email."""
raise NotImplementedError()
class SmtpEmailSender:
"""SMTP email sender uses SMTP protocol for sending emails."""
def send(self, to, body):
"""Send email to specified email."""
# Send email via SMTP
class EchoEmailSender:
"""Echo email sender prints emails to stdout."""
def send(self, to, body):
"""Send email to specified email."""
print('Sending email to "{0}", body = "{1}"'.format(to, body))

View File

@ -1,22 +0,0 @@
"""Example use cases package."""
class UseCase:
"""Abstract use case."""
def execute(self):
"""Execute use case handling."""
raise NotImplementedError()
class SignupUseCase:
"""Sign up use cases registers users."""
def __init__(self, email_sender):
"""Initialize instance."""
self.email_sender = email_sender
def execute(self, email):
"""Execute use case handling."""
print('Sign up user {0}'.format(email))
self.email_sender.send(email, 'Welcome, "{}"'.format(email))