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.4.0

$ 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.4.0.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.4.0-py3-none-win_arm64.whl (5.2 MB view details)

Uploaded Python 3Windows ARM64

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

Uploaded Python 3Windows x86-64

airom-0.4.0-py3-none-musllinux_1_2_x86_64.whl (5.8 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

airom-0.4.0-py3-none-musllinux_1_2_aarch64.whl (5.2 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

airom-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.8 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

airom-0.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (5.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

airom-0.4.0-py3-none-macosx_10_9_x86_64.whl (5.9 MB view details)

Uploaded Python 3macOS 10.9+ x86-64

File details

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

File metadata

  • Download URL: airom-0.4.0.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.4.0.tar.gz
Algorithm Hash digest
SHA256 e574fdf46dba422e2046ff3d6f6dd6d6c4f4979ba2153a366a40a99e6bf86822
MD5 f113f24266fef41707a55582ced0ee28
BLAKE2b-256 376cfba83f2afbbd5200f2542327a6af488ab416e27757883fbf054c70bbf9d6

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.4.0.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.4.0-py3-none-win_arm64.whl.

File metadata

  • Download URL: airom-0.4.0-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.4.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 076e933a7386357f1373641e756164a54fce019f72925901c12088615b445147
MD5 07c6c3fabf858b50022555188e0b9a64
BLAKE2b-256 a7c1dfea8ac3fc48f681e749c5a676f539c90f07f809e02db4d9eb43160ab2dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.4.0-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.4.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: airom-0.4.0-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.4.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 2b34b82ef77d07012157923d3fdf060f55665410235591de107cc17e77f52638
MD5 0bf9b91b309a773923507b8326d3c340
BLAKE2b-256 03721b9d3df7b317258c43c5317791c83d0369e8b8d7edb7116591c2373cd3fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.4.0-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.4.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: airom-0.4.0-py3-none-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 5.8 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.4.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 0aa5e2bfc04f81b018dba7a0affb4cec308373058d47596368b21b7d4cec23bb
MD5 64d7c7a53c638a0977416cb938d59f19
BLAKE2b-256 81e16f49bca8c21cc1bca29f35a2e6603997df088703efe441c3c8e1a0062c2a

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.4.0-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.4.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for airom-0.4.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 c31c63e7b1deb816953be18559bd94fb1dbfe2246fae1ac32f6cefc6298654c7
MD5 f8fa6ac5af91a255f05ddbeb04b1b41f
BLAKE2b-256 a2e057178d26193176d9def74e9715a4cd3ba1f0194e249f21b79574f65e3fe2

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.4.0-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.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for airom-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0d60c63c379a1dfef7552c0a9be683fa83c2de70ae68ce27eb52330cc159fc2f
MD5 ebe9dfe1b0236c61913c26351613f478
BLAKE2b-256 aba8e4a6ef95e436ec0bddd4ae4dc08983eff6e3344ea7984f6a6b05fd37c091

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.4.0-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.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for airom-0.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0d8db6bd986dc05d09a42cfcf32104164cb334a35429109228a41a0bd5d8c0df
MD5 01222ebb9aa26c0c926d7fc2cde598a0
BLAKE2b-256 e3740dc65f12b6a8d7798ffe2c91c82a45dc5a64753d57de32bf2c2883fe85c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.4.0-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.4.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: airom-0.4.0-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.4.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cd32bfbda0c3c0361068ed0c68a11dadc73c111a4d7bddf02132449be35dd799
MD5 231699a0e61bab2e59fe4ddbd59ffa37
BLAKE2b-256 a99bc7538cee9e4a5a1dd385e63bb97dab6bed72ce9a5de10f30a0e3db520b5e

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.4.0-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.4.0-py3-none-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for airom-0.4.0-py3-none-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 4242f5acdb1a23c07215a69269302f3168afeb267a76749616be716235f75c15
MD5 34f6ace774bf4c8f178903bb9ebe22ef
BLAKE2b-256 b4344887474d367141964c22a2c096712726ea963c46495f94d1fdff8366be93

See more details on using hashes here.

Provenance

The following attestation bundles were made for airom-0.4.0-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