Skip to main content

pjdev-armis-sdk

PyPI - Version PyPI - Python Version


Async Python SDK for the Armis API, built on httpx and pydantic.

Table of Contents

Installation

pip install pjdev-armis-sdk

Usage

Configure once at startup (reads from environment variables prefixed with ARMIS_):

from pjdev_armis_sdk import config_service

config_service.init(
    instance_url="https://your-tenant.armis.com",
    secret_key="your-secret-key",
)

Then call any of the resource modules:

from pjdev_armis_sdk import devices, search

# AQL search
result = await search.aql_search("in:devices type:MOBILE_PHONE")

# Lookup a single device by id
device = await devices.get_device(id=12345)

# Set / remove custom properties across many devices in one request
await devices.bulk_device_custom_properties([
    devices.custom_property_upsert_op(12345, "location", "Building 4"),
    devices.custom_property_delete_op(67890, "owner"),
])

Auth (Authorization header with a temporary access token) is handled automatically by the underlying httpx.AsyncClient. Tokens are refreshed on the fly when they expire or when the API returns 401.

Retries and backoff

Every endpoint call retries transient failures with capped, jittered exponential backoff. Retry N waits http_retry_delay_seconds * 2 ** (N - 1) seconds, clamped to http_retry_max_delay_seconds and then scaled by a random factor in [0.5, 1.0]. A Retry-After header on a retried response is honored instead — both the delay-seconds and HTTP-date forms — clamped to the same ceiling.

Config knobs (all readable as ARMIS_-prefixed environment variables):

Setting Default Meaning
http_retry_max_count 5 Maximum attempts per call.
http_retry_delay_seconds 2 Base delay; doubles each retry.
http_retry_max_delay_seconds 60.0 Ceiling for any single wait.
http_retry_jitter True Spread out callers that failed together.

What is retried: any status not listed in a call's status_codes_to_ignore, plus transport failures (httpx.TransportError — connect errors, read/write and pool timeouts, protocol errors). 400, 403 and 404 are treated as deterministic and fail immediately.

401 is retried, with one deliberate exception. For ordinary endpoints a 401 means a stale access token, and it is worth retrying — note that ArmisAccessTokenAuth has already re-authenticated and replayed the request once, with no delay, before the retry layer ever sees it, so what retrying adds is elapsed time for a transient condition to clear. Against the token endpoint itself a 401 means the secret key is wrong, which no retry can fix, so access_token.get_access_token() and failed token fetches inside the auth flow fail fast on any 4xx and retry only on 429 or 5xx.

Consumers that need different behavior can override per call site without changing the shared defaults:

from pjdev_armis_sdk.api_utilities import async_retry_http

# Retry a status that this call site would otherwise treat as fatal.
@async_retry_http(status_codes_to_ignore=[400, 403], retry_status_codes=[409])
async def my_call() -> None: ...

retry_status_codes takes precedence over status_codes_to_ignore; passing only the latter behaves exactly as it always has. It is an override layered on the base rule, never an allowlist — it widens what is retried, never narrows it.

Writes that are not safe to repeat

Creates, and actions like _run_now/ that trigger work, are marked idempotent=False. On those calls the SDK retries only failures that prove the request never landed:

Never landed — safe to retry ConnectError, ConnectTimeout, PoolTimeout (no connection was ever established, so nothing was transmitted) and 401 (rejected at the authentication boundary before the handler runs)
May have landed — not retried ReadTimeout, WriteTimeout, ReadError, WriteError, RemoteProtocolError (the request was on the wire and the response was lost) and every 4xx/5xx other than 401

The question for a write is not "is this failure transient?" but "could the server have applied the write and still returned this?" A 504 or a ReadTimeout means the request arrived and the response was lost — the write may well have landed, so repeating it creates a duplicate. Armis offers no idempotency key, so nothing about the request lets the SDK work this out for itself; it has to be declared at the call site.

Note this is not a read/write split. A connection refused mid-deploy is the commonest transient failure there is, and it stays retryable on every endpoint including creates, because a refused connection cannot have written anything.

Affected: create_user, create_site, create_boundary, create_integration, create_integration_v2, run_silk_integration, run_va_integration, add_site_integration_id, add_site_network_equipment, bulk_add_site_network_equipment.

The last three are a deliberate conservative guess, not a known fact: they POST an id into a collection, and if Armis stores that collection as a set they are harmless to repeat and the flag costs retry resilience for nothing. The guess is made on cost asymmetry — a wrong False costs availability, a wrong True costs duplicate data — and confirmation from Armis that POSTing an already-present id is a no-op would settle it.

Not affected, because repeating them is harmless: every read, the update_* / patch_* calls (they set fields to given values), the delete_* calls, add_device_tags / remove_device_tags (set semantics), and bulk_upsert_devices (upsert keyed by macAddress), and bulk_device_custom_properties (upsert/delete keyed by device id and property key).

Upgrading

Which statuses retry is unchanged for callers that pass only status_codes_to_ignore. Two timing changes are visible without any code change on your side:

  • Transport failures other than ConnectError — read/write and pool timeouts, protocol errors — are now retried instead of propagating after one attempt. A call that used to fail fast on a ReadTimeout now consumes its retry budget and the wall-clock time that goes with it.

  • Jitter is on by default, so a delay is 0.5x–1.0x of the computed value. At the default http_retry_delay_seconds=2 the schedule was 2, 4, 8, 16 and is now 1–2, 2–4, 4–8, 8–16. Set http_retry_jitter=False for the exact old schedule.

  • Creates no longer survive a transient 5xx or 429. This is the change most likely to affect you, and it is a reduction in write resilience, not only a bug fix. The ten non-idempotent calls listed above previously retried those statuses up to http_retry_max_count times; they now fail on the first one. If you have code relying on create_user riding out a brief 503, it will now raise where it used to succeed, and the caller has to decide whether to retry.

    The trade is deliberate: a duplicate user is worse than a failed create the caller can retry on purpose. Note this closes a pre-existing hole as well as a recent one — a 504 on a create could already produce duplicate rows before this release, because any status outside status_codes_to_ignore was retried. Connection failures are unaffected and still retry, since they cannot duplicate anything.

License

pjdev-armis-sdk is distributed under the terms of the MIT license.

Metadata

Release files for pjdev-armis-sdk 2026.1007.82101

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pjdev-armis-sdk 2026.1007.82101
File Size Uploaded Provenance Actions
pjdev_armis_sdk-2026.1007.82101.tar.gz 23.3 kB Without provenance Details for pjdev_armis_sdk-2026.1007.82101.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pjdev-armis-sdk 2026.1007.82101
File Interpreter ABI Platform Actions
pjdev_armis_sdk-2026.1007.82101-py3-none-any.whl Python 3 none any Details for pjdev_armis_sdk-2026.1007.82101-py3-none-any.whl

Total release size: 52.8 kB

Release files / pjdev_armis_sdk-2026.1007.82101.tar.gz

Download URL pjdev_armis_sdk-2026.1007.82101.tar.gz
Size 23.3 kB
Tags Source
SHA-256 checksum
How to use checksums
9a974c46e466ef481ab5ca34a373544eadef952fa192684049e9a39e48c2242e
BLAKE2b-256 checksum
How to use checksums
bbd3dee3502dc251a5368894d6786f34b4ad80a4b1d80dd6b9009d99db39a3c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.18.1 {"ci":true,"cpu":"aarch64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.12.3"},"installer":{"name":"hatch","version":"1.18.1"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.12.3","system":{"name":"Linux","release":"7.0.12-linuxkit"}} HTTPX2/2.13.1

Release files / pjdev_armis_sdk-2026.1007.82101-py3-none-any.whl

Download URL pjdev_armis_sdk-2026.1007.82101-py3-none-any.whl
Size 29.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cb0369738547758f9326f0413b391d1eee6cdcf65ce42a9368e31d14f8344c41
BLAKE2b-256 checksum
How to use checksums
ec7854845f0af49acc040f71f768304975adffe22bb718844a0d929975dcac16
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.18.1 {"ci":true,"cpu":"aarch64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.12.3"},"installer":{"name":"hatch","version":"1.18.1"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.12.3","system":{"name":"Linux","release":"7.0.12-linuxkit"}} HTTPX2/2.13.1

Security for pjdev-armis-sdk 2026.1007.82101

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page