Skip to main content

airom — Python SDK

Python SDK for AIROM, the open-source AI Bill of Materials (AIBOM) scanner. Discover AI assets — models, prompts, datasets, embeddings, vector databases, frameworks, serving infrastructure — across code, containers, and Kubernetes, and get them back as typed Python objects.

pip install airom

This installs both the airom command and the Python library — the wheel ships the scanner binary itself into your environment's bin/, so there is nothing else to install:

$ airom --version
airom 0.3.8

$ airom fs ./my-app -o table          # the CLI, globally

Quick start

import airom

inv = airom.fs("./my-app", min_confidence=0.8)

for c in inv.by_kind(airom.ComponentKind.HOSTED_LLM):
    print(c.name, c.provider.or_default("-"), c.confidence)
    for occ in c.evidence.occurrences:
        print(f"   {occ.location.path}:{occ.location.line}  [{occ.detector_id}]")
gpt-4.1 openai 0.87
   src/rag.py:88  [rules/openai/model-literal]
   src/agent.py:12  [rules/openai/sdk-import]

Every component carries the evidence that justifies it — that is the point of AIROM, and the SDK hands you all of it.

Scanning

airom.scan("./app")                       # auto-detect: path, git URL, or image ref
airom.fs("./app")                         # a directory tree
airom.repo("https://github.com/o/r")      # remote (shallow clone) or a local worktree
airom.image(input="img.tar")              # docker save -o img.tar <ref>
airom.k8s(manifests="./deploy")           # offline: enumerate workload images
airom.version()                           # the underlying binary's ToolInfo

Common keyword args mirror the CLI flags: select, rules, ignore, min_confidence, max_file_size, io_budget, parallel, no_cache, cache_dir, offline, stats, plus binary, timeout, and cwd. None leaves the tool's own default in place — the SDK never invents defaults.

min_confidence=0.8 is the practical high-signal filter: on general-purpose directories, extension-only dataset detection and keyword-only generation-param detection emit low-confidence (0.5–0.6) noise. Note the application root always survives the filter — it is the scan target, not a finding.

select tokens are detector IDs or tags, not languages — "-dataset/file", not "python". Run airom detectors list (or airom.raw(["detectors", "list"])) to see them.

Not wired yet: pulling an image from a live registry/daemon, and live-cluster Kubernetes scanning. Both fail with a clear error. Use image(input=...) / an OCI layout and k8s(manifests=...) today.

Tri-state fields

version, provider, download_location and release_time are tri-state, and the SDK preserves the distinction rather than collapsing it into None:

JSON Meaning Opt
key omitted does not apply Presence.ABSENT
null applies, but undetermined (SPDX NOASSERTION) Presence.UNKNOWN
a value known Presence.KNOWN
c.version.known           # bool — only True when a real value is present
c.version.or_none()       # value, or None (collapses absent and unknown)
c.version.or_default("-") # value, or your fallback
c.version.presence        # the full distinction, when you need it

Navigating the graph

inv.components                  # sorted, deterministic
inv.by_kind("vector-db", "framework")
inv.get("airom:1f3a9b2c4d5e6f70")
inv.application                 # the scan-root component
inv.edges_from(c.id)            # typed, evidenced relationships
inv.unknowns                    # "looked relevant, could not process" — honesty channel
inv.stats.files_walked          # requires stats=True
len(inv); [c for c in inv]      # Inventory is sized and iterable

CI gating

A fail_on match is a verdict, not an error — the scan succeeded and the AIBOM is complete, so it is reported rather than raised:

res = airom.execute(
    ["fs", "./app"],
    options=airom.ScanOptions(fail_on="hosted-llm&confidence>=0.9", exit_code=7),
)
if res.policy_matched:
    raise SystemExit(res.exit_code)

Often you don't need fail_on at all — you have the whole graph, so gate in Python:

risky = [c for c in inv if c.model and c.model.pickle_risk]
if risky:
    raise SystemExit(f"unsafe pickle globals in: {[c.name for c in risky]}")

Errors

Exception Raised when
BinaryNotFoundError the airom executable could not be located
ScanError a fatal scan failure (exit 2): unreadable target, clone failure, bad flags
OutputError no parseable AIBOM, or an unsupported schemaVersion

Detector errors are not exceptions: they degrade to inv.unknowns records and the scan still succeeds. That is AIROM's degrade-by-default contract, and the SDK preserves it.

The binary

The SDK shells out to the airom binary and decodes its native JSON — the lossless superset every other format (CycloneDX, SARIF, YAML, table) projects from. Resolution order:

  1. the binary= argument
  2. a copy bundled in the wheel (airom/_bin/airom)
  3. $AIROM_BINARY
  4. airom on PATH

Platform wheels bundle the binary as a script, so pip installs it into the environment's bin/ (Scripts\ on Windows): pip install airom gives you a working airom command on PATH and the importable library, with no Python shim in between. In a virtualenv it is on PATH as soon as the venv is active; pipx install airom or pip install --user airom puts it on PATH globally.

The library resolves the binary without relying on PATH at all (it consults the environment's scripts dir directly), so import airom works even from an unactivated venv's interpreter.

Platforms with no wheel

Wheels are published for macOS (Intel + Apple Silicon), Linux (x86-64 + arm64, glibc + musl), and Windows (x86-64 + arm64). Every one is installed and executed on the platform it targets before it is published; see the smoke jobs in release-pypi.yml.

Anywhere else, pip falls back to the sdist, which ships the Python library and no binary — and cannot build one, since it does not contain the Go module. Rather than install successfully and leave you without a scanner, that build now fails and says so. To proceed, either install the binary for your platform from the releases page and put it on your PATH, or take the library alone:

AIROM_SKIP_BUNDLE=1 pip install airom

The second form is the right one when you already run the standalone binary and only want import airom. Resolution then falls through to $AIROM_BINARY or airom on PATH.

Development

cd sdk/python
pip install -e ".[dev]"
pytest            # builds the binary from the checkout and tests against it
mypy && ruff check .

The suite runs against the real binary, not mocks: a wrapper tested only against mocks proves nothing about the contract it wraps.

Building a wheel needs the Go toolchain (the build hook compiles the binary with CGO_ENABLED=0) and fails without it, because a wheel with no binary installs no airom command. Set AIROM_SKIP_BUNDLE=1 for a pure-Python wheel on purpose.

Publishing

Releases are published by .github/workflows/release-pypi.yml using PyPI Trusted Publishing (OIDC): GitHub Actions authenticates to PyPI directly, so there is no API token stored as a secret, and none to leak or rotate.

One-time setup

On pypi.org/manage/account/publishing, add a pending publisher:

Field Value
PyPI project name airom
Owner airomhq
Repository name airom
Workflow name release-pypi.yml
Environment (leave blank)

That is all — no secret is added to GitHub.

Cutting a release

The workflow runs on every push to main that touches the SDK or the scanner, but publishes only when the version is new: PyPI permanently refuses to re-upload a version (even a deleted one), so the workflow compares __version__ against the index and skips cleanly if it is already there.

So a release is exactly one deliberate act:

# sdk/python/src/airom/__init__.py
__version__ = "0.1.0"     # bump, commit, merge to main -> published

Publishing is irreversible: a version number is burned forever once used, and yanking does not free it. Test the whole path first with the manual workflow_dispatch run against TestPyPI (which needs its own pending publisher at test.pypi.org).

License

Apache-2.0, same as AIROM.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

airom-0.3.8.tar.gz (26.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

airom-0.3.8-py3-none-win_arm64.whl (5.2 MB view details)

Uploaded Python 3Windows ARM64

airom-0.3.8-py3-none-win_amd64.whl (5.9 MB view details)

Uploaded Python 3Windows x86-64

airom-0.3.8-py3-none-musllinux_1_2_x86_64.whl (5.7 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

airom-0.3.8-py3-none-musllinux_1_2_aarch64.whl (5.1 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

airom-0.3.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

airom-0.3.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (5.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

airom-0.3.8-py3-none-macosx_11_0_arm64.whl (5.3 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

airom-0.3.8-py3-none-macosx_10_9_x86_64.whl (5.8 MB view details)

Uploaded Python 3macOS 10.9+ x86-64

File details

Details for the file airom-0.3.8.tar.gz.

File metadata

  • Download URL: airom-0.3.8.tar.gz
  • Upload date:
  • Size: 26.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for airom-0.3.8.tar.gz
Algorithm Hash digest
SHA256 b4b8b3a242c091c916f7dbc1d29deab06a58859083fbe6fdb56f18c61d06a435
MD5 8ad7b21a8a5ab12e39d0bf51dc655b6a
BLAKE2b-256 d70fa43181841007be81c40c5950f4399936cc01bb51cabb55e5d8f71207bf75

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.3.8.tar.gz:

Publisher: release-pypi.yml on airomhq/airom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file airom-0.3.8-py3-none-win_arm64.whl.

File metadata

  • Download URL: airom-0.3.8-py3-none-win_arm64.whl
  • Upload date:
  • Size: 5.2 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for airom-0.3.8-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 14dae886f681d62fe1c75c227650c02532e9aa2f1a27b2dd17d0603c3cfdd767
MD5 b895e1e3fff58a335260e226a1dd90c7
BLAKE2b-256 75969e87d43549448a51b181578ed336257b2c2a7ab90a3247bd07ada0619a8c

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.3.8-py3-none-win_arm64.whl:

Publisher: release-pypi.yml on airomhq/airom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file airom-0.3.8-py3-none-win_amd64.whl.

File metadata

  • Download URL: airom-0.3.8-py3-none-win_amd64.whl
  • Upload date:
  • Size: 5.9 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for airom-0.3.8-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 0afdfdecf93b05f7c677c128366e8d2148f9b84939da61dcfc994f56617e399a
MD5 b202bdc4f324014aeddc25e9fb4e8e1d
BLAKE2b-256 a9efe605fb0bbb28c2cc88567615083ad37513f62a36f889c8890908e7e3ad77

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.3.8-py3-none-win_amd64.whl:

Publisher: release-pypi.yml on airomhq/airom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file airom-0.3.8-py3-none-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: airom-0.3.8-py3-none-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 5.7 MB
  • Tags: Python 3, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for airom-0.3.8-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9f1f296ca584c21a1940a33f54afc360a623a85b9c7e9643bc687472dc665899
MD5 4db62dc0d02959084e3331e4108ce366
BLAKE2b-256 40357cf33c59818f2ffb61ab74b67f5d90dc9c17188a15b0cee54d7f29ec57db

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.3.8-py3-none-musllinux_1_2_x86_64.whl:

Publisher: release-pypi.yml on airomhq/airom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file airom-0.3.8-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for airom-0.3.8-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1b555b1bc8d3031f349b1d11b2293b6edce4d33f707db876cfc2c6c967bac0b2
MD5 1b92947a24f15138957a2dec1d7c42ed
BLAKE2b-256 0eed86d5eb42cf2373b5981961953fd1ccb4fc57b4bd24b7da3177900d830192

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.3.8-py3-none-musllinux_1_2_aarch64.whl:

Publisher: release-pypi.yml on airomhq/airom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file airom-0.3.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for airom-0.3.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5d8c11d27802c48366b440be6ebb3409e0b42790a4aefb19551113e9eee95070
MD5 cfcfe4ef776ae701f2aea06ff010de38
BLAKE2b-256 92b62cd6f558f08657f9bb02709d63a76cc11cb02440e8eeea98d5b0a06ab3e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.3.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release-pypi.yml on airomhq/airom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file airom-0.3.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for airom-0.3.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 eae73e53d60153108a83ab695988fe5916d06b996604b7b4033da1440799e612
MD5 1cf0551c483e91baedf27860910edda7
BLAKE2b-256 4a280ff79785b1ed777142382d5b080b7e1b364c9e4dfb649ccbf76887c18a51

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.3.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release-pypi.yml on airomhq/airom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file airom-0.3.8-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: airom-0.3.8-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 5.3 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for airom-0.3.8-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2f5d0a397383328dd418513f0f29ed71117ae915e48415c2d370adf547f767f0
MD5 2a0ab06f881b1062771d96afe304dc84
BLAKE2b-256 a6f75abd64835acc3bdd43a777fbc58a7e2e2b5dadc2db95d827fc3cff322af2

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.3.8-py3-none-macosx_11_0_arm64.whl:

Publisher: release-pypi.yml on airomhq/airom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file airom-0.3.8-py3-none-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for airom-0.3.8-py3-none-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 1ed90a71bd717ded5f487312816be6be4d0e125b72c3e34e1879bde8121548a5
MD5 1d393e90110a64a22db3e4e808fdb871
BLAKE2b-256 5ced059f2f03db2a695bdc181c4e39e76745714f4d6e5de098188192fbe8ef0b

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.3.8-py3-none-macosx_10_9_x86_64.whl:

Publisher: release-pypi.yml on airomhq/airom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page