Getting Started
Installation
odin-control can be installed into your python environment with the following command:
For more detailed information and alternative installation methods, see the Installation Guide.
Running odin-control
You can verify that odin-control has been correctly installed into your python environment with the following command:
odin-control requires configuration to do anything useful. You can get help with its command-line options in the usual way:
$ odin_control --help
usage: odin_control [-h] [--version] [--config FILE] [--adapters ADAPTERS] [--http_addr HTTP_ADDR] [--http_port HTTP_PORT] [--enable_http ENABLE_HTTP]
[--https_port HTTPS_PORT] [--enable_https ENABLE_HTTPS] [--ssl_cert_file SSL_CERT_FILE] [--ssl_key_file SSL_KEY_FILE] [--debug_mode DEBUG_MODE]
[--access_logging debug|info|warning|error|none] [--static_path STATIC_PATH] [--enable_cors ENABLE_CORS] [--cors_origin CORS_ORIGIN]
[--api_version API_VERSION] [--graylog_server GRAYLOG_SERVER] [--graylog_logging_level GRAYLOG_LOGGING_LEVEL]
[--graylog_static_fields GRAYLOG_STATIC_FIELDS] [--log_file_max_size LOG_FILE_MAX_SIZE] [--log_file_num_backups LOG_FILE_NUM_BACKUPS]
[--log_file_prefix PATH] [--log_rotate_interval LOG_ROTATE_INTERVAL] [--log_rotate_mode LOG_ROTATE_MODE] [--log_rotate_when LOG_ROTATE_WHEN]
[--log_to_stderr LOG_TO_STDERR] [--logging debug|info|warning|error|none]
options:
-h, --help show this help message and exit
--version Show the server version information and exit
--config FILE Specify a configuration file to parse
--adapters ADAPTERS Comma-separated list of API adapters to load
<... snip ...>
--config
option:
where config_file_name points to a INI-style configuration file on your host. You can create a
simple example by pasting the follwing into a file (called, for example test.cfg):
[server]
debug_mode = 1
http_port = 8888
http_addr = 127.0.0.1
static_path = static
adapters = system_info
[tornado]
logging = debug
[adapter.system_info]
module = odin_control.adapters.system_info.SystemInfoAdapter
[D YYMMDD hh:mm:dd selector_events:64] Using selector: KqueueSelector
[D YYMMDD hh:mm:dd adapter:62] SystemInfoAdapter loaded
[D YYMMDD hh:mm:dd api:103] Registered API adapter class SystemInfoAdapter from module odin_control.adapters.system_info for path system_info
[D YYMMDD hh:mm:dd adapter:73] SystemInfoAdapter initialize called with 1 adapters
[W YYMMDD hh:mm:dd default:38] Default handler static path does not exist: static
[I YYMMDD hh:mm:dd server:81] HTTP server listening on 127.0.0.1:8888
Note
You can safely ignore the warning "Default handler static path does not exist" - more on that
later.
Warning
In the example, the http_addr parameter in the configuration limits access to the local
loopback network interface (127.0.0.1). You can modify this to suit your own environment
but exercise caution if exposing your odin-control instance to the wider network.
You can leave odin_control running to follow the next sections of this guide, or shut it down using
the usual key sequence, e.g. Ctrl-C.
Interacting with an API
You can now interact with an API provided by odin-control with a suitable client application. Curl is commonly used and widely available, but we recommend httpie for ease of use; it can be installed as a standalone application or into your python virtual environment if you prefer.
For instance, so see what API adapters are loaded, enter the following command:
which will return output like the following:
HTTP/1.1 200 OK
Content-Length: 143
Content-Type: application/json; charset=UTF-8
Date: Fri, 06 Mar 2026 09:25:29 GMT
Etag: "38fdbbb91794fef1105f7ff38f1f60f92c277559"
Server: TornadoServer/6.4.1
{
"adapters": {
"system_info": {
"module": "odin_control.adapters.system_info.SystemInfoAdapter",
"version": "2.0.0"
}
}
}
Note
An equivalent command using curl would be:
curl -s http://127.0.0.1:8888/api/adapters | python -m json.tool.
Piping the output to python -m json.tool formats the response for better readability.
Note that the response from odin-control is JSON-formatted; this is the common content type used to
interact with APIs in odin-control. The ./api/adapters endpoint is bulit into odin-control and
returns information about the loaded adapters, which python package and module they are provided by,
and version information. This allows a client to interrogate a running instance to determine what is
loaded. In this case a single adapter system_info is loaded, which is provided by the odin-control
package itself.
To interact with the system_info adapter API, enter the following command:
which will return the following (with HTTP headers removed for clarity):
{
"description": "Information about the system hosting this odin server instance",
"name": "system_info",
"odin_version": "2.0.0",
"platform": {
"description": "Information about the underlying platform",
"name": "platform",
"node": "hostname.example.com",
"processor": "arm",
"release": "25.3.0",
"system": "Darwin",
"version": "Darwin Kernel Version 25.3.0: Wed Jan 28 20:53:05 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6020"
},
"python_version": "3.12.11",
"server_uptime": 7106.5337200164795,
"tornado_version": "6.4.1"
}
server_uptime value, enter the
following:
which will return just the value of the server_uptime parameter:
returns the platform subtree:
{
"description": "Information about the underlying platform",
"name": "platform",
"node": "hostname.example.com",
"processor": "arm",
"release": "25.3.0",
"system": "Darwin",
"version": "Darwin Kernel Version 25.3.0: Wed Jan 28 20:53:05 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6020"
}
Modifying state
So far, all the interaction with odin-control has been to read the state an adapter. In a REST-like API this corresponds to making HTTP GET requests. To modify the state of one or more parameters in an adapter, PUT requests are used with a JSON payload containing the new values.
The system_info adapter used above does not expose any read-write parameters. A simple example is
available in the odin-workshop repository. To use this,
first clone the repository:
Change directory to the location of the example adapter:
and install the adapter into your python environment (where odin-control is already installed):
Note
If you wish to try modifying the adapter code, it can also be installed in
editable mode
by using the -e command option.
The repository also contains an example configuration file, or you can create it yourself:
[server]
debug_mode = 1
http_port = 8888
http_addr = 127.0.0.1
static_path = test/static
adapters = workshop, system_info
[tornado]
logging = debug
[adapter.workshop]
module = workshop.adapter.WorkshopAdapter
background_task_enable = 1
background_task_interval = 1.0
[adapter.system_info]
module = odin_control.adapters.system_info.SystemInfoAdapter
Note
This configuration also loads the system_info adapter and shows how multiple adapters can
be run and configured.
Run odin-control with this configuration:
and note that the output shows the adapter incrementing in two background tasks:
[D YYMMDD hh:mm:ss selector_events:64] Using selector: KqueueSelector
[D YYMMDD hh:mm:ss adapter:62] WorkshopAdapter loaded
[D YYMMDD hh:mm:ss controller:120] Launching background tasks with interval 1.00 secs
[D YYMMDD hh:mm:ss adapter:41] WorkshopAdapter loaded
[D YYMMDD hh:mm:ss api:101] Registered API adapter class WorkshopAdapter from module workshop.adapter for path workshop
[D YYMMDD hh:mm:ss adapter:62] SystemInfoAdapter loaded
[D YYMMDD hh:mm:ss api:101] Registered API adapter class SystemInfoAdapter from module odin_control.adapters.system_info for path system_info
[D YYMMDD hh:mm:ss adapter:73] WorkshopAdapter initialize called with 2 adapters
[W YYMMDD hh:mm:ss adapter:83] WorkshopAdapter controller has no initialize method
[D YYMMDD hh:mm:ss adapter:73] SystemInfoAdapter initialize called with 2 adapters
[D YYMMDD hh:mm:ss default:40] Static path for default handler is test/static
[I YYMMDD hh:mm:ss server:81] HTTP server listening on 127.0.0.1:8888
[D YYMMDD hh:mm:ss controller:148] Background IOLoop task running, count = 0
[D YYMMDD hh:mm:ss controller:167] Background thread task running, count = 0
[D YYMMDD hh:mm:ss controller:148] Background IOLoop task running, count = 1
[D YYMMDD hh:mm:ss controller:167] Background thread task running, count = 1
[D YYMMDD hh:mm:ss controller:148] Background IOLoop task running, count = 2
[D YYMMDD hh:mm:ss controller:167] Background thread task running, count = 2
The adapter exposes a sub-tree of parameters related to the background tasks:
returns:
The enable and interval parameters are read-write in this instance. You can stop the background
tasks by setting enable to false using a PUT request:
Note
This command is using httpie's implicit JSON support and
JSON field syntax to create the
PUT request body. The equivalent curl command is (the much more verbose):
The output will show the background tasks stopping and no futher status reports:
[D YYMMDD hh:mm:ss server:141] 200 PUT /api/workshop/background_task (127.0.0.1) 1.13ms
[D YYMMDD hh:mm:ss controller:172] Background thread task stopping
You can also increase the speed of the counters by setting the interval:
and re-enabling the tasks:
which will give the following output:
[D YYMMDD hh:mm:ss controller:105] Setting background task interval to 0.500000
[D YYMMDD hh:mm:ss adapter:91] {'ioloop_count': 535, 'thread_count': 533, 'enable': False, 'interval': 0.5}
[D YYMMDD hh:mm:ss server:141] 200 PUT /api/workshop/background_task (127.0.0.1) 2.62ms
[D YYMMDD hh:mm:ss controller:120] Launching background tasks with interval 0.50 secs
[D YYMMDD hh:mm:ss adapter:91] {'ioloop_count': 535, 'thread_count': 533, 'enable': True, 'interval': 0.5}
[D YYMMDD hh:mm:ss server:141] 200 PUT /api/workshop/background_task (127.0.0.1) 0.85ms
[D YYMMDD hh:mm:ss controller:148] Background IOLoop task running, count = 540
[D YYMMDD hh:mm:ss controller:167] Background thread task running, count = 540
[D YYMMDD hh:mm:ss controller:148] Background IOLoop task running, count = 560
[D YYMMDD hh:mm:ss controller:167] Background thread task running, count = 560
Going further
Refer to the user guide to learn more about installation, configuration and the key concepts of odin-control. The developer guide explains more details on how to implement adapters for controlling systems.