Official Python SDK for ContrastAPI — security intelligence for developers and AI agents
Project description
ContrastAPI Python SDK
Official Python client for ContrastAPI — security intelligence for developers and AI agents.
42 MCP tools / 50+ HTTP endpoints: CVE / EPSS / KEV / CWE, MITRE ATLAS (AI/ML attacks) + bulk drill, MITRE D3FEND defenses, domain audit, IOC + threat intel, OSINT, code-security checks, and more. No API key required for the free tier (100 req/hr).
Install
pip install contrastapi
Requires Python 3.10+. Depends only on httpx>=0.25.
Quickstart
Sync
from contrastapi import ContrastAPI
from contrastapi.models import CveResponse, AuditResponse
with ContrastAPI() as client: # keyless, free tier
cve: CveResponse = client.cve.lookup("CVE-2021-44228")
print(cve["kev"]["in_kev"]) # True (IDE autocompletes "kev", "epss"...)
techs = client.atlas.bulk_technique_lookup(["AML.T0051", "AML.T0043"])
print(techs["successful"]) # 2
audit: AuditResponse = client.domain.audit("example.com")
print(audit["score"])
Every response method has a typed return — client.cve.lookup(...) returns CveResponse, client.atlas.technique(...) returns AtlasTechniqueResponse, etc. You never need to write the type annotation; IDEs (VSCode/PyCharm) infer it from the method signature and offer autocomplete on response keys. Import from contrastapi.models only if you want to annotate explicitly or pass responses across function boundaries.
Async
import asyncio
from contrastapi import AsyncContrastAPI
async def main():
async with AsyncContrastAPI(api_key="cc_...") as client:
defenses = await client.d3fend.defense_for_attack("T1059")
print(len(defenses["defenses"]))
asyncio.run(main())
Shortcuts (multi-call helpers)
from contrastapi import ContrastAPI, audit_full, enrich_batch, triage_ioc
with ContrastAPI() as client:
# Auto-route IP/hash/domain to the right enrichment leg
report = triage_ioc(client, "8.8.8.8") # ioc + threat_report
# Audit + subdomains + tech + per-subdomain SSL (capped)
audit = audit_full(client, "example.com", ssl_subdomains=5)
# Auto-detect CVE vs IOC and bulk-route
enriched = enrich_batch(client, ["CVE-2021-44228", "8.8.8.8", "evil.com"])
Shortcuts swallow per-leg ContrastAPIError so partial failures still return whatever succeeded — see result["errors"] for the failure map.
Authentication
Pass an API key as the first positional argument or as api_key=:
client = ContrastAPI("cc_<your-key>") # 1000 req/hr (Pro tier)
Get a key at contrastcyber.com/pricing.
Exception model
The SDK maps server error codes (v1.22.2+ wire envelope) to typed exceptions:
| Exception | Status | Server code |
|---|---|---|
InvalidArgumentError |
400, 422 | invalid_argument |
AuthRequiredError |
401 | auth_required |
TierLimitError |
403 | tier_limit |
NotFoundError |
404 | not_found |
RateLimitError |
429 | rate_limit_exceeded |
UpstreamError |
502 | upstream_error |
UpstreamTimeoutError |
504 | upstream_timeout |
TransportError |
n/a | (network failure, before HTTP) |
ContrastAPIError |
* | base / unknown |
Every exception carries the parsed envelope:
from contrastapi import ContrastAPI, RateLimitError
try:
client.cve.lookup("CVE-2021-44228")
except RateLimitError as exc:
print(exc.message) # "Hourly limit reached"
print(exc.retry_after_seconds) # 60 (capped at 3600)
print(exc.upgrade_url) # "https://contrastcyber.com/pricing"
print(exc.extras) # back-compat top-level fields (tier, limit, ...)
Namespaces
| Namespace | Methods |
|---|---|
cve |
lookup, search, leading, kev, exploit, bulk |
cwe |
lookup |
ioc |
lookup, hash, phishing, bulk |
atlas |
technique, technique_search, bulk_technique_lookup, case_study, case_study_search |
d3fend |
defense, defense_search, defense_for_attack, coverage |
domain |
report, dns, whois, subdomains, certs, ssl, tech, threat, monitor, vulns, audit, wayback, bulk |
ip |
lookup, threat_report |
asn |
lookup |
email |
mx, disposable |
phone |
lookup |
password |
check (k-anonymity SHA-1 prefix) |
username |
lookup |
check |
secrets, injection, headers, dependencies |
scan |
headers (live HTTP scan) |
The async client (AsyncContrastAPI) exposes the same namespace surface 1:1 — every method is async def.
Parity with the Node SDK
| Surface | Node SDK | Python SDK |
|---|---|---|
| Sync | ✅ (Promise-based) | ✅ (ContrastAPI) |
| Async | (Promise model) | ✅ (AsyncContrastAPI) |
| Namespace count | 13 | 14 (adds username) |
bulk_technique_lookup (ATLAS) |
(added in v1.4.0) | ✅ |
wayback archive lookup |
(added in v1.4.0) | ✅ |
| Typed errors | Error subclasses |
full hierarchy with envelope fields |
| Shortcuts | — | ✅ triage_ioc, audit_full, enrich_batch |
| Response models | Promise<any> |
✅ TypedDict (IDE autocomplete, no runtime cost) |
Configuration
client = ContrastAPI(
api_key="cc_...", # optional; keyless = free tier
base_url="https://api.contrastcyber.com", # override for self-host
timeout=30.0, # seconds; clamped to [1, 120]
allow_insecure=False, # set True to allow http:// (dev only)
)
The transport hard-caps response bodies at 10 MB, sends a User-Agent: contrastapi-python/<version> header, and refuses to send your API key over plaintext HTTP even when allow_insecure=True.
Links
- API docs: https://api.contrastcyber.com/docs
- Pricing & API key: https://contrastcyber.com/pricing
- Source: https://github.com/UPinar/contrastapi
- Issues: https://github.com/UPinar/contrastapi/issues
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 contrastapi-1.22.3.tar.gz.
File metadata
- Download URL: contrastapi-1.22.3.tar.gz
- Upload date:
- Size: 27.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7b5644488e197900850bfcc0cb0c03a01bd9387b795df6a4c75ab0030813d8e
|
|
| MD5 |
f8ec700951f104638a00e283201d5afe
|
|
| BLAKE2b-256 |
e6b186587aa1a961c38dc899d1e893140c07316b2636a801e84c703734496c36
|
File details
Details for the file contrastapi-1.22.3-py3-none-any.whl.
File metadata
- Download URL: contrastapi-1.22.3-py3-none-any.whl
- Upload date:
- Size: 23.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
505adbf2cf9e8d7c54527f6219a591af8acce207a7e43b168aabd63a6f84ac85
|
|
| MD5 |
4f8702704f5c4ed0662c6b5c160064fd
|
|
| BLAKE2b-256 |
c23e856f08467455d4ddacf4da190dfcccb6eda3e85738a9f0d0c9c6e1a23fa6
|