Python SDK for AIROM — the open-source AI Bill of Materials (AIBOM) scanner
Project description
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.1.1
$ 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 andk8s(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:
- the
binary=argument - a copy bundled in the wheel (
airom/_bin/airom) $AIROM_BINARYairomonPATH
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.
Installing from an sdist ships no binary — put airom on your PATH
(go install github.com/airomhq/airom/cmd/airom@latest, then ensure
$(go env GOPATH)/bin is on PATH) or set $AIROM_BINARY.
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). Set AIROM_SKIP_BUNDLE=1 for a pure-Python wheel.
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file airom-0.1.1.tar.gz.
File metadata
- Download URL: airom-0.1.1.tar.gz
- Upload date:
- Size: 22.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39b2bf0d1995e23678ee3f1298c5f9770ca975070a5130207f245a094540ec0c
|
|
| MD5 |
3d07ddda17696e6e7ea840cbae927659
|
|
| BLAKE2b-256 |
bfb8ce11df05d48167955a1892a7802497fa5c39d810d056eabcbe6720d7e457
|
Provenance
The following attestation bundles were made for airom-0.1.1.tar.gz:
Publisher:
release-pypi.yml on airomhq/airom
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airom-0.1.1.tar.gz -
Subject digest:
39b2bf0d1995e23678ee3f1298c5f9770ca975070a5130207f245a094540ec0c - Sigstore transparency entry: 2189365087
- Sigstore integration time:
-
Permalink:
airomhq/airom@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/airomhq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file airom-0.1.1-py3-none-win_amd64.whl.
File metadata
- Download URL: airom-0.1.1-py3-none-win_amd64.whl
- Upload date:
- Size: 5.4 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81f9260dc2ee922be52ff0b77f62ac1bbd0ffea2a3b0cdf3d0ba5d499e1538c4
|
|
| MD5 |
188d1d6c3d5b344267f5ba754404c610
|
|
| BLAKE2b-256 |
b89d7bcbbc74742bb462d0b583425429292bc0c89ab7597ce757f2d1bfc979b1
|
Provenance
The following attestation bundles were made for airom-0.1.1-py3-none-win_amd64.whl:
Publisher:
release-pypi.yml on airomhq/airom
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airom-0.1.1-py3-none-win_amd64.whl -
Subject digest:
81f9260dc2ee922be52ff0b77f62ac1bbd0ffea2a3b0cdf3d0ba5d499e1538c4 - Sigstore transparency entry: 2189365205
- Sigstore integration time:
-
Permalink:
airomhq/airom@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/airomhq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file airom-0.1.1-py3-none-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: airom-0.1.1-py3-none-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 5.2 MB
- Tags: Python 3, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3dae08164774cf8f742fb737c54d229b09afbf15d73d7df674fd46a5f859482b
|
|
| MD5 |
6e3af9b41def01050fb61b3cb2f8ba31
|
|
| BLAKE2b-256 |
9ba5b28335234f434a5353892100b507eabd97a942f81130eb0dd943fe35cbc5
|
Provenance
The following attestation bundles were made for airom-0.1.1-py3-none-musllinux_1_2_x86_64.whl:
Publisher:
release-pypi.yml on airomhq/airom
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airom-0.1.1-py3-none-musllinux_1_2_x86_64.whl -
Subject digest:
3dae08164774cf8f742fb737c54d229b09afbf15d73d7df674fd46a5f859482b - Sigstore transparency entry: 2189365774
- Sigstore integration time:
-
Permalink:
airomhq/airom@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/airomhq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file airom-0.1.1-py3-none-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: airom-0.1.1-py3-none-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 4.7 MB
- Tags: Python 3, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a247317cf8b1e16579baebf6a26ef43c7b1a8b29ca08ba8071e6fcb71f0470e
|
|
| MD5 |
83628e3a994d8465b7b508fbf3ec778f
|
|
| BLAKE2b-256 |
1a57ff40483e3645b16c3afdbcfa0620a017cdf82062e203eb4372cef648e3ad
|
Provenance
The following attestation bundles were made for airom-0.1.1-py3-none-musllinux_1_2_aarch64.whl:
Publisher:
release-pypi.yml on airomhq/airom
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airom-0.1.1-py3-none-musllinux_1_2_aarch64.whl -
Subject digest:
5a247317cf8b1e16579baebf6a26ef43c7b1a8b29ca08ba8071e6fcb71f0470e - Sigstore transparency entry: 2189365270
- Sigstore integration time:
-
Permalink:
airomhq/airom@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/airomhq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file airom-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: airom-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.2 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53551efd6729d123b9930619274eb262a762e843ca248df6dc8621e8c6915a9e
|
|
| MD5 |
5874e45172a417a0b8e1ab14075249be
|
|
| BLAKE2b-256 |
ed09801a898834fb31cbbcccea1fc2cb398e9b97cb281eccde70ce8e6fbfd926
|
Provenance
The following attestation bundles were made for airom-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release-pypi.yml on airomhq/airom
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airom-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
53551efd6729d123b9930619274eb262a762e843ca248df6dc8621e8c6915a9e - Sigstore transparency entry: 2189365358
- Sigstore integration time:
-
Permalink:
airomhq/airom@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/airomhq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file airom-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: airom-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 4.7 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a497a7af3de93a2aebff8bd98fd3803c9f89579c48ababe629501eeb03be811b
|
|
| MD5 |
2bc5169fad03956a70ef8929048e62ab
|
|
| BLAKE2b-256 |
eb3a45fcd68581251da069b3a1ea7016904e66efb0e280b06988932a276dbe8e
|
Provenance
The following attestation bundles were made for airom-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release-pypi.yml on airomhq/airom
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airom-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
a497a7af3de93a2aebff8bd98fd3803c9f89579c48ababe629501eeb03be811b - Sigstore transparency entry: 2189365445
- Sigstore integration time:
-
Permalink:
airomhq/airom@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/airomhq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file airom-0.1.1-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: airom-0.1.1-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 4.8 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc10a93a02e4e7ff0197c4573d50613610b9a960468e955cb1239e87a17d0a38
|
|
| MD5 |
3a50d864d6caa26a2e336ec898e532cb
|
|
| BLAKE2b-256 |
38620065ffe1153522eb511de5f74931a371fd5da766e7af166bee526b1c4028
|
Provenance
The following attestation bundles were made for airom-0.1.1-py3-none-macosx_11_0_arm64.whl:
Publisher:
release-pypi.yml on airomhq/airom
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airom-0.1.1-py3-none-macosx_11_0_arm64.whl -
Subject digest:
cc10a93a02e4e7ff0197c4573d50613610b9a960468e955cb1239e87a17d0a38 - Sigstore transparency entry: 2189365663
- Sigstore integration time:
-
Permalink:
airomhq/airom@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/airomhq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file airom-0.1.1-py3-none-macosx_10_9_x86_64.whl.
File metadata
- Download URL: airom-0.1.1-py3-none-macosx_10_9_x86_64.whl
- Upload date:
- Size: 5.3 MB
- Tags: Python 3, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1cfac55ec8b550c3a46fca0da17d3094ebef8e38cb3035c2273f4242da7fa12
|
|
| MD5 |
6e9c14b1749e80d66b2deebd9712e77c
|
|
| BLAKE2b-256 |
e597296658eca900f35d46639ee3ba9a97cbfa254cb64912fe0eef739d7cf8ea
|
Provenance
The following attestation bundles were made for airom-0.1.1-py3-none-macosx_10_9_x86_64.whl:
Publisher:
release-pypi.yml on airomhq/airom
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airom-0.1.1-py3-none-macosx_10_9_x86_64.whl -
Subject digest:
d1cfac55ec8b550c3a46fca0da17d3094ebef8e38cb3035c2273f4242da7fa12 - Sigstore transparency entry: 2189365549
- Sigstore integration time:
-
Permalink:
airomhq/airom@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/airomhq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2255bcca3f2abff00359072b4dbe45ef3f6170f4 -
Trigger Event:
push
-
Statement type: