Add docs page and examples

This commit is contained in:
Roman Mogylatov 2020-08-24 13:27:55 -04:00
parent c3e93f8d4d
commit 083c050cd4
6 changed files with 99 additions and 3 deletions

View File

@ -96,4 +96,34 @@ where ``examples/providers/configuration/config.local.yml`` is:
.. literalinclude:: ../../examples/providers/configuration/config.local.yml
:language: ini
Specifying value type
~~~~~~~~~~~~~~~~~~~~~
You can specify the type of the injected configuration value explicitly.
This helps when you read the value from the ini file or the environment variable and need to
convert it into an ``int`` or a ``float``.
.. literalinclude:: ../../examples/providers/configuration/configuration_type.py
:language: python
:lines: 3-
:emphasize-lines: 17
:py:class:`Configuration` provider has next helper methods:
- ``.as_int()``
- ``.as_float()``
- ``.as_(callback, *args, **kwargs)``
The last method ``.as_(callback, *args, **kwargs)`` helps to implement a other conversions.
.. literalinclude:: ../../examples/providers/configuration/configuration_type_custom.py
:language: python
:lines: 3-
:emphasize-lines: 16
With the ``.as_(callback, *args, **kwargs)`` you can specify the function that will be called
before the injection. The value from the config will be passed as a first argument. The returned
value will be injected. Parameters ``*args`` and ``**kwargs`` are handled as any other injections.
.. disqus::

View File

@ -62,3 +62,5 @@ should use the :py:class:`ProvidedInstance` provider.
In all other cases you should not use :py:class:`ProvidedInstance`, :py:class:`AttributeGetter`,
:py:class:`ItemGetter`, or :py:class:`MethodCaller` providers directly. Use the ``.provided``
attribute of the injected provider instead.
.. disqus::

View File

@ -7,7 +7,7 @@ import models
# Creating ApiClient and User providers:
api_client = providers.Singleton(api.ApiClient,
api_client = providers.Singleton(api.Converter,
host='production.com',
api_key='PROD_API_KEY')
user_factory = providers.Factory(models.User,
@ -27,7 +27,7 @@ if __name__ == '__main__':
# {'id': 2}
# Overriding of ApiClient on dev environment:
api_client.override(providers.Singleton(api.ApiClient,
api_client.override(providers.Singleton(api.Converter,
host='localhost',
api_key='DEV_API_KEY'))

View File

@ -6,7 +6,7 @@ import main
import api
# Mock ApiClient for testing:
with main.api_client.override(Mock(api.ApiClient)) as api_client_mock:
with main.api_client.override(Mock(api.Converter)) as api_client_mock:
user = main.user_factory('test')
user.register()
api_client_mock().call.assert_called_with('register', {'id': 'test'})

View File

@ -0,0 +1,34 @@
"""`Configuration` provider type specification example."""
import os
from dependency_injector import providers
class ApiClient:
def __init__(self, api_key: str, timeout: int):
self.api_key = api_key
self.timeout = timeout
config = providers.Configuration()
api_client_factory = providers.Factory(
ApiClient,
api_key=config.api.key,
timeout=config.api.timeout.as_int(),
)
if __name__ == '__main__':
# Emulate environment variables
os.environ['API_KEY'] = 'secret'
os.environ['API_TIMEOUT'] = '5'
config.api.key.from_env('API_KEY')
config.api.timeout.from_env('API_TIMEOUT')
api_client = api_client_factory()
assert api_client.api_key == 'secret'
assert api_client.timeout == 5

View File

@ -0,0 +1,30 @@
"""`Configuration` provider custom type specification example."""
import os
import decimal
from dependency_injector import providers
class Calculator:
def __init__(self, pi: decimal.Decimal):
self.pi = pi
config = providers.Configuration()
calculator_factory = providers.Factory(
Calculator,
pi=config.pi.as_(decimal.Decimal),
)
if __name__ == '__main__':
# Emulate environment variables
os.environ['PI'] = '3.1415926535897932384626433832'
config.pi.from_env('PI')
calculator = calculator_factory()
assert calculator.pi == decimal.Decimal('3.1415926535897932384626433832')