# GHSA Client
A Python client library for the GitHub Security Advisory (GHSA) API, providing structured access to security advisory data.
## Features
- **Type-safe models**: Full Pydantic models for GHSA data structures
- **Rate limiting**: Built-in rate limit handling and retry logic
- **Flexible queries**: Search advisories with various filters
- **Comprehensive data**: Access to all GHSA fields including CVSS scores, CWE mappings, and package information
## Installation
```bash
pip install ghsa-client
```
## Quick Start
```python
import logging
from ghsa_client import GHSAClient, GHSA_ID
# Set up logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# Create client
client = GHSAClient(logger)
# Get a specific advisory
ghsa_id = GHSA_ID("GHSA-gq96-8w38-hhj2")
advisory = client.get_advisory(ghsa_id)
print(f"Advisory: {advisory.summary}")
print(f"Severity: {advisory.severity}")
print(f"CVSS Score: {advisory.cvss.score if advisory.cvss else 'N/A'}")
```
## Usage
### Authentication
The client automatically uses the `GITHUB_TOKEN` environment variable if available:
```bash
export GITHUB_TOKEN=your_github_token_here
```
### Getting an Advisory
```python
from ghsa_client import GHSAClient, GHSA_ID
client = GHSAClient(logger)
advisory = client.get_advisory(GHSA_ID("GHSA-gq96-8w38-hhj2"))
# Access advisory properties
print(advisory.summary)
print(advisory.severity)
print(advisory.published_at)
print(advisory.vulnerabilities)
```
### Searching Advisories
```python
# Search by ecosystem
advisories = client.search_advisories(ecosystem="npm")
# Search by severity
advisories = client.search_advisories(severity="high")
# Search by date range
advisories = client.search_advisories(published="2024-01-01..2024-12-31")
# Get all advisories for a year
advisories = client.get_all_advisories_for_year(2024)
```
### Rate Limiting
The client automatically handles GitHub's rate limits:
```python
# Check remaining rate limit
rate_limit = client.get_ratelimit_remaining()
print(f"Remaining requests: {rate_limit['resources']['core']['remaining']}")
# The client will automatically wait for rate limit reset when needed
```
## Models
### Advisory
The main model representing a GitHub Security Advisory:
```python
from ghsa_client import Advisory
advisory: Advisory = client.get_advisory(ghsa_id)
# Core properties
advisory.ghsa_id # GHSA_ID object
advisory.cve_id # Optional CVE_ID object
advisory.summary # str
advisory.severity # str
advisory.published_at # str (ISO date)
advisory.description # Optional[str]
# Vulnerability data
advisory.vulnerabilities # List[Vulnerability]
advisory.affected_packages # List[Package] (computed property)
# CVSS data
advisory.cvss # Optional[CVSS]
advisory.cwes # Optional[List[str]]
# Repository information
advisory.source_code_location # Optional[str]
advisory.repository_url # str (property, raises if not found)
# References
advisory.references # List[str]
```
### GHSA_ID
Type-safe GHSA identifier with validation:
```python
from ghsa_client import GHSA_ID, InvalidGHSAIDError
try:
ghsa_id = GHSA_ID("GHSA-gq96-8w38-hhj2")
print(ghsa_id.id) # "GHSA-gq96-8w38-hhj2"
except InvalidGHSAIDError as e:
print(f"Invalid GHSA ID: {e}")
```
### CVE_ID
Type-safe CVE identifier with validation:
```python
from ghsa_client import CVE_ID
cve_id = CVE_ID("CVE-2024-12345")
print(cve_id.id) # "CVE-2024-12345"
```
## Error Handling
The client raises specific exceptions for different error conditions:
```python
from ghsa_client import RateLimitExceeded, GHSAClient
import requests
try:
advisory = client.get_advisory(ghsa_id)
except requests.HTTPError as e:
if e.response.status_code == 404:
print("Advisory not found")
else:
print(f"HTTP error: {e}")
except RateLimitExceeded as e:
print(f"Rate limit exceeded: {e}")
except requests.RequestException as e:
print(f"Network error: {e}")
```
## Development
### Setup
```bash
git clone https://github.com/valmarelox/ghsa-client.git
cd ghsa-client
pip install -e ".[dev]"
```
### Running Tests
```bash
pytest
```
### Code Formatting
```bash
black .
isort .
```
### Type Checking
```bash
mypy src/ghsa_client
```
## License
MIT License - see [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Please open an issue or pull request on [GitHub](https://github.com/valmarelox/ghsa-client).
## Changelog
See the [releases page](https://github.com/valmarelox/ghsa-client/releases) for a history of changes.
Raw data
{
"_id": null,
"home_page": null,
"name": "ghsa-client",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "advisory, cve, ghsa, github, security, vulnerability",
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/89/db/1498538c9c31aacce3b358ca826fe5c5db504d1ba11e38c736418f337980/ghsa_client-1.0.2.tar.gz",
"platform": null,
"description": "# GHSA Client\n\nA Python client library for the GitHub Security Advisory (GHSA) API, providing structured access to security advisory data.\n\n## Features\n\n- **Type-safe models**: Full Pydantic models for GHSA data structures\n- **Rate limiting**: Built-in rate limit handling and retry logic\n- **Flexible queries**: Search advisories with various filters\n- **Comprehensive data**: Access to all GHSA fields including CVSS scores, CWE mappings, and package information\n\n## Installation\n\n```bash\npip install ghsa-client\n```\n\n## Quick Start\n\n```python\nimport logging\nfrom ghsa_client import GHSAClient, GHSA_ID\n\n# Set up logging\nlogger = logging.getLogger(__name__)\nlogger.setLevel(logging.INFO)\n\n# Create client\nclient = GHSAClient(logger)\n\n# Get a specific advisory\nghsa_id = GHSA_ID(\"GHSA-gq96-8w38-hhj2\")\nadvisory = client.get_advisory(ghsa_id)\n\nprint(f\"Advisory: {advisory.summary}\")\nprint(f\"Severity: {advisory.severity}\")\nprint(f\"CVSS Score: {advisory.cvss.score if advisory.cvss else 'N/A'}\")\n```\n\n## Usage\n\n### Authentication\n\nThe client automatically uses the `GITHUB_TOKEN` environment variable if available:\n\n```bash\nexport GITHUB_TOKEN=your_github_token_here\n```\n\n### Getting an Advisory\n\n```python\nfrom ghsa_client import GHSAClient, GHSA_ID\n\nclient = GHSAClient(logger)\nadvisory = client.get_advisory(GHSA_ID(\"GHSA-gq96-8w38-hhj2\"))\n\n# Access advisory properties\nprint(advisory.summary)\nprint(advisory.severity)\nprint(advisory.published_at)\nprint(advisory.vulnerabilities)\n```\n\n### Searching Advisories\n\n```python\n# Search by ecosystem\nadvisories = client.search_advisories(ecosystem=\"npm\")\n\n# Search by severity\nadvisories = client.search_advisories(severity=\"high\")\n\n# Search by date range\nadvisories = client.search_advisories(published=\"2024-01-01..2024-12-31\")\n\n# Get all advisories for a year\nadvisories = client.get_all_advisories_for_year(2024)\n```\n\n### Rate Limiting\n\nThe client automatically handles GitHub's rate limits:\n\n```python\n# Check remaining rate limit\nrate_limit = client.get_ratelimit_remaining()\nprint(f\"Remaining requests: {rate_limit['resources']['core']['remaining']}\")\n\n# The client will automatically wait for rate limit reset when needed\n```\n\n## Models\n\n### Advisory\n\nThe main model representing a GitHub Security Advisory:\n\n```python\nfrom ghsa_client import Advisory\n\nadvisory: Advisory = client.get_advisory(ghsa_id)\n\n# Core properties\nadvisory.ghsa_id # GHSA_ID object\nadvisory.cve_id # Optional CVE_ID object\nadvisory.summary # str\nadvisory.severity # str\nadvisory.published_at # str (ISO date)\nadvisory.description # Optional[str]\n\n# Vulnerability data\nadvisory.vulnerabilities # List[Vulnerability]\nadvisory.affected_packages # List[Package] (computed property)\n\n# CVSS data\nadvisory.cvss # Optional[CVSS]\nadvisory.cwes # Optional[List[str]]\n\n# Repository information\nadvisory.source_code_location # Optional[str]\nadvisory.repository_url # str (property, raises if not found)\n\n# References\nadvisory.references # List[str]\n```\n\n### GHSA_ID\n\nType-safe GHSA identifier with validation:\n\n```python\nfrom ghsa_client import GHSA_ID, InvalidGHSAIDError\n\ntry:\n ghsa_id = GHSA_ID(\"GHSA-gq96-8w38-hhj2\")\n print(ghsa_id.id) # \"GHSA-gq96-8w38-hhj2\"\nexcept InvalidGHSAIDError as e:\n print(f\"Invalid GHSA ID: {e}\")\n```\n\n### CVE_ID\n\nType-safe CVE identifier with validation:\n\n```python\nfrom ghsa_client import CVE_ID\n\ncve_id = CVE_ID(\"CVE-2024-12345\")\nprint(cve_id.id) # \"CVE-2024-12345\"\n```\n\n\n## Error Handling\n\nThe client raises specific exceptions for different error conditions:\n\n```python\nfrom ghsa_client import RateLimitExceeded, GHSAClient\nimport requests\n\ntry:\n advisory = client.get_advisory(ghsa_id)\nexcept requests.HTTPError as e:\n if e.response.status_code == 404:\n print(\"Advisory not found\")\n else:\n print(f\"HTTP error: {e}\")\nexcept RateLimitExceeded as e:\n print(f\"Rate limit exceeded: {e}\")\nexcept requests.RequestException as e:\n print(f\"Network error: {e}\")\n```\n\n## Development\n\n### Setup\n\n```bash\ngit clone https://github.com/valmarelox/ghsa-client.git\ncd ghsa-client\npip install -e \".[dev]\"\n```\n\n### Running Tests\n\n```bash\npytest\n```\n\n### Code Formatting\n\n```bash\nblack .\nisort .\n```\n\n### Type Checking\n\n```bash\nmypy src/ghsa_client\n```\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Please open an issue or pull request on [GitHub](https://github.com/valmarelox/ghsa-client).\n\n## Changelog\n\nSee the [releases page](https://github.com/valmarelox/ghsa-client/releases) for a history of changes.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Python client library for the GitHub Security Advisory (GHSA) API",
"version": "1.0.2",
"project_urls": {
"Repository": "https://github.com/valmarelox/ghsa-client.git"
},
"split_keywords": [
"advisory",
" cve",
" ghsa",
" github",
" security",
" vulnerability"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "731281d49e91585fa68c8bf3f5a5493250ff30fdd5902916f8aa4c16f50520b3",
"md5": "7102af0d156f4078c3db090d13966e9a",
"sha256": "a05d7fb417a5fd918566ff6e523c72b846a7da7b60b518f91d44966e1fcc8125"
},
"downloads": -1,
"filename": "ghsa_client-1.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7102af0d156f4078c3db090d13966e9a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 14609,
"upload_time": "2025-09-19T12:31:16",
"upload_time_iso_8601": "2025-09-19T12:31:16.840900Z",
"url": "https://files.pythonhosted.org/packages/73/12/81d49e91585fa68c8bf3f5a5493250ff30fdd5902916f8aa4c16f50520b3/ghsa_client-1.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "89db1498538c9c31aacce3b358ca826fe5c5db504d1ba11e38c736418f337980",
"md5": "88a00908353eae3e208310bae3cbc75c",
"sha256": "8665e403c981463e573f3f924f3cba7545039e8d63ff81bfb325f2b23fd9f51a"
},
"downloads": -1,
"filename": "ghsa_client-1.0.2.tar.gz",
"has_sig": false,
"md5_digest": "88a00908353eae3e208310bae3cbc75c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 13072,
"upload_time": "2025-09-19T12:31:18",
"upload_time_iso_8601": "2025-09-19T12:31:18.201408Z",
"url": "https://files.pythonhosted.org/packages/89/db/1498538c9c31aacce3b358ca826fe5c5db504d1ba11e38c736418f337980/ghsa_client-1.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-19 12:31:18",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "valmarelox",
"github_project": "ghsa-client",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "ghsa-client"
}