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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.