Changelog¶
0.2.2¶
Documentation and metadata cleanup. No changes to client behavior.
- Removed transient release-status notes from the README and the documentation site.
0.2.1¶
Documentation release. No changes to client behavior.
- Added a documentation site (MkDocs Material, with an API reference
generated from the docstrings) at https://ahur4.github.io/nvd-client/.
GitHub Actions builds it with
mkdocs build --strictand deploys it to GitHub Pages frommain. - Added a
docsextra:pip install -e ".[docs]". - PyPI project URLs now include Documentation (https://ahur4.github.io/nvd-client/), Homepage, Source, Repository, Issues, and Changelog.
0.2.0¶
This release makes the client match the NVD API 2.0, replaces raw dictionaries with typed models, and stops hiding failed requests. It is not published to PyPI by this change.
Breaking changes¶
- Python 3.10 or newer is required (3.9 reached end of life in October 2025).
- CVE and CPE methods return pydantic models. They no longer return a
dictorNone. get_all_cves,get_cve_by_date, andget_cve_by_cpereturnCveListResponse. Records for the page areresponse.cves.get_cve_by_idreturns oneCveRecord. A missing id raisesNvdNotFoundError.get_cpes_by_cve,get_cpes_by_criteria, andget_cpes_by_criteria_name_idreturnCpeMatchResponse.model_dump()uses snake_case.model_dump(by_alias=True)uses the NVD camelCase names.model_dump_json()accepts the same arguments.- HTTP failures, rate limits, and documents that do not match the schema
raise
NvdApiError,NvdRateLimitError,NvdNotFoundError, orNvdResponseError. They are not returned asNone. - Date arguments must be
datetimevalues. Naive values are treated as UTC and sent asYYYY-MM-DDTHH:MM:SS.sss+00:00. Aware values are converted to UTC. A range missing one end, reversed, or longer than 120 days raisesInvalidParametersError. per_pageoutside NVD's maximum (2000 for CVEs, 500 for CPE match strings) raisesInvalidParametersErrorinstead of being sent.- A per-call
proxyoverrides the client proxy. Previously the client proxy won and the argument was ignored. str(NvdApi(...))describes the base URL and whether an API key is set. The key itself is not included.pytzis no longer a dependency. Pass timezone-aware datetimes from the standard library (datetime.timezoneorzoneinfo) instead.
Fixes¶
- Issue #3: importing the package after
pip installrequiredpytz, butsetup.pynever declared it (requirements.txtdid, and nothing used the timezone object). The dependency is removed. Dates use the standard library. - Issue #2: the sample fetched nothing because every request error was
swallowed, and because query strings were concatenated by hand. A
+in a UTC offset was not encoded as%2B, which NVD requires, and a naive localdatetime.now()was sent as wall-clock time that NVD reads as GMT. Requests now go throughparams, timestamps are explicit UTC, and failures raise.
Other behavior¶
- Retries with exponential backoff for connection errors and HTTP 403, 429,
500, 502, 503, and 504.
Retry-Afteris honored. A 403 that reports an invalid API key is not retried. - The client waits between calls so it stays inside NVD's published windows:
6 seconds without an API key (5 requests / 30 seconds) and 0.6 seconds with
one (50 requests / 30 seconds). Set
rate_limit_delayto override. - Optional API key is sent in the
apiKeyheader. NvdConfigcontrols the base URL, API key, timeout, page size, rate-limit delay, retries, backoff, user agent, and proxy.
Dependencies¶
Direct dependencies are lower bounds only. Transitive pins that forced old,
vulnerable releases of urllib3 and requests are gone. urllib3 and
idna are declared directly because requests still allows versions with
known vulnerabilities. PySocks is an optional socks extra.
| Package | Before | After |
|---|---|---|
| requests | ==2.32.3 (with the socks extra) |
>=2.33.0 |
| urllib3 | ==2.2.1 |
>=2.8.0,<3 |
| idna | ==3.7 |
>=3.7,<4 |
| certifi | ==2024.6.2 |
not declared (pulled by requests) |
| charset-normalizer | ==3.3.2 |
not declared (pulled by requests) |
| pytz | imported, listed only in requirements.txt |
removed |
| pydantic | not used | >=2.4,<3 |
| PySocks | always, via requests[socks] |
optional extra socks |
0.1.3.1¶
Last release published from the previous setup.py line. CVE calls returned
decoded JSON dictionaries, or None when the request failed.