mirror of
https://github.com/Steffo99/cfig.git
synced 2024-11-21 23:44:21 +00:00
🗒️ Complete the documentation!
This commit is contained in:
parent
fbfd5851c7
commit
4a69d3a2ba
5 changed files with 152 additions and 3 deletions
|
@ -21,7 +21,7 @@ class Configuration:
|
||||||
A collection of proxies with methods to easily define more.
|
A collection of proxies with methods to easily define more.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DEFAULT_SOURCES = [
|
DEFAULT_SOURCES: list[Source] = [
|
||||||
EnvironmentSource(),
|
EnvironmentSource(),
|
||||||
EnvironmentFileSource(),
|
EnvironmentFileSource(),
|
||||||
]
|
]
|
||||||
|
@ -76,14 +76,14 @@ class Configuration:
|
||||||
log.debug(f"Unresolving: {item!r}")
|
log.debug(f"Unresolving: {item!r}")
|
||||||
del item.__wrapped__
|
del item.__wrapped__
|
||||||
|
|
||||||
def __init__(self, *, sources: t.Optional[t.Collection[Source]] = None):
|
def __init__(self, *, sources: t.Optional[list[Source]] = None):
|
||||||
"""
|
"""
|
||||||
Create a new :class:`Configuration`.
|
Create a new :class:`Configuration`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
log.debug(f"Initializing a new {self.__class__.__qualname__} object...")
|
log.debug(f"Initializing a new {self.__class__.__qualname__} object...")
|
||||||
|
|
||||||
self.sources: t.Collection[Source] = sources or self.DEFAULT_SOURCES
|
self.sources: list[Source] = sources or self.DEFAULT_SOURCES
|
||||||
"""
|
"""
|
||||||
Collection of sources to use for values of this configuration.
|
Collection of sources to use for values of this configuration.
|
||||||
"""
|
"""
|
||||||
|
|
109
docs/advanced.rst
Normal file
109
docs/advanced.rst
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
##############
|
||||||
|
Advanced usage
|
||||||
|
##############
|
||||||
|
|
||||||
|
This page describes some more advanced :mod:`cfig` features that you might be interested in using.
|
||||||
|
|
||||||
|
|
||||||
|
Fail-fast
|
||||||
|
=========
|
||||||
|
|
||||||
|
If your variables are very slow to be resolved, you may want for the :meth:`~cfig.config.Configuration.ProxyDict.resolve` method to raise as soon as a single value fails to resolve.
|
||||||
|
|
||||||
|
For that purpose, the :meth:`~cfig.config.Configuration.ProxyDict.resolve_failfast` method is provided:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
:emphasize-lines: 4
|
||||||
|
|
||||||
|
from .mydefinitionmodule import config
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
config.proxies.resolve_failfast()
|
||||||
|
|
||||||
|
Please note that the :meth:`~cfig.config.Configuration.ProxyDict.resolve_failfast` method does not raise :exc:`~cfig.errors.BatchResolutionFailure`, but raises the first occurring error instead, so you might want to catch it in this way:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
:emphasize-lines: 4,5,6,7
|
||||||
|
|
||||||
|
from .mydefinitionmodule import config
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
config.proxies.resolve_failfast()
|
||||||
|
except cfig.ConfigurationError as err:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
Reloading variables
|
||||||
|
===================
|
||||||
|
|
||||||
|
You might want for the configuration to be reloaded without restarting your application.
|
||||||
|
|
||||||
|
In that case, you may use the :meth:`~cfig.config.Configuration.ProxyDict.unresolve` method to clear the cached values, and then call :meth:`~cfig.config.Configuration.ProxyDict.resolve` again.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
:emphasize-lines: 2,3
|
||||||
|
|
||||||
|
...
|
||||||
|
config.proxies.unresolve()
|
||||||
|
config.proxies.resolve()
|
||||||
|
...
|
||||||
|
|
||||||
|
To reload a single variable, you may use the ``del`` keyword:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
:emphasize-lines: 2
|
||||||
|
|
||||||
|
...
|
||||||
|
del MY_VARIABLE.__wrapped__
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
Sources selection
|
||||||
|
=================
|
||||||
|
|
||||||
|
If you need further fine-tuning of the places to gather configuration values from, you may specify them via the :attr:`cfig.config.Configuration.sources` collection:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
:emphasize-lines: 2,3,5,6,7,8,9,10
|
||||||
|
|
||||||
|
import cfig
|
||||||
|
import cfig.sources.env
|
||||||
|
import cfig.sources.envfile
|
||||||
|
|
||||||
|
config = cfig.Configuration(sources=[
|
||||||
|
cfig.source.env.EnvironmentSource(),
|
||||||
|
cfig.source.env.EnvironmentSource(prefix="PROD_"),
|
||||||
|
cfig.source.envfile.EnvironmentFileSource(),
|
||||||
|
cfig.source.envfile.EnvironmentFileSource(suffix="_PATH"),
|
||||||
|
])
|
||||||
|
|
||||||
|
The specified sources are used in the order they are specified.
|
||||||
|
|
||||||
|
They may also be altered at runtime, if for some *crazy reason* you need that feature:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
:emphasize-lines: 6,7,8
|
||||||
|
|
||||||
|
import cfig
|
||||||
|
import cfig.sources.env
|
||||||
|
|
||||||
|
config = cfig.Configuration()
|
||||||
|
|
||||||
|
config.sources.append(
|
||||||
|
cfig.source.env.EnvironmentSource()
|
||||||
|
)
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Already cached variables **won't** be automatically reloaded after changing the sources!
|
||||||
|
|
||||||
|
|
||||||
|
Sources customization
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
If the provided sources aren't enough, you may create a custom class inheriting from :class:`~cfig.sources.base.Source`.
|
||||||
|
|
||||||
|
.. hint::
|
||||||
|
|
||||||
|
Since :mod:`cfig.sources` is a namespace package, if you intend to distribute your custom source, you may want to do it by extending the namespace, for an easier developer workflow.
|
|
@ -29,6 +29,12 @@ html_theme_options = {
|
||||||
# Set this to the main color of your project
|
# Set this to the main color of your project
|
||||||
"style_nav_header_background": "#b72f37",
|
"style_nav_header_background": "#b72f37",
|
||||||
}
|
}
|
||||||
|
html_context = {
|
||||||
|
"display_github": True,
|
||||||
|
"github_user": "Steffo99",
|
||||||
|
"github_repo": "cfig",
|
||||||
|
"github_version": "main/docs/",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
|
|
|
@ -38,6 +38,7 @@ Table of contents
|
||||||
goals
|
goals
|
||||||
installation
|
installation
|
||||||
quickstart
|
quickstart
|
||||||
|
advanced
|
||||||
reference
|
reference
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -232,3 +232,36 @@ In the modules of your application, you can import and use the variables directl
|
||||||
|
|
||||||
assert ALWAYS_NONE is not None
|
assert ALWAYS_NONE is not None
|
||||||
assert ALWAYS_NONE == None
|
assert ALWAYS_NONE == None
|
||||||
|
|
||||||
|
|
||||||
|
Validate all variables at once
|
||||||
|
==============================
|
||||||
|
|
||||||
|
For a better user experience, you might want to ensure that all variables are correctly configured when your application is started.
|
||||||
|
|
||||||
|
For that goal, :mod:`cfig` provides the :meth:`~cfig.config.Configuration.ProxyDict.resolve` method, which immediately tries to resolve and cache all configurable values defined in the :class:`~cfig.config.Configuration`:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
:emphasize-lines: 1,4
|
||||||
|
|
||||||
|
from .mydefinitionmodule import config
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
config.proxies.resolve()
|
||||||
|
|
||||||
|
The method will gather all errors occurring during the resolution, and will raise all of them at once with a :exc:`~cfig.errors.BatchResolutionFailure`, which you may want to handle in a custom way:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
:emphasize-lines: 4,5,6,7
|
||||||
|
|
||||||
|
from .mydefinitionmodule import config
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
config.proxies.resolve()
|
||||||
|
except cfig.BatchResolutionFailure as failure:
|
||||||
|
...
|
||||||
|
|
||||||
|
And that's it! You're using :mod:`cfig` in the best way possible :)
|
||||||
|
|
||||||
|
See :doc:`advanced` for more features that may be useful in specific cases.
|
Loading…
Reference in a new issue