Python SDK for the Threat.Zone malware analysis platform
Project description
Threat.Zone Python SDK
Official Python SDK for the Threat.Zone malware analysis platform.
Targets the Threat.Zone Public API 1.0.0-rc1 surface, ships fully typed Pydantic v2
models for every endpoint, and exposes both synchronous (ThreatZone) and asynchronous
(AsyncThreatZone) clients with identical method surfaces. Requires Python 3.10+.
Install
pip install threatzone
# or
uv add threatzone
Configure
from threatzone import ThreatZone
client = ThreatZone(api_key="<your-api-key>")
The client reads THREATZONE_API_KEY from the environment, so ThreatZone() is enough
if you export it. The default base_url is https://app.threat.zone/public-api.
For on-prem or local development, pass base_url explicitly:
client = ThreatZone(
api_key="<your-api-key>",
base_url="https://threatzone.your-company.internal/public-api",
)
The base_url must include the /public-api suffix. For self-signed certs, leave
verify_ssl=False (the default).
Quick usage
from pathlib import Path
account = client.get_user_info()
print(f"Workspace: {account.workspace_name}")
submission = client.create_sandbox_submission(Path("./sample.exe"))
completed = client.wait_for_completion(submission.uuid, timeout=600)
print(f"Verdict: {completed.level}")
print(f"MITRE techniques: {completed.mitre_techniques}")
Core concepts
- Submissions — one analysis target (file or URL) with a stable
uuid, a workspace owner, aprivateflag, and up to four reports. - Reports —
dynamic,static,cdr,url_analysis. Independent; poll each viasubmission.is_complete()/submission.has_errors(). Every report carries its ownstatus,level,score. - Observation streams — the dynamic report produces
indicators(rule hits),iocs(concrete IOC values),behaviours(OS-level operations — theosquery param is required), andsyscalls(raw log lines). - Artifacts — files produced or extracted during analysis; keyed by
hashes.sha256. - Access control — public submissions are visible to every API key; private
submissions are workspace-scoped. Cross-workspace reads of private submissions raise
PermissionDeniedError(403).
Async
AsyncThreatZone mirrors ThreatZone method-for-method:
import asyncio
from threatzone import AsyncThreatZone
async def main() -> None:
async with AsyncThreatZone(api_key="<your-api-key>") as client:
account = await client.get_user_info()
print(account.email)
asyncio.run(main())
Use asyncio.gather() for concurrent fan-out. See recipe 10.
Errors
Every error inherits from ThreatZoneError. HTTP errors additionally inherit from
APIError and carry the parsed error envelope on .body, with the structured code at
.body["code"]. Branch on .code, never on .message.
| Status | Exception | When |
|---|---|---|
| — | ThreatZoneError |
Base class. Catch for a single safety net. |
| — | APIError |
HTTP error base class. .status_code, .body, .response. |
| 400 | BadRequestError |
INVALID_UUID, INVALID_QUERY_PARAM. |
| 401 | AuthenticationError |
Missing/invalid API key. |
| 402 | PaymentRequiredError |
Workspace subscription inactive. |
| 403 | PermissionDeniedError |
Cross-workspace private read, or module not enabled. |
| 404 | NotFoundError |
Submission, artifact, or media missing. |
| 409 | ReportUnavailableError |
Required report not yet available. Carries .code, .submission_uuid, .required_report, .current_status, .available_reports. |
| 429 | RateLimitError |
API quota exceeded. Has .retry_after. |
| 5xx | InternalServerError |
Server-side failure. |
| — | TimeoutError |
HTTP request timed out. |
| — | ConnectionError |
Network-level failure. |
| — | AnalysisTimeoutError |
wait_for_completion() exceeded its timeout. .uuid, .elapsed. |
| 202 | YaraRulePendingError |
YARA rule generation still in progress. .retry_after. |
from threatzone import ReportUnavailableError, ThreatZone
try:
indicators = client.get_indicators("00000000-0000-0000-0000-000000000000")
except ReportUnavailableError as exc:
if exc.code == "DYNAMIC_REPORT_UNAVAILABLE":
print(f"Dynamic report not ready (status: {exc.current_status}).")
See recipe 9 for the full discrimination pattern and recipe 7 for the recommended retry loop.
Documentation
| Document | Purpose |
|---|---|
| Recipes | 12 runnable examples covering common tasks. |
| Type Reference | Pydantic model overview grouped by feature area. |
Testing utilities
The SDK ships a stateful in-process fake Threat.Zone API for consumer-side tests:
from threatzone import ThreatZone
from threatzone.testing import FakeThreatZoneAPI, scenarios
fake = FakeThreatZoneAPI()
scenarios.seed_malicious_pe(fake, sha256="a" * 64)
client = ThreatZone(
api_key="test-key",
base_url="https://fake.threat.zone/public-api",
http_client=fake.as_httpx_client(),
)
Available scenarios: seed_malicious_pe, seed_benign_document, seed_cdr_document,
seed_phishing_url, seed_static_only_submission, seed_private_cross_workspace.
Development
uv sync --all-extras --dev
uv run pytest tests/
uv run ruff check src/ tests/
uv run mypy src/threatzone
uv build
All tests run in-process against FakeThreatZoneAPI — no network, no API token. Live
smoke-testing uses the scripts in examples/ with PUBLIC_API_TOKEN exported; see
examples/README.md.
GitHub Actions workflows can be exercised locally via act — see
.github/workflows/README.md.
Links
License
MIT — see LICENSE.
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 Distribution
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 threatzone-1.0.0.tar.gz.
File metadata
- Download URL: threatzone-1.0.0.tar.gz
- Upload date:
- Size: 151.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92c42962ae5188bd6cf3881cedaaf10daca34c5f3bf4c978f312181f4c3d6eea
|
|
| MD5 |
826920a14ee7b631e90997949252d837
|
|
| BLAKE2b-256 |
a36fb3551377dbf98a809ca0731f8c3fb04910cff94f300a47c8859536719924
|
Provenance
The following attestation bundles were made for threatzone-1.0.0.tar.gz:
Publisher:
publish.yml on Malwation/threatzone-python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
threatzone-1.0.0.tar.gz -
Subject digest:
92c42962ae5188bd6cf3881cedaaf10daca34c5f3bf4c978f312181f4c3d6eea - Sigstore transparency entry: 1309167220
- Sigstore integration time:
-
Permalink:
Malwation/threatzone-python-sdk@15b6408145e305e0789f69241a4ce818c2f86ae4 -
Branch / Tag:
refs/tags/1.0.0 - Owner: https://github.com/Malwation
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@15b6408145e305e0789f69241a4ce818c2f86ae4 -
Trigger Event:
release
-
Statement type:
File details
Details for the file threatzone-1.0.0-py3-none-any.whl.
File metadata
- Download URL: threatzone-1.0.0-py3-none-any.whl
- Upload date:
- Size: 62.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9605caa075dfd20ca29645a5fa26771bef2ba1e864e4eaa462c4fbecd7f82404
|
|
| MD5 |
5c6ff2d536c67455489907d9e34b2779
|
|
| BLAKE2b-256 |
06a1636892f0f65130f325beafa98d7e58f13231b55dbde74bb31a37e19e1bee
|
Provenance
The following attestation bundles were made for threatzone-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on Malwation/threatzone-python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
threatzone-1.0.0-py3-none-any.whl -
Subject digest:
9605caa075dfd20ca29645a5fa26771bef2ba1e864e4eaa462c4fbecd7f82404 - Sigstore transparency entry: 1309167348
- Sigstore integration time:
-
Permalink:
Malwation/threatzone-python-sdk@15b6408145e305e0789f69241a4ce818c2f86ae4 -
Branch / Tag:
refs/tags/1.0.0 - Owner: https://github.com/Malwation
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@15b6408145e305e0789f69241a4ce818c2f86ae4 -
Trigger Event:
release
-
Statement type: