Deployment config

Deployment config in Confident is basically a dictionary of configurations values. Only one configuration will be loaded in execution time depends on a given deployment_name. Deployment configurations can be either python dict or a file (json or yaml).

 1multi_configs = {
 2                'prod': {
 3                    'host': 'https://prod_server',
 4                    'log_level': 'info'
 5                },
 6                'dev': {
 7                    'host': 'http://dev_server',
 8                    'log_level': 'debug'
 9                },
10                'local': {
11                    'host': 'localhost',
12                    'log_level': 'debug'
13                },
14}

app/configs.json

{
    "prod": {
        "host": "https://prod_server",
        "log_level": "info"
    },
    "dev": {
        "host": "http://dev_server",
        "log_level": "debug"
    },
    "local": {
        "host": "localhost",
        "log_level": "debug"
    }
}

The config class definition can be as follows:

1from confident import Confident
2
3class MainConfig(Confident):
4    host: str
5    port: int = 5000
6    log_level: str = 'error'

Now we can create the config object in several ways:

1# Using python dict:
2config_a = MainConfig(deployment_name='local', deployments=multi_configs)
3print(config_a)
4#> host='localhost' port=5000 log_level='debug'
5
6# Same, but from a file path:
7config_b = MainConfig(deployment_name='local', deployments='app/configs.json')
8print(config_b)
9#> host='localhost' port=5000 log_level='debug'

Deployment Field

If we want more flexibility in selecting the deployment to load, we can use a property to do so. deployment_field is a field declared in the Confident object that its value will define what will be the deployment_name.

1from confident import Confident
2
3class MainConfig(Confident):
4    current_deployment: str = 'local'  # <-- This will be our `deployment_field`.
5    host: str
6    port: int = 5000
7    log_level: str = 'error'

Now we can create the config object:

1config_a = MainConfig(deployment_field='current_deployment', deployments=multi_configs)
2print(config_a)
3#> current_deployment='local' host='localhost' port=5000 log_level='debug'

In the above example the deployment_field is current_deployment, the deployment_name in run time is local so the matching properties are loaded from the deployment_config. Notice that the deployment_field as every other field, can be loaded from a source:

1os.environ['current_deployment'] = 'dev'  # Setting the field as an environment variable.
2config_c = MainConfig(deployment_field='current_deployment', deployments='app/configs.json')
3print(config_c)
4#> current_deployment='dev' host='http://dev_server' port=5000 log_level='debug'

Selecting the deployment_field can be done in class definition using DeploymentField. DeploymentField has the same functionality as pydantic Field. Moreover, it is possible to declare the deployment_field inside a ConfidentConfig class (See below).

Declaration with `DeploymentField`:

1from confident import Confident, DeploymentField
2
3class MainConfig(Confident):
4    deployment: str = DeploymentField('local')  # <-- This will be our `deployment_field`.
5    host: str
6    port: int = 5000
7    log_level: str = 'error'

Declaration with `ConfidentConfig` class:

 1from confident import Confident
 2
 3class MainConfig(Confident):
 4    deployment: str = 'local'
 5    host: str
 6    port: int = 5000
 7    log_level: str = 'error'
 8
 9    class ConfidentConfig:
10        deployment_field = 'deployment'  # <-- Marking `deployment` as our `deployment_field`.

Usage is the same in both ways:

1import os
2
3os.environ['deployment'] = 'prod'
4
5config = MainConfig(deployments='app/configs.json')  # <-- No need to mention the `deployment_field`.
6print(config)
7#> deployment='prod' host='https://prod_server' port=5000 log_level='info'