-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
34 changed files
with
894 additions
and
455 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
echo "There's no need to execute anything before running" | ||
echo "There's no need to execute anything before running" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
echo "Use pyenv rehash before executing tests" | ||
pyenv rehash | ||
pyenv rehash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
Advanced Usage | ||
-------------- | ||
|
||
|
||
Most of the time you can use the ``prettyconf.config`` function to get your | ||
settings and use the ``prettyconf``'s standard behaviour. But some times | ||
you need to change this behaviour. | ||
|
||
To make this changes possible you can always create your own | ||
``Configuration()`` instance and change it's default behaviour: | ||
|
||
.. code-block:: python | ||
from prettyconf import Configuration | ||
config = Configuration() | ||
.. warning:: ``prettyconf`` will skip configuration files inside ``.zip``, | ||
``.egg`` or wheel packages. | ||
|
||
|
||
.. _discovery-customization: | ||
|
||
Customizing the configuration discovery | ||
+++++++++++++++++++++++++++++++++++++++ | ||
|
||
By default the library will use the envrionment and the directory of the file | ||
where ``config()`` was called as the start directory to look for a ``.env`` | ||
configuration file. Consider the following file structure: | ||
|
||
.. code-block:: text | ||
project/ | ||
app/ | ||
.env | ||
config.ini | ||
settings.py | ||
If you call ``config()`` from ``project/app/settings.py`` the library will | ||
inspect the envrionment and then look for configuration files at | ||
``project/app``. | ||
|
||
You can change that behaviour, by customizing configuration loaders to look at | ||
a different ``path`` when instantiating your ``Configuration()``: | ||
|
||
.. code-block:: python | ||
# Code example in project/app/settings.py | ||
import os | ||
from prettyconf import Configuration | ||
from prettyconf.loaders import Environment, EnvFile | ||
project_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..')) | ||
env_file = f"{project_path}/.env" | ||
config = Configuration(loaders=[Environment(), EnvFile(filename=env_file)]) | ||
The example above will start looking for configuration in the environment and | ||
then in a ``.env`` file at ``project/`` instead of ``project/app``. | ||
|
||
Because ``config`` is nothing but an already instantiated ``Configuration`` object, | ||
you can also alter this ``loaders`` attribute in ``prettyconf.config`` before use it: | ||
|
||
.. code-block:: python | ||
# Code example in project/app/settings.py | ||
import os | ||
from prettyconf import config | ||
from prettyconf.loaders import Environment, EnvFile | ||
project_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..')) | ||
env_file = f"{project_path}/.env" | ||
config.loaders = [Environment(), EnvFile(filename=env_file)] | ||
Read more about how loaders can be configured in the :doc:`loaders section<loaders>`. | ||
|
||
.. _variable-naming: | ||
|
||
Naming conventions for variables | ||
++++++++++++++++++++++++++++++++ | ||
|
||
There happen to be some formating conventions for configuration paramenters | ||
based on where they are set. For example, it is common to name environment | ||
variables in uppercase: | ||
|
||
.. code-block:: sh | ||
$ DEBUG=yes OTHER_CONFIG=10 ./app.py | ||
but if you were to set this config in an ``.ini`` file, it should probably be | ||
in lower case: | ||
|
||
.. code-block:: ini | ||
[settings] | ||
debug=yes | ||
other_config=10 | ||
command line argments have yet another conventions: | ||
|
||
.. code-block:: sh | ||
$ ./app.py --debug=yes --another-config=10 | ||
Prettyconf let's you follow these aesthetics patterns by setting a | ||
``var_format`` function when instantiating the :doc:`loaders<loaders>`. | ||
|
||
By default, the :py:class:`Environment<prettyconf.loaders.Environment>` is | ||
instantiated with ``var_format=str.upper`` so that lookups play nice with the | ||
env variables. | ||
|
||
.. code-block:: python | ||
from prettyconf import Configuration | ||
from prettyconf.loaders import Environment | ||
config = Configuration(loaders=[Environment(var_format=str.upper)]) | ||
debug = config('debug', default=False, cast=config.boolean) # lookups for DEBUG=[yes|no] | ||
Writing your own loader | ||
+++++++++++++++++++++++ | ||
|
||
If you need a custom loader, you should just extend the :py:class:`AbstractConfigurationLoader<prettyconf.loaders.AbstractConfigurationLoader>`. | ||
|
||
.. autoclass:: prettyconf.loaders.AbstractConfigurationLoader | ||
|
||
For example, say you want to write a Yaml loader. It is important to note | ||
that by raising a ``KeyError`` exception from the loader, prettyconf knows | ||
that it has to keep looking down the loaders chain for a specific config. | ||
|
||
.. code-block:: python | ||
import yaml | ||
from prettyconf.loaders import AbstractConfigurationLoader | ||
class YamlFile(AbstractConfigurationLoader): | ||
def __init__(self, filename): | ||
self.filename = filename | ||
self.config = None | ||
def _parse(self): | ||
if self.config is not None: | ||
return | ||
with open(self.filename, 'r') as f: | ||
self.config = yaml.load(f) | ||
def __contains__(self, item): | ||
try: | ||
self._parse() | ||
except: | ||
return False | ||
return item in self.config | ||
def __getitem__(self, item): | ||
try: | ||
self._parse() | ||
except: | ||
# KeyError tells prettyconf to keep looking elsewhere! | ||
raise KeyError("{!r}".format(item)) | ||
return self.config[item] | ||
Then configure prettyconf to use it. | ||
|
||
.. code-block:: python | ||
from prettyconf import config | ||
config.loaders = [YamlFile('config.yml')] | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
Changelog | ||
--------- | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
This project adheres to `Semantic Versioning`_. | ||
|
||
.. _`Semantic Versioning`: https://semver.org/spec/v2.0.0.html | ||
|
||
.. include:: ../../CHANGES.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,39 @@ | ||
What's prettyconf | ||
----------------- | ||
|
||
Pretty Conf is a Python library created to make easy the separation of | ||
configuration and code following the recomendations of `12 Factor`_'s topic | ||
about configs. | ||
Prettyconf is a framework agnostic python library created to make easy the | ||
separation of configuration and code following the recomendations of `12 | ||
Factor`_'s topic about configs. | ||
|
||
|
||
Motivation | ||
++++++++++ | ||
|
||
Configuration is just another API of you app, aimed for users who will install | ||
and run it, that allows them to *preset* the state of a program, without having | ||
to interact with it, only through static files or environment variables. | ||
|
||
It is an important aspect of the architecture of any system, yet it is | ||
sometimes overlooked. | ||
|
||
It is important to provide a clear separation of configuration and code. This | ||
is because config varies substantially across deploys and executions, code | ||
should not. The same code can be run inside a container or in a regular | ||
machine, it can be executed in production or in testing environments. | ||
|
||
Well designed applications allow different ways to be configured. A proper | ||
settings-discoverability chain goes as follows: | ||
|
||
1. First CLI args are checked. | ||
2. Then Environment variables. | ||
3. Config files in different directories, that also imply some hierarchy. For | ||
example: config files in ``/etc/myapp/settings.ini`` are applied | ||
system-wide, while ``~/.config/myapp/settings.ini`` take precedence and are | ||
user-specific. | ||
4. Hardcoded constants. | ||
|
||
This raises the need to consolidate configuration in a single source of truth | ||
to avoid having config management scattered all over the codebase. | ||
|
||
|
||
.. _`12 Factor`: http://12factor.net/ |
Oops, something went wrong.