Python SDK for the Scanii content security API.
pip install scanii-pythonDistribution name is scanii-python; import as from scanii import ScaniiClient.
- Light. Zero runtime dependencies, stdlib only.
- Up to date. Always current with the latest Scanii API.
- Integration-only. Wraps the REST API — retries, concurrency, and batching are the caller's responsibility.
fromscaniiimportScaniiClient, ScaniiTargetclient=ScaniiClient(key="your-key", secret="your-secret", target=ScaniiTarget.US1)
result=client.process_file("./document.pdf")
print(result.findings) # [] when cleanPass any IO-like object (anything with read(n) -> bytes) to process() directly — no temp file needed:
importio# Scan bytes already in memoryresult=client.process(io.BytesIO(my_bytes), filename="upload.bin")
# Scan content from an open file handlewithopen("./large.pdf", "rb") asf:
result=client.process(f, filename="large.pdf")ScaniiClient(
*,
key: str|None=None,
secret: str|None=None,
token: str|None=None,
target: ScaniiTarget,
timeout: float=60.0,
)Supply either key + secret (HTTP Basic Auth) or token (auth-token authentication). Mixing both raises ValueError. target is required — see Regional Endpoints.
| Method | Description |
|---|---|
process(content, filename, content_type=None, metadata=None, callback=None) | Synchronous scan of an IO-like object |
process_file(path, metadata=None, callback=None) | Synchronous scan of a file on disk |
process_async(content, filename, content_type=None, metadata=None, callback=None) | Async-on-server scan of an IO-like object; returns ScaniiPendingResult |
process_async_file(path, metadata=None, callback=None) | Async-on-server scan of a file on disk; returns ScaniiPendingResult |
retrieve(id) | Retrieve a previous scan result |
delete(id) | Delete a scan result. Returns True; the processing trace is left intact |
delete_trace(id) | Delete a processing trace. Returns True; the scan result is left intact |
fetch(url, metadata=None, callback=None) | Server-side async fetch-and-scan of a remote URL |
process_from_url(location, callback=None, metadata=None) | Synchronous scan of a remote URL via POST /files |
retrieve_trace(id) | Retrieve processing event trace; returns None on 404 |
delete() and delete_trace() act on independent resources: deleting a scan result
leaves its trace readable, and deleting a trace leaves the result readable. To erase a
scan entirely, call both.
| Method | Description |
|---|---|
create_auth_token(timeout_seconds) | Mint a short-lived token |
retrieve_auth_token(id) | Inspect a token |
delete_auth_token(id) | Revoke a token |
| Method | Description |
|---|---|
ping() | Returns True when the API is reachable with valid credentials |
Choose a regional target explicitly. Six regional constants are available: US1, EU1, EU2, AP1, AP2, CA1. Latency-based routing (AUTO in other Scanii SDKs) is intentionally not provided — chain-of-custody and data-residency compliance require an explicit regional choice. For local testing against scanii-cli, construct a target with an arbitrary URL: ScaniiTarget("http://localhost:4000").
| Constant | URL | Location |
|---|---|---|
ScaniiTarget.US1 | https://api-us1.scanii.com | Virginia, USA |
ScaniiTarget.EU1 | https://api-eu1.scanii.com | Dublin, Ireland |
ScaniiTarget.EU2 | https://api-eu2.scanii.com | London, United Kingdom |
ScaniiTarget.AP1 | https://api-ap1.scanii.com | Sydney, Australia |
ScaniiTarget.AP2 | https://api-ap2.scanii.com | Singapore |
ScaniiTarget.CA1 | https://api-ca1.scanii.com | Montreal, Canada |
client=ScaniiClient(key="your-key", secret="your-secret", target=ScaniiTarget.EU1)fromscaniiimportScaniiClient, ScaniiTarget, ScaniiError, ScaniiAuthError, ScaniiRateLimitErrorimporttimeclient=ScaniiClient(key="your-key", secret="your-secret", target=ScaniiTarget.US1)
try:
result=client.process_file("./document.pdf")
exceptScaniiAuthError:
print("Invalid credentials")
exceptScaniiRateLimitErrorase:
ife.retry_after:
time.sleep(e.retry_after)
exceptScaniiErrorase:
print(f"API error {e.status_code}: {e}")Network-level failures (urllib.error.URLError) propagate unwrapped — retries are the caller's responsibility per SDK Principle 3.
All integration tests run against a locally-hosted scanii-cli mock server — no real credentials needed.
docker run -d --name scanii-cli -p 4000:4000 ghcr.io/scanii/scanii-cli:latest server
# Run tests
pip install -e ".[dev]"
pytestclient=ScaniiClient(key="key", secret="secret", target=ScaniiTarget("http://localhost:4000"))
result=client.ping() # TruePull requests welcome. Please open an issue first for substantial changes.
Apache 2.0 — see LICENSE.