sbom-tools 0.2.0

Semantic SBOM diff and analysis tool
Documentation
# sbom-tools Python bindings

Pure-Python `ctypes` bindings for the existing
[`sbom-tools`](https://github.com/sbom-tool/sbom-tools) C ABI.

> **Developer preview:** this binding requires a native library built from the
> same source tree. Binary wheels and publishing automation are not available.

Start with the [project overview](../../docs/PROJECT_OVERVIEW.md) and
[user journeys](../../docs/USER_JOURNEYS.md) to understand where Python fits in
the scientist and developer workflows. Those documents are introduced by
[PR #276](https://github.com/sbom-tool/sbom-tools/pull/276) and must land before
these relative links resolve on the upstream default branch.

The package does not change Rust behavior or implement its own SBOM logic.
When troubleshooting, include the output of `version()` in bug reports so the
loaded ABI and Rust crate versions are explicit.

## Requirements

- Python 3.10 or later
- A native `sbom-tools-ffi` library built from this repository

Build the native library from the repository root:

```sh
cargo build -p sbom-tools-ffi --release
```

The loader searches for the platform library in this order:

1. The file named by `SBOM_TOOLS_LIB_PATH`
2. `bindings/python/native/`
3. Repository release, then debug targets (flat or host target-triple directories)
4. The system library path

The platform filenames are:

- macOS: `libsbom_tools_ffi.dylib`
- Linux: `libsbom_tools_ffi.so`
- Windows: `sbom_tools_ffi.dll`

An invalid `SBOM_TOOLS_LIB_PATH` is reported immediately and does not fall
through to another library.

## Install and test

Use an isolated environment:

```sh
cd bindings/python
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[test]'
.venv/bin/python -m pytest -q
```

On Windows, replace `.venv/bin/python` with `.venv\Scripts\python`.

Tests that require the native library skip with a clear message when it has not
been built. An explicitly configured but invalid library path is a test failure.

## Usage

```python
import json

from sbomtools import ScoringProfile, parse_path_json, score_json, version

print(version())

normalized = parse_path_json("bom.cdx.json")
report = score_json(json.dumps(normalized), ScoringProfile.STANDARD)
print(report)
```

The diff and score functions accept normalized JSON produced by a parse
function:

```python
old = parse_path_json("old.cdx.json")
new = parse_path_json("new.cdx.json")

from sbomtools import diff_json

result = diff_json(json.dumps(old), json.dumps(new))
```

## Memory and errors

Every native result is decoded before the binding calls
`sbom_tools_string_result_free` exactly once. Native pointers are not exposed
through the public API. ABI failures raise `SbomToolsNativeError` with the
corresponding stable error code.