Metadata-Version: 2.4
Name: sparrow-engine
Version: 0.1.29
Requires-Dist: onnxruntime>=1.25.1,<1.26
Requires-Dist: numpy>=1.26
Summary: Camera-trap ML inference engine — Python API only (sparrow-engine CPU pipeline). The CLI binary (spe / spe-gpu) and HTTP server are NOT shipped via pip; install them via brew, the system installer (sparrow-engine-install.sh / .ps1), or the GitHub Release tarball. See https://github.com/microsoft/SPARROW-Engine/blob/main/docs/user-manual.md
Requires-Python: >=3.11
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# sparrow-engine (Python)

Camera-trap ML inference engine — Python API. `sparrow-engine` loads ONNX
models and runs detection, classification, and audio inference.

This package ships the **Python API only** (`import sparrow_engine`). The
command-line binaries (`spe` / `spe-gpu`) and the HTTP server are distributed
separately (Homebrew, the system installer, or the GitHub Release tarball) —
`pip install` does not place them on your `PATH`.

## Install

```bash
pip install sparrow-engine        # CPU build (depends on onnxruntime)
pip install sparrow-engine-gpu    # GPU/CUDA build (depends on onnxruntime-gpu)
```

Both distributions import as `sparrow_engine` and are drop-in replacements for
each other. Install exactly one per environment: they write the same
`sparrow_engine` import package, so a second flavor overwrites the first. The
GPU wheel carries only an advisory `Provides-Dist: sparrow-engine`, which pip
>=22 does not enforce, so pip MAY still install both into one environment —
keeping them apart is operator discipline. Neither wheel bundles ONNX Runtime or
CUDA — those come from the runtime dependency (`onnxruntime` / `onnxruntime-gpu`).

## Usage

```python
import sparrow_engine

# Models are read from ~/.sparrow-engine/models (override with
# SPARROW_ENGINE_MODEL_DIR). Device defaults to "auto".
print(sparrow_engine.list_models())

# Object detection — returns list[DetectResult], one per input image.
results = sparrow_engine.detect("photo.jpg", model="MDV6-yolov10-c")
for det in results[0].detections:
    # bbox coordinates are normalized to [0, 1].
    print(det.label, det.confidence, det.bbox.x_min, det.bbox.y_min)

# Classification — result.top1 is the highest-confidence class (or None).
clf = sparrow_engine.classify("crop.jpg", model="Deepfaune-Europe")
print(clf[0].top1)

# Detect-then-classify pipeline (ad-hoc; no TOML required).
pipe = sparrow_engine.pipeline("photo.jpg", detector="MDV6-yolov10-c",
                               classifier="Deepfaune-Europe")

# Audio detection (WAV input).
audio = sparrow_engine.detect_audio("recording.wav", model="md-audiobirds-v1")

# Localized time-frequency audio events (WAV input).
events = sparrow_engine.detect_audio_events(
    "ultrasonic.wav", model="batdetect2-uk-v2"
)
```

`init(device=..., model_dir=...)` is optional — the engine auto-initializes on
the first inference call. `detect` / `classify` / `detect_audio` /
`detect_audio_events` / `pipeline` each accept a file path, a directory, or a
list of paths, and take an optional
`progress_callback(index, total, filename)`.

`detect`, `detect_audio`, and `detect_audio_events` also accept an optional
`model`. The first two use their catalog default and stable fallback ID.
Audio-event detection uses a catalog default when present but has no
hard-coded fallback because event taxonomies and geographic scopes are
model-specific. `classify`, `embed`, and `pipeline` still require an explicit
model.

## Documentation

See the user manual (`docs/user-manual.md`) in the sparrow-engine repository for
the full model catalog, device selection, and the CLI / server surfaces.

