Configuration Elements
Configuration elements are the building blocks of a pydoover configuration schema. Each element type maps to a JSON Schema type and provides validation, UI rendering, and type-safe value access.
Import
from pydoover import config
Common Properties
All configuration elements share these common properties:
| Property | Type | Default | Description |
|---|---|---|---|
display_name | str | Required | The label shown in the UI |
default | varies | NotSet | Default value; if not set, element is required |
description | str | None | Help text displayed in the UI |
hidden | bool | False | Whether to hide the element in the UI |
deprecated | bool | None | Marks the element as deprecated |
position | int | None | Override automatic ordering |
Required vs Optional
Elements without a default are required. Elements with a default are optional:
# Required - user must provide a value
api_key = config.String("API Key")
# Optional - uses default if not provided
timeout = config.Integer("Timeout", default=30)
The value Property
After configuration injection, access the element's value:
class MyConfig(config.Schema):
def __init__(self):
self.timeout = config.Integer("Timeout", default=30)
# In your application:
timeout_value = self.config.timeout.value # Returns int
Accessing value before injection raises ValueError.
Integer
Represents a JSON integer type. Internally stored as Python int.
config.Integer(
display_name: str,
*,
default: int = NotSet,
description: str = None,
hidden: bool = False,
deprecated: bool = None,
minimum: int = None,
exclusive_minimum: int = None,
maximum: int = None,
exclusive_maximum: int = None,
multiple_of: int = None
)
Integer Constraints
| Parameter | Description |
|---|---|
minimum | Value must be >= this |
exclusive_minimum | Value must be > this |
maximum | Value must be <= this |
exclusive_maximum | Value must be < this |
multiple_of | Value must be divisible by this |
Integer Examples
# Basic integer
pin_number = config.Integer("Pin Number", default=1)
# With range constraints
temperature = config.Integer(
"Temperature Setpoint",
default=25,
minimum=0,
maximum=100,
description="Target temperature in degrees Celsius"
)
# Must be positive (exclusive minimum)
count = config.Integer(
"Item Count",
exclusive_minimum=0,
description="Must be at least 1"
)
# Multiple of a value
step_size = config.Integer(
"Step Size",
default=10,
multiple_of=5,
description="Must be a multiple of 5"
)
Number
Represents a JSON number type for floating-point values. Internally stored as Python float. Inherits all constraints from Integer.
config.Number(
display_name: str,
*,
default: float = NotSet,
description: str = None,
hidden: bool = False,
deprecated: bool = None,
minimum: float = None,
exclusive_minimum: float = None,
maximum: float = None,
exclusive_maximum: float = None,
multiple_of: float = None
)
Number Examples
# Basic number
voltage = config.Number("Voltage", default=3.3)
# With constraints
gain = config.Number(
"Amplifier Gain",
default=1.0,
minimum=0.1,
maximum=10.0,
description="Signal amplification factor"
)
# Percentage value
threshold = config.Number(
"Threshold Percentage",
default=0.5,
minimum=0.0,
maximum=1.0
)
Boolean
Represents a JSON boolean type. Internally stored as Python bool.
config.Boolean(
display_name: str,
*,
default: bool = NotSet,
description: str = None,
hidden: bool = False,
deprecated: bool = None
)
Boolean Examples
# Toggle feature
enable_logging = config.Boolean(
"Enable Logging",
default=True,
description="Whether to log debug information"
)
# Required boolean
accept_terms = config.Boolean(
"Accept Terms",
description="User must accept terms of service"
)
String
Represents a JSON string type. Internally stored as Python str.
config.String(
display_name: str,
*,
default: str = NotSet,
description: str = None,
hidden: bool = False,
deprecated: bool = None,
length: int = None,
pattern: str = None
)
String Constraints
| Parameter | Description |
|---|---|
length | Exact length the string must have |
pattern | Regex pattern the string must match |
String Examples
# Basic string
device_name = config.String(
"Device Name",
default="Sensor-01",
description="Human-readable device identifier"
)
# With pattern validation (email format)
contact_email = config.String(
"Contact Email",
pattern=r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
description="Notification email address"
)
# Fixed length (e.g., product code)
product_code = config.String(
"Product Code",
length=8,
description="8-character product identifier"
)
# Hidden string (e.g., for internal use)
internal_id = config.String(
"Internal ID",
default="default-id",
hidden=True
)
Enum
Represents a choice selection. Rendered as a dropdown in the UI.
config.Enum(
display_name: str,
*,
choices: list | EnumType,
default: Any,
description: str = None,
hidden: bool = False,
deprecated: bool = None
)
Enum with String Choices
engine_type = config.Enum(
"Engine Type",
choices=["Honda", "John Deere", "Cat"],
default="Honda",
description="Type of diesel engine"
)
# Access value
engine = engine_type.value # Returns "Honda", "John Deere", or "Cat"
Enum with Python Enum
Using Python's enum.Enum provides type safety and allows custom attributes:
import enum
from pydoover import config
class SensorType(enum.Enum):
TEMPERATURE = "Temperature"
HUMIDITY = "Humidity"
PRESSURE = "Pressure"
class MyConfig(config.Schema):
def __init__(self):
self.sensor_type = config.Enum(
"Sensor Type",
choices=SensorType,
default=SensorType.TEMPERATURE
)
Enum with Custom Objects
Enum values can be objects with custom attributes. The object must implement __str__:
import enum
from pydoover import config
class SensorSpec:
def __init__(self, name: str, unit: str, precision: int):
self.name = name
self.unit = unit
self.precision = precision
def __str__(self):
return self.name
class SensorType(enum.Enum):
TEMPERATURE = SensorSpec("Temperature", "C", 2)
HUMIDITY = SensorSpec("Humidity", "%", 1)
PRESSURE = SensorSpec("Pressure", "kPa", 3)
class MyConfig(config.Schema):
def __init__(self):
self.sensor = config.Enum(
"Sensor",
choices=SensorType,
default=SensorType.TEMPERATURE
)
@property
def sensor_unit(self):
return self.sensor.value.unit # Access custom attribute
Array
Represents a JSON array type. Contains a list of elements of the same type.
config.Array(
display_name: str,
*,
element: ConfigElement = None,
min_items: int = None,
max_items: int = None,
unique_items: bool = None,
description: str = None,
hidden: bool = False,
deprecated: bool = None
)
Note: default values are not allowed for Array elements.
Array Parameters
| Parameter | Description |
|---|---|
element | The type of items in the array |
min_items | Minimum number of items required |
max_items | Maximum number of items allowed |
unique_items | Whether items must be unique |
Array Examples
# Array of strings
tags = config.Array(
"Tags",
element=config.String("Tag"),
min_items=1,
max_items=10,
unique_items=True,
description="List of tags for categorization"
)
# Array of integers
sensor_pins = config.Array(
"Sensor Pins",
element=config.Integer("Pin", minimum=0, maximum=40),
min_items=1,
description="GPIO pins connected to sensors"
)
# Accessing array values
for element in tags.elements:
print(element.value)
Array Value Access
Use the elements property to iterate over loaded values:
class MyConfig(config.Schema):
def __init__(self):
self.ports = config.Array(
"Ports",
element=config.Integer("Port", minimum=1, maximum=65535)
)
# After configuration injection:
for port_element in self.config.ports.elements:
print(port_element.value)
Object
Represents a JSON object type with nested properties. Rendered as a collapsible form section in the UI.
config.Object(
display_name: str,
*,
additional_elements: bool | dict = True,
collapsible: bool = True,
default_collapsed: bool = False,
description: str = None,
hidden: bool = False,
deprecated: bool = None
)
Note: default values are not allowed for Object elements.
Object Parameters
| Parameter | Description |
|---|---|
additional_elements | Allow properties not defined in schema |
collapsible | Whether the section can be collapsed in UI |
default_collapsed | Whether to start collapsed |
Adding Elements to Object
Use add_elements() or attribute assignment:
# Using add_elements()
pump_settings = config.Object("Pump Settings")
pump_settings.add_elements(
config.Integer("Pin", description="GPIO pin number"),
config.Number("On Time", default=5.0),
)
# Using attribute assignment
pump_settings = config.Object("Pump Settings")
pump_settings.pin = config.Integer("Pin")
pump_settings.on_time = config.Number("On Time", default=5.0)
Object Example
class MyConfig(config.Schema):
def __init__(self):
self.pump = config.Object(
"Pump Settings",
description="Configure the pump output"
)
self.pump.add_elements(
config.Integer(
"Digital Output Number",
description="The digital output pin"
),
config.Number(
"On Time",
default=5.2,
description="Run time in seconds"
),
)
# Access nested values
pin = self.config.pump.digital_output_number.value
on_time = self.config.pump.on_time.value
Variable
A special element that creates dynamic references to other configuration values. Variables are resolved at deployment time.
config.Variable(scope: str, name: str)
Variable Parameters
| Parameter | Description |
|---|---|
scope | The application or context name |
name | The configuration key to reference |
Variable Usage
Variables are typically used as default values:
class MyConfig(config.Schema):
def __init__(self):
# Reference a value from another app's config
self.device_id = config.String(
"Device ID",
default=config.Variable("device_manager", "primary_device_id")
)
The variable serializes to a string format: $scope.name
var = config.Variable("app", "setting")
str(var) # Returns "$app.setting"
Application
A special element that references other Doover applications. Rendered as a dropdown of installed applications in the UI.
config.Application(
display_name: str,
*,
default: str = NotSet,
description: str = None,
hidden: bool = False,
deprecated: bool = None
)
Application Example
class MyConfig(config.Schema):
def __init__(self):
self.data_source = config.Application(
"Data Source",
description="Select the application to receive data from"
)
# The value is the application identifier string
source_app_id = self.config.data_source.value
The Application element generates JSON Schema with format: "doover-application", which the Doover UI uses to render an application selector.
Element Summary
| Element | JSON Type | Python Type | Constraints |
|---|---|---|---|
Integer | integer | int | min, max, multipleOf |
Number | number | float | min, max, multipleOf |
Boolean | boolean | bool | None |
String | string | str | length, pattern |
Enum | string or number | varies | choices |
Array | array | list | minItems, maxItems, uniqueItems |
Object | object | nested | additionalElements |
Variable | N/A | reference | scope, name |
Application | string | str | format: doover-application |