DevSecure Intelligence for Python
Rank CVEs by real-world risk from Python. Each CVE gets an RPS score (from CVSS, EPSS and CISA KEV), a Final Priority, and the reason for its rank. Exploit and fix evidence come with it.
- Standard library only: no dependencies.
- Typed (
py.typed), Python 3.10+. - Retries network errors, 5xx and
429 rate_limited, honouringRetry-After. It never retriesquota_exceeded. - Accepts a list of IDs or a whole scanner report, splits long lists to fit your plan, and merges the results into one ranking.
pip install devsecure-intelligence
export DEVSECURE_API_KEY=dsec_live_... # free key: https://intelligence.devsecure.io/signup
Rank a scanner's findings
from pathlib import Path
from devsecure_intelligence import Client
client = Client() # reads DEVSECURE_API_KEY
result = client.prioritize(Path("trivy.json").read_text()) # any text that mentions CVE IDs
for cve in result["ranked"]:
print(cve["rank_in_request"], cve["cve_id"], cve["priority_band"], cve["rps_score"], cve["reason"])
priority_band is the Final Priority: the RPS band after the CISA KEV floor and the EPSS gate. band_basis says which rule set it (rps, kev_floor or epss_gate). CVEs not in the corpus come last with band unknown and are listed in not_found.
Free keys take 25 IDs per call and Pro and above take 1,000. You can pass a longer list anyway: if the API rejects it as list_too_long, the client re-sends it in chunks of your plan's limit and merges them. The merged list uses the API's own order: band first, then RPS within a band. Pass chunk_size= to choose the size yourself.
Fail a CI step on High, Critical or KEV
import sys
blocking = [c for c in result["ranked"]
if c["priority_band"] in ("critical_priority", "high_priority") or (c.get("evidence") or {}).get("kev", {}).get("listed")]
for c in blocking:
print(f"{c['cve_id']}\t{c['priority_band']}\t{c['reason']}")
sys.exit(1 if blocking else 0)
Your organisation decides what blocks a build. For a ready-made GitHub Action with allowlists, VEX and a job summary, see the CI gate.
Other calls
| Method | Endpoint | Plan |
|---|---|---|
cve(id), rps(id) |
GET /api/v1/cve/{id}, /rps/{id} |
Any key |
cve_batch(ids) |
POST /api/v1/cve/batch |
Any key (Free 100 IDs, Pro+ 1,000) |
prioritize(ids_or_text, chunk_size=None) |
POST /api/v1/prioritize |
Any key |
movers(window="7d", types=[...]), iter_movers(...) |
GET /api/v1/movers |
Any key |
recent(since=...) |
GET /api/v1/cve/recent |
Any key |
cwe_cves(79, is_kev=True) |
GET /api/v1/cwe/{cwe}/cves |
Any key |
intelligence(id) |
GET /api/v1/cve/{id}/intelligence |
Pro and above |
patches(id) |
GET /api/v1/patches/{id} |
Business and Enterprise |
public_cve(id), kev(), stats(), status(), health() |
public endpoints | No key needed |
request(method, path, params=..., json_body=...) |
anything else |
What changed in the last 24 hours:
for m in client.iter_movers(window="24h", types=["kev_added", "priority_change"]):
print(m["occurred_on"], m["cve_id"], m["type"], m.get("priority_now"), m["reason"])
Command line: devsecure
Installing the package also installs a devsecure command:
devsecure cve CVE-2024-3400 # no key needed: falls back to the public record
devsecure prioritize trivy.json grype.json # ranked table of every CVE found in the files
trivy image -f json app:1.2 | devsecure prioritize - --fail-on high,kev
devsecure movers --window 24h --type kev_added,priority_change
devsecure kev --limit 10 # CISA KEV ranked by RPS, no key needed
devsecure --json prioritize sbom.cdx.json # the API's JSON instead of a table
--fail-on takes critical, high, medium and/or kev (comma-separated). Exit codes: 0 done, 1 a CVE matched --fail-on, 2 a usage or API error, with the error's docs link printed. python -m devsecure_intelligence works too.
Errors, limits and quota
Every error raises a DevSecureError carrying status, code, message, docs_url, request_id and retry_after. These subclasses let you catch the common cases:
| Class | When |
|---|---|
AuthenticationError |
401: missing, invalid or revoked key |
PlanError |
403 forbidden_plan: your plan doesn't include the endpoint |
NotFoundError |
404: the CVE isn't in the corpus |
RateLimitError |
429 rate_limited, after the retries are used up |
QuotaExceededError |
429 quota_exceeded: the month's allowance is used (resets on the 1st, UTC) |
client.last_quota holds the rate-limit and quota headers from the last response, for example {"quota_limit": 500, "quota_remaining": 412, "rate_limit_remaining": 19}. client.last_request_id is the ID to quote to support.
Client(api_key="...", base_url="https://api.intelligence.devsecure.io", timeout=30, max_retries=3)
The key is sent only in the Authorization header, and never appears in URLs or in repr(client). base_url must be https://, except http://localhost for testing.
Development
cd sdk/python
pip install pytest
PYTHONPATH=src pytest # unit tests, no network
PYTHONPATH=src pytest -m live # a few public calls to the production API, no key
Licence: MIT. API docs: https://intelligence.devsecure.io/docs. Support: support@devsecure.io.
Metadata
Release files for devsecure-intelligence 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| devsecure_intelligence-0.1.0.tar.gz | 18.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| devsecure_intelligence-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.1 kB
Release files / devsecure_intelligence-0.1.0.tar.gz
| Download URL | devsecure_intelligence-0.1.0.tar.gz |
|---|---|
| Size | 18.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8c5cd148f877f24989559b5390a8072d15c2f63579ee73a08b5f3db9d8c74bb5
|
|
BLAKE2b-256 checksum How to use checksums |
b3098725f8fe915b5bec36f6ba48d88208aeb7bda65379f4810537619c644f87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.10
|
Release files / devsecure_intelligence-0.1.0-py3-none-any.whl
| Download URL | devsecure_intelligence-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e1cb20e726bdd315e8f62f4978057d50ab1ef1d282617a4b607b68c12d44461b
|
|
BLAKE2b-256 checksum How to use checksums |
510e70ba11ef3395ce2206fb3eae1d59311eb9e91968ff19a61fdd09600d14f6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.10
|
Security for devsecure-intelligence 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.