Python package and CLI for configuring Axis devices via their HTTPS APIs: device info and health, snapshots, network details, MQTT clients, analytics publishers, API discovery, SSH users and more.
See also ax-devil-mqtt and ax-devil-rtsp for related tools.
pip install ax-devil-device-apiSet environment variables to avoid repeating credentials and broker details:
AX_DEVIL_TARGET_ADDR– Device IP or hostnameAX_DEVIL_TARGET_USER– Device usernameAX_DEVIL_TARGET_PASS– Device passwordAX_DEVIL_MQTT_BROKER_ADDR– MQTT broker addressAX_DEVIL_MQTT_BROKER_PASS– MQTT broker passwordAX_DEVIL_USAGE_CLI– Set tounsafeto skip the HTTP confirmation prompt (defaults tosafe)
- Device info & readiness – model/firmware, system readiness, restart; CLI
device; Pythonclient.device - Network – interface details; CLI
network info; Pythonclient.network - Media – video channels, supported codecs/resolutions, saved stream profiles, and snapshots; CLI
media; Pythonclient.media - MQTT client – configure/activate/deactivate/status/config; CLI
mqtt; Pythonclient.mqtt_client - Analytics MQTT publishers – list/create/remove; CLI
analytics; Pythonclient.analytics_mqtt - Analytics metadata producers – list/enable/disable/sample/versions; CLI
analytics-metadata; Pythonclient.analytics_metadata - Device Configuration API discovery – list API definitions, inspect docs/models/OpenAPI; CLI
discovery; Pythonclient.discovery - Classic VAPIX API Discovery – query
getApiList/getSupportedVersions; Pythonclient.classic_discovery - Feature flags – list/get/set; CLI
features; Pythonclient.feature_flags - Geocoordinates – location/orientation get/set/apply; CLI
geocoordinates; Pythonclient.geocoordinates - SSH users – add/list/show/modify/remove; CLI
ssh; Pythonclient.ssh - Data transformation (v1beta) – list topics, list/create/remove jq expression-based transforms; CLI
data-transformation; Pythonclient.data_transformation
Analytics MQTT and data transformation availability depends on device firmware. Data transformation is a beta API.
The implementation follows the official Data transformation API:
outputTopic is the transform collection key, and dotted topic components are
sent as URL path segments for DELETE. A slash inside a component is percent-encoded.
MQTT protocol values follow the official MQTT client API:
tcp, ssl, ws, and wss.
- Systemready – check device readiness (no auth), supported API versions; CLI
systemready; Pythonclient.systemready - Legacy CGI diagnostics – server/crash reports, network traces, pings, port checks, core dumps; CLI
debug; Pythonclient.device_debug
ax-devil-device-api --help lists all subcommands. Global options: --device-ip/-a, --device-username/-u, --device-password/-p, --protocol [http|https], --port, --ca-bundle, and --no-verify-ssl.
HTTPS is the default and verifies certificates by default. Use --ca-bundle PATH for a PEM CA bundle accepted by Requests. Use --no-verify-ssl only when certificate verification is intentionally disabled. HTTP must be explicitly selected and is never secure; the CLI prompts before using it unless AX_DEVIL_USAGE_CLI=unsafe. The default port is 443 for HTTPS and 80 for HTTP; an explicit non-default port is included in the URL.
Common flows:
- Device checks and restart:
ax-devil-device-api device info \
--device-ip <device-ip> \
--device-username <username> \
--device-password <password>
ax-devil-device-api device health # systemready readiness check
ax-devil-device-api device restart --force- Capture a snapshot:
ax-devil-device-api media snapshot \
--device-ip <device-ip> \
--device-username <username> \
--device-password <password> \
--output snapshot.jpg
# Optional snapshot tuning:
ax-devil-device-api media snapshot --resolution 1920x1080 --compression 50 --device 1- Inspect video channels and saved stream profiles:
ax-devil-device-api media channels
ax-devil-device-api media stream-profiles
ax-devil-device-api media stream-profiles "Profile name"- Configure and inspect the device MQTT client:
ax-devil-device-api mqtt configure \
--device-ip <device-ip> \
--device-username <username> \
--device-password <password> \
--broker-address <broker-ip> \
--broker-port 1883 \
--protocol ssl
ax-devil-device-api mqtt status
ax-devil-device-api mqtt config- Network and geocoordinates:
ax-devil-device-api network info
ax-devil-device-api geocoordinates location set 59.3293 18.0686
ax-devil-device-api geocoordinates orientation set --heading 45 --tilt 5
ax-devil-device-api geocoordinates orientation apply- Manage analytics publishers:
ax-devil-device-api analytics sources
ax-devil-device-api analytics create pub-1 "com.axis.analytics_scene_description.v0.beta#1" "axis/events" --qos 1 --retain
ax-devil-device-api analytics list
ax-devil-device-api analytics remove pub-1- Manage analytics metadata producers:
ax-devil-device-api analytics-metadata list
ax-devil-device-api analytics-metadata enable metadata-producer --channel 1 --channel 2
ax-devil-device-api analytics-metadata sample metadata-producer --format json- Feature flags:
ax-devil-device-api features list
ax-devil-device-api features get my_flag other_flag
ax-devil-device-api features set my_flag=true other_flag=false --force- Inspect APIs exposed by the device:
ax-devil-device-api discovery list
ax-devil-device-api discovery info analytics-mqtt --docs-html-linkdiscovery uses the authenticated GET /config/discover Device Configuration
discovery endpoint. With no explicit version, it selects the highest SemVer
entry whose state is released; if none is released, selection fails with
FeatureError and an explicit version is required. It is distinct from classic
VAPIX API Discovery, whose documented security level is anonymous and which uses
POST /axis-cgi/apidiscovery.cgi JSON requests:
client.classic_discovery.get_api_list()
client.classic_discovery.get_supported_versions()For the documented legacy exception on AXIS OS 9.80 and 10.12, classic
discovery retries only a 401 response that advertises Basic or Digest
authentication. Other responses remain anonymous and are not retried with
credentials.
- Data transformation:
ax-devil-device-api data-transformation topics
ax-devil-device-api data-transformation list
ax-devil-device-api data-transformation create "input/topic" "output/topic" '.key'
ax-devil-device-api data-transformation remove "com.axis.dt.output.topic"- Check device readiness (no authentication required):
ax-devil-device-api systemready check --device-ip <device-ip>
ax-devil-device-api systemready check --timeout 30
ax-devil-device-api systemready versions- Manage SSH users or collect diagnostics:
ax-devil-device-api ssh add new-user --comment "Service account"
ax-devil-device-api ssh list
ax-devil-device-api ssh modify new-user --password
ax-devil-device-api debug download-server-report report.zip
ax-devil-device-api debug download-server-report report.zip --mode zip_with_image
ax-devil-device-api debug download-crash-report crash.tgz
ax-devil-device-api debug download-network-trace trace.pcap --duration 30 --interface eth0
ax-devil-device-api debug ping-test example.com
ax-devil-device-api debug port-open-test example.com 443These are legacy CGI diagnostics. Debug downloads require HTTP 200 and apply
representation guards: the server report must be application/zip with a ZIP
leading signature, but this is not full archive validation. The CLI defaults to
portable zip, recommended for broad product support. The Python API preserves
its compatibility default of zip_with_image; pass mode="zip" explicitly for
the portable mode. Both return application/zip. Crash reports must be gzip
data. Network traces use cmd=pcapdump and accept classic PCAP or PCAPNG data;
--duration must be a positive integer, and a supplied interface must be a
nonempty string. The Requests timeout is an inactivity timeout plus capture
duration grace, not a hard deadline. Ping and TCP tests return raw text.
Core-dump collection is legacy buffered, non-streaming I/O and may remain
active for a long time.
SSH management uses the released SSH Management API discovered through the
authenticated Device Configuration API discovery endpoint. It requires HTTPS;
there is no beta or hardcoded endpoint fallback. The API returns HTTP 200 for
successful add, list, show, modify, and remove operations. ssh add prompts
for a hidden confirmed password. ssh modify --password does the same; never
place an SSH password in command arguments.
import json
from ax_devil_device_api import Client, DeviceConfig
config = DeviceConfig.https(
host="192.168.1.81",
username="root",
password="pass",
verify_ssl=True,
)
with Client(config) as client:
info = client.device.get_info()
print(json.dumps(info, indent=2))
snapshot = client.media.get_snapshot()
tuned_snapshot = client.media.get_snapshot(resolution="1280x720", compression=50, camera_head=1)
video_channels = client.media.list_video_channels()
stream_profiles = client.media.list_stream_profiles()
mqtt_state = client.mqtt_client.get_state()For a private device CA, pass its PEM bundle to verify_ssl:
config = DeviceConfig.https(
host="192.168.1.81",
username="root",
password="pass",
verify_ssl="/path/to/device-ca-bundle.pem",
)AuthMethod.AUTO starts with an unauthenticated challenge request. It selects an advertised Digest or Basic challenge, preferring Digest, and then caches only a successful method. request_no_auth bypasses both cached authentication and session-level Authorization.
When debug callbacks or CLI --debug output are enabled, credentials and secret-like values are recursively redacted from headers, URLs, query parameters, and nested request bodies.
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytestThis project is an independent, community-driven implementation and is not affiliated with or endorsed by Axis Communications AB. For official APIs and development resources, see the Axis Developer Community.
MIT License - see LICENSE for details.
