You can create a new project using the cdev init
command.
The Cdev Sdk
provides a singleton object representing the information available for a project
such as the settings, components, and resource output. You can access the Project
object using the singleton.
from cdev import Project as cdev_project
myProject = cdev_project.instance()
An Environment
is an isolated version of a project
in the Cloud
. By default, a project comes with three environments: prod
, stage
, and dev
. You can create more environments using the cdev environment create
command.
Cdev provides a mechanism to manage settings per Environment
. These settings can be used to provide different values to the framework for different Environments
.
We built our settings starting from the Pydantic Settings module to provide a type safe mechanism for working with settings, and then we added an additional workflow inspired by the Django Settings module to provide flexibility when working with complex types (List, Dict, etc).
In your src
folder, create a new file called project_settings.py
. Then copy the following code into the file.
from core.constructs.settings import Settings class CustomSettings(Settings): SOME_KEY: str = "default_value"
Set this as the Settings
for the current Environment
using the following command.
cdev environment settings_information --key base_class --new-value src.project_settings.CustomSettings
This command sets the CustomSettings
class found in the src.project_settings
module as the default class to use for your Environment
Settings.
--new-value
parameter is <python_module>.<class_name>
, where the python_module
must be available on the python search path and contain the class class_name
that is a descendant of core.constructs.settings.Settings
.You can access the Settings via the Global Project
object.
from cdev import Project as cdev_project from src.project_settings import CustomSettings myProject = cdev_project.instance() mySettings: CustomSettings = myProject.settings print(mySettings.SOME_KEY)
myProject.settings.SOME_KEY
) without storing the settings in the mySettings
variable, but this step allows us to add a typing hint to help clarify the values we are using.All the custom setting classes will derive from the core.constructs.settings.Settings
class, which itself derives from the Pydantic BaseSettings Model
. Therefore, we can add additional settings by adding properties to the class with the defining type conditions. You must derive from the Settings
class to make sure that the needed settings for the framework to work are available.
from typing import Optional from core.constructs.settings import Settings class CustomSettings(Settings): SOME_KEY: str = "" ANOTHER_KEY: int = "" FINAL_KEY: Optional[str]
The ordering of the precedent for settings values is (from lowest to highest):
When creating a property, it is recommended to either provide a value as the default value or denote the property as Optional
.
from typing import Optional from core.constructs.settings import Settings class CustomSettings(Settings): SOME_KEY: str = "" ANOTHER_KEY: int = "" FINAL_KEY: Optional[str]
When a Cdev Environment
is created, a directory (settings/secrets/<your_environment>_secrets) is added to store the secret values for that Environment
. This directory is used when loading your settings module as the Secrets Directory for the Pydantic Base Settings. Following the Pydantic Documentation to set a secret, create a file name cdev_<property>
and add the value as the only thing in the file.
Create:
settings/secrets/<your_environment>_secrets/cdev_some_key
cdev_
prefix and the property written in lower case.Then add to the file:
somesecretvalue
You can use standard Environment Variables to set your settings values via Pydantic Base Settings support for Environment Variables.
export CDEV_SOME_KEY=somevalue
CDEV_
prefix.For more complex values, it can be helpful to write the values directly in Python. We felt that the Django framework handled this in an elegant way, so we modeled our system after theirs. Each Cdev Environment
comes with a python module that can be used to load complex values. You can set properties by setting them as variables in the module.
cdev
prefix when setting the propertiesfrom uuid import uuid4 SOME_KEY = f"random;{str(uuid4())}" ANOTHER_KEY = "somevalue".capitalize() FINAL_KEY = "hello"
As mentioned in the Django Settings documentation, the file is a valid python module therefor:
It doesn’t allow for Python syntax errors.
It can assign settings using normal Python syntax. For example:
ANOTHER_KEY = "somevalue".capitalize()
Each Cdev Environment
has it’s own dedicated dynamic module in the settings/
folder, but there is also a base_settings.py
module that is applied for all environments. This should be used to set values that are the same for all Environments
.
Settings Lifecycle
Setting
class is that it is initialized as a child of the Pydantic Base Settings
then the Dynamic Setting Modules are applied. This means if you have a required property that is only set via a Dynamic Setting Module, it will fail to initially create the class because of a Pydantic
validation error. This can be avoided by either providing a default value when creating the Custom Setting Class
or making the property as Optional
.