Skip to content

Commit

Permalink
Add config.from_env(as_=...) (#541)
Browse files Browse the repository at this point in the history
* Add implementation and typing stub

* Add unit tests

* Update demo example

* Add typing tests

* Update changelog

* Update docs

* Add tests for an empty environment variable

* Improve wording in di_in_python.rst

* Update wording in changelog and docs

* Update doc blocks
  • Loading branch information
rmk135 committed Dec 20, 2021
1 parent cc17052 commit cfadd8c
Show file tree
Hide file tree
Showing 12 changed files with 5,377 additions and 5,150 deletions.
6 changes: 3 additions & 3 deletions README.rst
Expand Up @@ -90,7 +90,7 @@ Key features of the ``Dependency Injector``:
api_client = providers.Singleton(
ApiClient,
api_key=config.api_key,
timeout=config.timeout.as_int(),
timeout=config.timeout,
)
service = providers.Factory(
Expand All @@ -106,8 +106,8 @@ Key features of the ``Dependency Injector``:
if __name__ == "__main__":
container = Container()
container.config.api_key.from_env("API_KEY")
container.config.timeout.from_env("TIMEOUT")
container.config.api_key.from_env("API_KEY", required=True)
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
container.wire(modules=[__name__])
main() # <-- dependency is injected automatically
Expand Down
6 changes: 3 additions & 3 deletions docs/index.rst
Expand Up @@ -96,7 +96,7 @@ Key features of the ``Dependency Injector``:
api_client = providers.Singleton(
ApiClient,
api_key=config.api_key,
timeout=config.timeout.as_int(),
timeout=config.timeout,
)
service = providers.Factory(
Expand All @@ -112,8 +112,8 @@ Key features of the ``Dependency Injector``:
if __name__ == "__main__":
container = Container()
container.config.api_key.from_env("API_KEY")
container.config.timeout.from_env("TIMEOUT")
container.config.api_key.from_env("API_KEY", required=True)
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
container.wire(modules=[__name__])
main() # <-- dependency is injected automatically
Expand Down
8 changes: 4 additions & 4 deletions docs/introduction/di_in_python.rst
Expand Up @@ -150,7 +150,7 @@ What does the Dependency Injector do?
-------------------------------------

With the dependency injection pattern objects loose the responsibility of assembling
the dependencies. The ``Dependency Injector`` absorbs that responsibilities.
the dependencies. The ``Dependency Injector`` absorbs that responsibility.

``Dependency Injector`` helps to assemble and inject the dependencies.

Expand All @@ -172,7 +172,7 @@ the dependency.
api_client = providers.Singleton(
ApiClient,
api_key=config.api_key,
timeout=config.timeout.as_int(),
timeout=config.timeout,
)
service = providers.Factory(
Expand All @@ -188,8 +188,8 @@ the dependency.
if __name__ == "__main__":
container = Container()
container.config.api_key.from_env("API_KEY")
container.config.timeout.from_env("TIMEOUT")
container.config.api_key.from_env("API_KEY", required=True)
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
container.wire(modules=[__name__])
main() # <-- dependency is injected automatically
Expand Down
2 changes: 2 additions & 0 deletions docs/main/changelog.rst
Expand Up @@ -9,6 +9,8 @@ follows `Semantic versioning`_

Development version
-------------------
- Add argument ``as_`` to the ``config.from_env()`` method for the explicit type casting
of an environment variable value, e.g.: ``config.timeout.from_env("TIMEOUT", as_=int)``.
- Add ``.providers`` attribute to the ``FactoryAggregate`` provider. It is an alias for
``FactoryAggregate.factories`` attribute.
- Add ``.set_providers()`` method to the ``FactoryAggregate`` provider. It is an alias for
Expand Down
18 changes: 18 additions & 0 deletions docs/providers/configuration.rst
Expand Up @@ -205,6 +205,24 @@ Loading from an environment variable
:lines: 3-
:emphasize-lines: 18-20

You can use ``as_`` argument for the type casting of an environment variable value:

.. code-block:: python
:emphasize-lines: 2,6,10
# API_KEY=secret
container.config.api_key.from_env("API_KEY", as_=str, required=True)
assert container.config.api_key() == "secret"
# SAMPLING_RATIO=0.5
container.config.sampling.from_env("SAMPLING_RATIO", as_=float, required=True)
assert container.config.sampling() == 0.5
# TIMEOUT undefined, default is used
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
assert container.config.timeout() == 5
Loading a value
---------------

Expand Down
6 changes: 3 additions & 3 deletions examples/demo/with_di.py
Expand Up @@ -13,7 +13,7 @@ class Container(containers.DeclarativeContainer):
api_client = providers.Singleton(
ApiClient,
api_key=config.api_key,
timeout=config.timeout.as_int(),
timeout=config.timeout,
)

service = providers.Factory(
Expand All @@ -29,8 +29,8 @@ def main(service: Service = Provide[Container.service]):

if __name__ == "__main__":
container = Container()
container.config.api_key.from_env("API_KEY")
container.config.timeout.from_env("TIMEOUT")
container.config.api_key.from_env("API_KEY", required=True)
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
container.wire(modules=[__name__])

main() # <-- dependency is injected automatically
Expand Down

0 comments on commit cfadd8c

Please sign in to comment.