From source
If you have a connector's Python project, cloned from source or scaffolded with the connector-factory, you can configure and run it directly with uv, hatch, or poetry. This is the typical workflow during connector development and for advanced deployments where you run the connector from its project rather than as a packaged executable.
Create a configuration file
A connector is configured through a config.json (or config.yaml) file. Generate one with the config create command:
uv run config create --app unitelabs.connector_starter:create_app
hatch run config create --app unitelabs.connector_starter:create_app
poetry run config create --app unitelabs.connector_starter:create_app
--app option is required for Windows. On MacOS and Linux, commands like connector start and config will generally work without providing this option. On these operating systems, needing to provide --app often points to an error in the connector package.The create command by default will create a file called config.json in the current working directory. We support yaml and json file-types and allow users to specify their own path and file type by adding the --path argument:
uv run config create --app unitelabs.connector_starter:create_app --path /path/to/config.prod.json
hatch run config create --app unitelabs.connector_starter:create_app --path /path/to/config.prod.json
poetry run config create --app unitelabs.connector_starter:create_app --path /path/to/config.prod.json
Run the connector
Starting the connector named connector-starter with a configuration file at the default path is as simple as:
uv run connector start --app unitelabs.connector_starter:create_app
hatch run connector start --app unitelabs.connector_starter:create_app
poetry run connector start --app unitelabs.connector_starter:create_app
Both connector start and certificate generate CLIs have a --config-path or -cfg argument that allows one to pass in a path to their configuration file, enabling users to create and apply multiple configurations for their connectors.
uv run connector start --app unitelabs.connector_starter:create_app -cfg /path/to/config.prod.json
hatch run connector start --app unitelabs.connector_starter:create_app -cfg /path/to/config.prod.json
poetry run connector start --app unitelabs.connector_starter:create_app -cfg /path/to/config.prod.json
-v/--verbose CLI flag on start and dev is deprecated and will be removed in future versions. Until then it overrides the root config level. Configure the log level through the logging section instead.For more information about the config CLI, check out the help documentation:
uv run config --help
hatch run config --help
poetry run config --help
or for a sub-command, e.g. create:
uv run config create --help
hatch run config create --help
poetry run config create --help
Logging
A connector logs its activity so you can monitor it and diagnose problems. There is no need to set anything up to get useful logs.
Leaving the logging field of your configuration unset (null, the default) applies sensible, command-specific presets automatically:
| Command | Console (stderr) | JSON log file (./logs/connector.log) |
|---|---|---|
connector dev | DEBUG, human-readable | — |
connector start | INFO, human-readable | DEBUG, structured JSON |
In production (connector start) the console shows INFO and above for a readable live view, while the rotating file records everything from DEBUG up as structured JSON for troubleshooting. Once the active file reaches 5 MB it rolls over to connector.log.1, connector.log.2, and so on. By default the connector keeps the active file plus the 199 most recent rotated files (backupCount), deleting the oldest on each rollover:
./logs/
├── connector.log ← active file
├── connector.log.1 ← most recent rotation
├── connector.log.2 ← ...
└── connector.log.199 ← oldest kept; deleted on the next rollover
backupCount default is a safety cap to stop logs from filling the disk. It bounds total usage to roughly 1 GB.
It is not a retention or archival policy. It is the connector user's responsibility to manage log files by shipping them to a log aggregator, rotating them with an external tool, or backing them up before they are deleted. If you don't need a large local buffer, or don't care about the logs except for error debugging in case of crashes, you can lower backupCount (or maxBytes) in your logging config; setting backupCount to 0 keeps only the active file. For more information how to configure the file handler read the respective logging.handlers.RotatingFileHandler documentation.Customizing the logging configuration
To change the defaults, set the logging field to a standard Python logging configuration dictionary. Once set, your configuration is used for every command, overwriting the defaults.
To scaffold a new config file pre-populated with a preset, use the --explicit-logging/-x flag of config create. The flag defaults to prod:
uv run config create --app unitelabs.connector_starter:create_app -x prod
hatch run config create --app unitelabs.connector_starter:create_app -x prod
poetry run config create --app unitelabs.connector_starter:create_app -x prod
Alternatively, copy one of the presets below into the logging section of your config file and adapt it:
"logging": {
"version": 1,
"disable_existing_loggers": false,
"handlers": {
"file": {
"class": "unitelabs.cdk.logging.RotatingStructlogHandler",
"filename": "./logs/connector.log",
"maxBytes": 5242880,
"backupCount": 200,
"encoding": "utf-8",
"level": "DEBUG"
},
"console": {
"class": "unitelabs.cdk.logging.ConsoleHandler",
"level": "INFO"
}
},
"root": {
"level": "DEBUG",
"handlers": ["file", "console"]
}
}
"logging": {
"version": 1,
"disable_existing_loggers": false,
"handlers": {
"console": {
"class": "unitelabs.cdk.logging.ConsoleHandler"
}
},
"root": {
"level": "DEBUG",
"handlers": ["console"]
}
}
Adjusting log levels per module
Loggers are organized hierarchically by dotted path, so any module can be tuned independently by adding a loggers entry with its own level, while root sets the default for everything else:
"logging": {
...
"loggers": {
"sila.server.cloud_server": {
"level": "INFO"
},
"unitelabs.cdk": {
"level": "WARNING"
},
"connector_name": {
"level": "DEBUG"
}
},
...
}
In the example above:
sila.server.cloud_server— the cloud server module emitsINFOand above, dropping itsDEBUGrecords.unitelabs.cdk— everything within the CDK emitsWARNINGand above only.connector_name— everything that specific connector logs, down toDEBUG, is captured.
Use the connector
With your connector running, you can interact with your instrument in three ways:
- GroundControl — read values, trigger actions, and monitor activity directly from the edge app.
- UniteLabs Platform — view, inspect, and operate the connector from the Platform UI, and add it to workflows.
- SDK & REST API — control the connector programmatically: discover services, explore modules and actions, and subscribe to live data.