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

192 lines
5 KiB
ReStructuredText
Raw Normal View History

2022-04-20 23:32:20 +00:00
##########
Quickstart
##########
This page describes how to use :mod:`cfig` in an application.
.. note::
This page assumes you have already `installed <installation>` :mod:`cfig`.
Creating a configuration module
===============================
First, create a new ``.py`` file inside your package with the following contents:
.. code-block:: python
:emphasize-lines: 1,2,4
import cfig
import typing as t
config = cfig.Configuration()
This will:
#. Import :mod:`cfig` into your module
#. Import :mod:`typing` into your module and alias it as ``t`` for ease of use
#. Create a new :class:`~cfig.config.Configuration` with the default parameters, which will be able to be configured from `environment variables`_ and from environment files (files whose path is specified in an environment variable suffixed with ``_FILE``)
.. _environment variables: https://wiki.archlinux.org/title/Environment_variables
2022-04-20 23:32:20 +00:00
Creating configurable variables
===============================
Basics
------
To make use of :mod:`cfig`, you'll need to create one or more configurable variables in your module file:
.. code-block:: python
:emphasize-lines: 6,7,8,9
import cfig
import typing as t
config = cfig.Configuration()
@config.required()
def SECRET_PASSWORD(val: str) -> str:
"""The secret password required to use this application!"""
return val
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 ``@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
--------
Configuration values can be optional:
.. code-block:: python
:emphasize-lines: 11,12,13,14,15,16
import cfig
import typing as t
config = cfig.Configuration()
@config.required()
def SECRET_PASSWORD(val: str) -> str:
"""The secret password required to use this application!"""
return val
@config.optional()
def SECRET_USERNAME(val: t.Optional[str]) -> str:
"""The username to require users to login as. If unset, defaults to `root`."""
if val is None:
return "root"
return val
Optional values differ from required ones in their decorator and signature:
#. The decorator is ``@config.optional()`` instead of ``@config.required()``;
#. Since the passed ``val`` can be :data:`None`, it is given a signature of :data:`typing.Optional`.
Processing
----------
2022-04-20 23:32:20 +00:00
.. todo::
A few words about value processing.
.. code-block:: python
:emphasize-lines: 18,19,20,21,22,23,24
import cfig
import typing as t
config = cfig.Configuration()
@config.required()
def SECRET_PASSWORD(val: str) -> str:
"""The secret password required to use this application!"""
return val
@config.optional()
def SECRET_USERNAME(val: t.Optional[str]) -> str:
"""The username to require users to login as. If unset, defaults to `root`."""
if val is None:
return "root"
return val
@config.required()
def MAX_USERS(val: str) -> int:
"""The maximum number of users that will be able to login to this application."""
try:
return int(val)
except ValueError:
raise cfig.InvalidValueError("Not an int.")
.. todo::
A few words about slower resolvers.
2022-04-20 23:32:20 +00:00
Adding CLI support
==================
.. todo::
What is the CLI and why is it useful?
.. code-block:: python
:emphasize-lines: 26,27
import cfig
import typing as t
config = cfig.Configuration()
@config.required()
def SECRET_PASSWORD(val: str) -> str:
"""The secret password required to use this application!"""
return val
@config.optional()
def SECRET_USERNAME(val: t.Optional[str]) -> str:
"""The username to require users to login as. If unset, defaults to `root`."""
if val is None:
return "root"
return val
@config.required()
def MAX_USERS(val: str) -> int:
"""The maximum number of users that will be able to login to this application."""
try:
return int(val)
except ValueError:
raise cfig.InvalidValueError("Not an int.")
if __name__ == "__main__":
config.cli()
.. todo::
What will be displayed here?
Use the configuration
=====================
.. todo::
How do I use the created values in my application?
.. todo::
Why does ``is None`` not work?