462 Config.from_value() (#465)

* Implement .from_value() method for config provider

* Add tests for config.from_value() method

* Add example for config.from_value()

* Add docs

* Update changelog
This commit is contained in:
Roman Mogylatov 2021-06-13 22:05:29 -04:00 committed by GitHub
parent bbd623c719
commit dbbf5fdcf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 5400 additions and 5149 deletions

View File

@ -13,6 +13,10 @@ Development version
configuration files with ``${ENV_NAME:default}`` format. configuration files with ``${ENV_NAME:default}`` format.
See issue `#459 <https://github.com/ets-labs/python-dependency-injector/issues/459>`_. See issue `#459 <https://github.com/ets-labs/python-dependency-injector/issues/459>`_.
Thanks to `Maksym Shemet @hbmshemet <https://github.com/hbmshemet>`_ for suggesting the feature. Thanks to `Maksym Shemet @hbmshemet <https://github.com/hbmshemet>`_ for suggesting the feature.
- Add method ``Configuration.from_value()``.
See issue `#462 <https://github.com/ets-labs/python-dependency-injector/issues/462>`_.
Thanks to Mr. `Slack Clone <https://disqus.com/by/slackclone/>`_ for bringing it up
in the comments for configuration provider docs.
4.32.3 4.32.3
------ ------

View File

@ -164,6 +164,17 @@ Loading from an environment variable
:lines: 3- :lines: 3-
:emphasize-lines: 18-20 :emphasize-lines: 18-20
Loading a value
---------------
``Configuration`` provider can load configuration value using the
:py:meth:`Configuration.from_value` method:
.. literalinclude:: ../../examples/providers/configuration/configuration_value.py
:language: python
:lines: 3-
:emphasize-lines: 14-15
Loading from the multiple sources Loading from the multiple sources
--------------------------------- ---------------------------------

View File

@ -0,0 +1,24 @@
"""`Configuration` provider values loading example."""
from datetime import date
from dependency_injector import containers, providers
class Container(containers.DeclarativeContainer):
config = providers.Configuration()
if __name__ == '__main__':
container = Container()
container.config.option1.from_value(date(2021, 6, 13))
container.config.option2.from_value(date(2021, 6, 14))
assert container.config() == {
'option1': date(2021, 6, 13),
'option2': date(2021, 6, 14),
}
assert container.config.option1() == date(2021, 6, 13)
assert container.config.option2() == date(2021, 6, 14)

File diff suppressed because it is too large Load Diff

View File

@ -205,6 +205,7 @@ class ConfigurationOption(Provider[Any]):
def from_pydantic(self, settings: PydanticSettings, required: bool = False, **kwargs: Any) -> None: ... def from_pydantic(self, settings: PydanticSettings, required: bool = False, **kwargs: Any) -> None: ...
def from_dict(self, options: _Dict[str, Any], required: bool = False) -> None: ... def from_dict(self, options: _Dict[str, Any], required: bool = False) -> None: ...
def from_env(self, name: str, default: Optional[Any] = None, required: bool = False) -> None: ... def from_env(self, name: str, default: Optional[Any] = None, required: bool = False) -> None: ...
def from_value(self, value: Any) -> None: ...
class TypedConfigurationOption(Callable[T]): class TypedConfigurationOption(Callable[T]):
@ -241,6 +242,7 @@ class Configuration(Object[Any]):
def from_pydantic(self, settings: PydanticSettings, required: bool = False, **kwargs: Any) -> None: ... def from_pydantic(self, settings: PydanticSettings, required: bool = False, **kwargs: Any) -> None: ...
def from_dict(self, options: _Dict[str, Any], required: bool = False) -> None: ... def from_dict(self, options: _Dict[str, Any], required: bool = False) -> None: ...
def from_env(self, name: str, default: Optional[Any] = None, required: bool = False) -> None: ... def from_env(self, name: str, default: Optional[Any] = None, required: bool = False) -> None: ...
def from_value(self, value: Any) -> None: ...
class Factory(Provider[T]): class Factory(Provider[T]):

View File

@ -1698,6 +1698,16 @@ cdef class ConfigurationOption(Provider):
self.override(value) self.override(value)
def from_value(self, value):
"""Load configuration value.
:param value: Configuration value
:type value: object
:rtype: None
"""
self.override(value)
@property @property
def related(self): def related(self):
"""Return related providers generator.""" """Return related providers generator."""
@ -2104,6 +2114,16 @@ cdef class Configuration(Object):
self.override(value) self.override(value)
def from_value(self, value):
"""Load configuration value.
:param value: Configuration value
:type value: object
:rtype: None
"""
self.override(value)
@property @property
def related(self): def related(self):
"""Return related providers generator.""" """Return related providers generator."""

View File

@ -1376,3 +1376,25 @@ class ConfigFromEnvTests(unittest.TestCase):
self.config = providers.Configuration(strict=True) self.config = providers.Configuration(strict=True)
self.config.option.from_env('UNDEFINED_ENV', default='default-value', required=False) self.config.option.from_env('UNDEFINED_ENV', default='default-value', required=False)
self.assertEqual(self.config.option(), 'default-value') self.assertEqual(self.config.option(), 'default-value')
class ConfigFromValueTests(unittest.TestCase):
def setUp(self):
self.config = providers.Configuration(name='config')
def test_from_value(self):
test_value = 123321
self.config.from_value(test_value)
self.assertEqual(self.config(), test_value)
def test_option_from_value(self):
test_value_1 = 123
test_value_2 = 321
self.config.option1.from_value(test_value_1)
self.config.option2.from_value(test_value_2)
self.assertEqual(self.config(), {'option1': test_value_1, 'option2': test_value_2})
self.assertEqual(self.config.option1(), test_value_1)
self.assertEqual(self.config.option2(), test_value_2)