Skip to content

Commit cfadd8c

Browse files
authored
Add config.from_env(as_=...) (ets-labs#541)
* 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
1 parent cc17052 commit cfadd8c

File tree

12 files changed

+5377
-5150
lines changed

12 files changed

+5377
-5150
lines changed

README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ Key features of the ``Dependency Injector``:
9090
api_client = providers.Singleton(
9191
ApiClient,
9292
api_key=config.api_key,
93-
timeout=config.timeout.as_int(),
93+
timeout=config.timeout,
9494
)
9595
9696
service = providers.Factory(
@@ -106,8 +106,8 @@ Key features of the ``Dependency Injector``:
106106
107107
if __name__ == "__main__":
108108
container = Container()
109-
container.config.api_key.from_env("API_KEY")
110-
container.config.timeout.from_env("TIMEOUT")
109+
container.config.api_key.from_env("API_KEY", required=True)
110+
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
111111
container.wire(modules=[__name__])
112112
113113
main() # <-- dependency is injected automatically

docs/index.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Key features of the ``Dependency Injector``:
9696
api_client = providers.Singleton(
9797
ApiClient,
9898
api_key=config.api_key,
99-
timeout=config.timeout.as_int(),
99+
timeout=config.timeout,
100100
)
101101
102102
service = providers.Factory(
@@ -112,8 +112,8 @@ Key features of the ``Dependency Injector``:
112112
113113
if __name__ == "__main__":
114114
container = Container()
115-
container.config.api_key.from_env("API_KEY")
116-
container.config.timeout.from_env("TIMEOUT")
115+
container.config.api_key.from_env("API_KEY", required=True)
116+
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
117117
container.wire(modules=[__name__])
118118
119119
main() # <-- dependency is injected automatically

docs/introduction/di_in_python.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ What does the Dependency Injector do?
150150
-------------------------------------
151151

152152
With the dependency injection pattern objects loose the responsibility of assembling
153-
the dependencies. The ``Dependency Injector`` absorbs that responsibilities.
153+
the dependencies. The ``Dependency Injector`` absorbs that responsibility.
154154

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

@@ -172,7 +172,7 @@ the dependency.
172172
api_client = providers.Singleton(
173173
ApiClient,
174174
api_key=config.api_key,
175-
timeout=config.timeout.as_int(),
175+
timeout=config.timeout,
176176
)
177177
178178
service = providers.Factory(
@@ -188,8 +188,8 @@ the dependency.
188188
189189
if __name__ == "__main__":
190190
container = Container()
191-
container.config.api_key.from_env("API_KEY")
192-
container.config.timeout.from_env("TIMEOUT")
191+
container.config.api_key.from_env("API_KEY", required=True)
192+
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
193193
container.wire(modules=[__name__])
194194
195195
main() # <-- dependency is injected automatically

docs/main/changelog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ follows `Semantic versioning`_
99

1010
Development version
1111
-------------------
12+
- Add argument ``as_`` to the ``config.from_env()`` method for the explicit type casting
13+
of an environment variable value, e.g.: ``config.timeout.from_env("TIMEOUT", as_=int)``.
1214
- Add ``.providers`` attribute to the ``FactoryAggregate`` provider. It is an alias for
1315
``FactoryAggregate.factories`` attribute.
1416
- Add ``.set_providers()`` method to the ``FactoryAggregate`` provider. It is an alias for

docs/providers/configuration.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,24 @@ Loading from an environment variable
205205
:lines: 3-
206206
:emphasize-lines: 18-20
207207

208+
You can use ``as_`` argument for the type casting of an environment variable value:
209+
210+
.. code-block:: python
211+
:emphasize-lines: 2,6,10
212+
213+
# API_KEY=secret
214+
container.config.api_key.from_env("API_KEY", as_=str, required=True)
215+
assert container.config.api_key() == "secret"
216+
217+
# SAMPLING_RATIO=0.5
218+
container.config.sampling.from_env("SAMPLING_RATIO", as_=float, required=True)
219+
assert container.config.sampling() == 0.5
220+
221+
# TIMEOUT undefined, default is used
222+
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
223+
assert container.config.timeout() == 5
224+
225+
208226
Loading a value
209227
---------------
210228

examples/demo/with_di.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Container(containers.DeclarativeContainer):
1313
api_client = providers.Singleton(
1414
ApiClient,
1515
api_key=config.api_key,
16-
timeout=config.timeout.as_int(),
16+
timeout=config.timeout,
1717
)
1818

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

3030
if __name__ == "__main__":
3131
container = Container()
32-
container.config.api_key.from_env("API_KEY")
33-
container.config.timeout.from_env("TIMEOUT")
32+
container.config.api_key.from_env("API_KEY", required=True)
33+
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
3434
container.wire(modules=[__name__])
3535

3636
main() # <-- dependency is injected automatically

0 commit comments

Comments
 (0)