1
Fork 0
mirror of https://github.com/Steffo99/cfig.git synced 2024-10-16 14:27:38 +00:00

🗒️ Complete documentation?

This commit is contained in:
Steffo 2022-04-21 19:14:09 +02:00
parent 6e473687da
commit fbfd5851c7
Signed by: steffo
GPG key ID: 6965406171929D01
7 changed files with 179 additions and 100 deletions

View file

@ -1,20 +1,23 @@
# Minimal makefile for Sphinx documentation
#
export SPHINXOPTS =
export SPHINXBUILD = "sphinx-build"
export SOURCEDIR = "."
export BUILDDIR = "_build"
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
export LATEXMKOPTS ?= ""
export LATEXOPTS ?= "-interaction=nonstopmode"
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)
livehtml:
sphinx-autobuild "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)

View file

@ -1,29 +0,0 @@
########
Glossary
########
In this documentation, the following terms are used:
.. glossary::
Key
The name of a configuration value, usually in SCREAMING_SNAKE_CASE.
For example, ``PATH``, the name of the environment variable.
Value
A single non-processed configuration value in :class:`str` form.
For example, the raw string value of an environment variable.
Source
A possible origin of configuration values, such as the environment, or a file.
Proxy
An object used to lazily and transparently resolve and cache values.
After resolving a value, it behaves in almost completely the same way as the object it cached.
Resolver
A function taking in input a value originating from a source, and emitting in output its processed representation.
For example, a resolver may be the :class:`int` class, which converts the value into an integer.
Configuration
A collection of proxies.

View file

@ -14,8 +14,8 @@ Pitch
| In that case, :mod:`cfig` is for you!
Minimal example
===============
Screenshots
===========
.. figure:: example-definition.png
@ -39,7 +39,6 @@ Table of contents
installation
quickstart
reference
glossary
Other tables and links

View file

@ -1,35 +0,0 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

View file

@ -2,11 +2,11 @@
Quickstart
##########
This page describes how to use :mod:`cfig` in an application.
.. note::
This page assumes you have already `installed <installation>` :mod:`cfig`.
This page assumes you have already :ref:`installed <Installation>` :mod:`cfig`.
This page describes how to use :mod:`cfig` in an application.
Creating a configuration module
@ -54,17 +54,13 @@ To make use of :mod:`cfig`, you'll need to create one or more configurable varia
The newly added lines create a new configurable value named ``SECRET_PASSWORD``:
* the **name** of the function is used as :term:`key` of the configurable value;
* the **name** of the function is used as key of the configurable value;
* the ``@config.required()`` **decorator** marks the value as required, preventing your application from launching if it is not set;
* the **function parameters** consist of a single :class:`str` parameter named ``val``, which is the string read from the environment variable having the same name of the function;
* the **docstring** defines the meaning of the configuration value in natural language;
* the **contents of the function** are used to process the input string into more refined Python objects;
* the **return annotation** of the function is used to let IDEs know what type this configuration value will be.
.. todo::
Maybe say that it is called a :term:`resolver`?
Optional
--------
@ -97,12 +93,12 @@ Optional values differ from required ones in their decorator and signature:
#. Since the passed ``val`` can be :data:`None`, it is given a signature of :data:`typing.Optional`.
Processing
----------
Processing and validation
-------------------------
.. todo::
The function defining a new configurable variable is also called a resolver: it will be executed only once, when its value is first requested, then the result is cached in a special object called proxy.
A few words about value processing.
This allows us to perform some expensive operations inside, such as connecting to a database, or performing API requests to validate tokens and passwords.
.. code-block:: python
:emphasize-lines: 18,19,20,21,22,23,24
@ -132,17 +128,20 @@ Processing
except ValueError:
raise cfig.InvalidValueError("Not an int.")
.. todo::
We can see that the new ``MAX_USERS`` configurable value processes the input string by trying to cast it into an :class:`int`, and raises a :exc:`~cfig.errors.InvalidValueError` containing the error message to display to the user if the cast fails.
A few words about slower resolvers.
Ideally, errors happening in resolvers should be caught by the programmer and re-raised as :exc:`~cfig.errors.InvalidValueError`, so that users can distinguish them from bugs.
Adding CLI support
==================
.. todo::
.. note::
This requires the CLI extra to be installed. See :ref:`Installation` for more details.
To facilitate configuration on the users' part, :mod:`cfig` provides an integrated command line interface previewing the values of variables, triggered by a call to :meth:`~cfig.config.Configuration.cli`:
What is the CLI and why is it useful?
.. code-block:: python
:emphasize-lines: 26,27
@ -175,18 +174,61 @@ Adding CLI support
if __name__ == "__main__":
config.cli()
.. todo::
By adding the :meth:`~cfig.config.Configuration.cli` call to a :mod:`__main__` clause, we allow users to access the CLI by manually running this module, but we prevent the CLI from starting when this module is accessed from another location.
What will be displayed here?
Given our current configuration, something similar to this will be displayed:
.. code-block:: console
$ python -m myproject.mydefinitionmodule
===== Configuration =====
SECRET_PASSWORD → Required, but not set.
The secret password required to use this application!
SECRET_USERNAME = 'root'
The username to require users to login as. If unset, defaults to `root`.
MAX_USERS → Required, but not set.
The maximum number of users that will be able to login to this application.
===== End =====
Use the configuration
=====================
.. todo::
Finally, it is time to use in our application the configurable variables we defined!
How do I use the created values in my application?
In the modules of your application, you can import and use the variables directly from the definition module:
.. todo::
.. code-block:: python
:emphasize-lines: 1,4,7,11,12
Why does ``is None`` not work?
from .mydefinitionmodule import SECRET_PASSWORD, SECRET_USERNAME, MAX_USERS
if __name__ == "__main__":
if username := input("Username: ") != SECRET_USERNAME:
print("error: invalid username")
sys.exit(1)
if password := input("Password: ") != SECRET_PASSWORD:
print("error: invalid password")
sys.exit(2)
print("Welcome, " + SECRET_USERNAME + "!")
print(f"The current user limit is: {MAX_USERS}")
.. warning::
Since the values imported from the definition module are proxies to the real value, ``is`` comparisions won't work with them, but you can do ``==`` comparsions with them:
.. code-block:: python
:emphasize-lines: 6,7
@config.optional()
def ALWAYS_NONE(val: t.Optional[str]) -> str:
"""This configuration value will always be None."""
return None
assert ALWAYS_NONE is not None
assert ALWAYS_NONE == None

100
poetry.lock generated
View file

@ -131,6 +131,18 @@ category = "main"
optional = false
python-versions = ">=3.6"
[[package]]
name = "livereload"
version = "2.6.3"
description = "Python LiveReload is an awesome tool for web developers"
category = "dev"
optional = false
python-versions = "*"
[package.dependencies]
six = "*"
tornado = {version = "*", markers = "python_version > \"2.7\""}
[[package]]
name = "markupsafe"
version = "2.1.1"
@ -247,6 +259,14 @@ urllib3 = ">=1.21.1,<1.27"
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
[[package]]
name = "six"
version = "1.16.0"
description = "Python 2 and 3 compatibility utilities"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
[[package]]
name = "snowballstemmer"
version = "2.2.0"
@ -286,6 +306,22 @@ docs = ["sphinxcontrib-websupport"]
lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "docutils-stubs", "types-typed-ast", "types-requests"]
test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"]
[[package]]
name = "sphinx-autobuild"
version = "2021.3.14"
description = "Rebuild Sphinx documentation on changes, with live-reload in the browser."
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
colorama = "*"
livereload = "*"
sphinx = "*"
[package.extras]
test = ["pytest", "pytest-cov"]
[[package]]
name = "sphinx-rtd-theme"
version = "1.0.0"
@ -380,6 +416,14 @@ category = "dev"
optional = false
python-versions = ">=3.7"
[[package]]
name = "tornado"
version = "6.1"
description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed."
category = "dev"
optional = false
python-versions = ">= 3.5"
[[package]]
name = "urllib3"
version = "1.26.9"
@ -399,7 +443,7 @@ cli = ["click", "colorama"]
[metadata]
lock-version = "1.1"
python-versions = "^3.10"
content-hash = "b0adc395c41c3e95211038a54caca8da0b1d37752a4c5bf11825dda754332c9b"
content-hash = "8c5e9050157d93b63f5ea2641312dbfab21e45541a2c17e5401ff35db7b9aaca"
[metadata.files]
alabaster = [
@ -493,6 +537,9 @@ lazy-object-proxy = [
{file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"},
{file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"},
]
livereload = [
{file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"},
]
markupsafe = [
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
@ -571,6 +618,10 @@ requests = [
{file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
{file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"},
]
six = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]
snowballstemmer = [
{file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
{file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
@ -579,6 +630,10 @@ sphinx = [
{file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"},
{file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"},
]
sphinx-autobuild = [
{file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"},
{file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"},
]
sphinx-rtd-theme = [
{file = "sphinx_rtd_theme-1.0.0-py2.py3-none-any.whl", hash = "sha256:4d35a56f4508cfee4c4fb604373ede6feae2a306731d533f409ef5c3496fdbd8"},
{file = "sphinx_rtd_theme-1.0.0.tar.gz", hash = "sha256:eec6d497e4c2195fa0e8b2016b337532b8a699a68bcb22a512870e16925c6a5c"},
@ -611,6 +666,49 @@ tomli = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
tornado = [
{file = "tornado-6.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32"},
{file = "tornado-6.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c"},
{file = "tornado-6.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05"},
{file = "tornado-6.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910"},
{file = "tornado-6.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b"},
{file = "tornado-6.1-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675"},
{file = "tornado-6.1-cp35-cp35m-win32.whl", hash = "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5"},
{file = "tornado-6.1-cp35-cp35m-win_amd64.whl", hash = "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68"},
{file = "tornado-6.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb"},
{file = "tornado-6.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c"},
{file = "tornado-6.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921"},
{file = "tornado-6.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558"},
{file = "tornado-6.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c"},
{file = "tornado-6.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085"},
{file = "tornado-6.1-cp36-cp36m-win32.whl", hash = "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575"},
{file = "tornado-6.1-cp36-cp36m-win_amd64.whl", hash = "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795"},
{file = "tornado-6.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f"},
{file = "tornado-6.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102"},
{file = "tornado-6.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4"},
{file = "tornado-6.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd"},
{file = "tornado-6.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01"},
{file = "tornado-6.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d"},
{file = "tornado-6.1-cp37-cp37m-win32.whl", hash = "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df"},
{file = "tornado-6.1-cp37-cp37m-win_amd64.whl", hash = "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37"},
{file = "tornado-6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95"},
{file = "tornado-6.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a"},
{file = "tornado-6.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5"},
{file = "tornado-6.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288"},
{file = "tornado-6.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f"},
{file = "tornado-6.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6"},
{file = "tornado-6.1-cp38-cp38-win32.whl", hash = "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326"},
{file = "tornado-6.1-cp38-cp38-win_amd64.whl", hash = "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c"},
{file = "tornado-6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5"},
{file = "tornado-6.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe"},
{file = "tornado-6.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea"},
{file = "tornado-6.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2"},
{file = "tornado-6.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0"},
{file = "tornado-6.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd"},
{file = "tornado-6.1-cp39-cp39-win32.whl", hash = "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c"},
{file = "tornado-6.1-cp39-cp39-win_amd64.whl", hash = "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4"},
{file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"},
]
urllib3 = [
{file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
{file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},

View file

@ -164,6 +164,7 @@ pytest = "^7.1.1"
Sphinx = "^4.5.0"
sphinx-rtd-theme = "^1.0.0"
pytest-github-actions-annotate-failures = "^0.1.6"
sphinx-autobuild = "^2021.3.14"
[tool.pytest.ini_options]