Metadata-Version: 2.4
Name: qrcode-ai-scanner
Version: 0.5.0
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Requires-Dist: pytest ; extra == 'test'
Requires-Dist: jsonschema ; extra == 'test'
Requires-Dist: pillow ; extra == 'test'
Provides-Extra: test
Summary: QR decoding + scannability scoring for artistic, AI-generated, and photo-captured QR codes — Rust core via PyO3.
Keywords: qrcode,qr,scanner,decoder,barcode,validation
License-Expression: AGPL-3.0-or-later
Requires-Python: >=3.8
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Documentation, https://github.com/supernovae-st/qrcode-ai-scanner/tree/main/docs
Project-URL: Repository, https://github.com/supernovae-st/qrcode-ai-scanner

# qrcode-ai-scanner (Python)

QR decoding + scannability scoring for **artistic / AI-generated / photo-captured** QR
codes — the Rust [`qrcode-ai-scanner`](https://crates.io/crates/qrcode-ai-scanner) engine,
via PyO3. Same versioned `ScanReport` contract as the Rust, Node and WASM surfaces.

```python
import qrcode_ai_scanner as qr

with open("image.png", "rb") as f:
    report = qr.scan(f.read(), profile="full")   # "full" | "fast" | "frame"

if report["detections"]:
    d = report["detections"][0]
    print(d["content"]["text"])
    print(report["score"]["value"], report["score"]["grade"])  # 0-100 + ISO band
    print(report["hints"])                                      # machine-actionable
```

- `scan(image: bytes, profile="full", max_dimension=None, max_pixels=None, budget_ms=None)
  -> dict` — decode encoded bytes (PNG/JPEG/WebP/GIF).
- `scan_frame(rgba: bytes, width: int, height: int, profile="frame", max_dimension=None,
  max_pixels=None, budget_ms=None) -> dict` — raw RGBA frame, no image-format roundtrip.
- Optional kwargs: `max_dimension` / `max_pixels` cap inputs BEFORE any pixel work
  (defaults 10000 px / 64 MP — lower them for untrusted uploads); `budget_ms` bounds the
  scan wall-clock (`0` = unbounded — leave unset for strictly reproducible reports).
- "No QR found" returns a `dict` with empty `detections`; `ValueError` is raised only for
  invalid input.

The returned `dict` is the same `ScanReport` documented in the
[spec](https://github.com/supernovae-st/qrcode-ai-scanner/tree/main/spec).

License: AGPL-3.0-or-later · © SuperNovae Studio.

