Skip to main content

cryptopanic

Unit Tests Integration Tests codecov PyPI version Python 3.10+ License: MIT Code style: black Ruff

A modern, type-safe Python client library for the CryptoPanic API. This library provides a clean, intuitive interface to access cryptocurrency news and market data.

Features

  • 🚀 Type-safe: Built with Pydantic for robust data validation
  • 🎯 Easy to use: Simple, Pythonic API design
  • 🔒 Error handling: Comprehensive exception handling for all API error codes
  • 📦 Well tested: High test coverage with pytest
  • 🛠️ Developer friendly: Full type hints, comprehensive documentation
  • ⚡ Async ready: Built on requests for reliable HTTP handling

Installation

pip install cryptopanic

Quick Start

from cryptopanic import CryptoPanicClient

# Initialize the client with your API token
client = CryptoPanicClient(auth_token="your_api_token_here")

# Get news posts for Bitcoin and Ethereum
posts = client.get_posts(
    currencies=["BTC", "ETH"],
    filter="rising"
)

# Iterate through posts
for post in posts.results:
    print(f"{post.title} - {post.published_at}")
    print(f"Source: {post.source.title}")
    print(f"URL: {post.url}")
    print(f"Panic Score: {post.panic_score}")
    print("-" * 50)

API Reference

CryptoPanicClient

The main client class for interacting with the CryptoPanic API.

Initialization

client = CryptoPanicClient(
    auth_token: str,  # Your CryptoPanic API token (required)
    timeout: int = 30  # Request timeout in seconds (optional)
)

Methods

get_posts(...)

Retrieve a list of news posts with various filtering options.

Parameters:

  • public (bool, optional): Enable public mode (uses non-user-specific settings)
  • currencies (list[str], optional): Filter by currency codes (e.g., ["BTC", "ETH"])
  • regions (list[str], optional): Filter by regions (e.g., ["en", "fr"])
  • filter (str, optional): Filter by type: "rising", "hot", "bullish", "bearish", "important", "saved", "lol"
  • kind (str, optional): Filter by news kind: "news", "media", "all" (default: "all")
  • following (bool, optional): Filter by sources you follow (PRIVATE API only)
  • last_pull (datetime | str, optional): Limit search to last pull time (ISO 8601) - Enterprise only
  • panic_period (str, optional): Include panic score for period: "1h", "6h", "24h" - Enterprise only
  • panic_sort (str, optional): Sort by panic score: "asc" or "desc" (requires panic_period) - Enterprise only
  • size (int, optional): Items per page (1-500, max 500) - Enterprise only
  • with_content (bool, optional): Filter items with full content - Enterprise only
  • search (str, optional): Search by keyword - Enterprise only
  • format (str, optional): Response format (e.g., "rss") - returns max 20 items

Returns: PostsResponse object containing:

  • results: List of Post objects
  • next: URL for next page (or None)
  • previous: URL for previous page (or None)

Example:

# Get rising news for Bitcoin
posts = client.get_posts(
    currencies=["BTC"],
    filter="rising"
)

# Get public news in English and French
posts = client.get_posts(
    public=True,
    regions=["en", "fr"]
)

# Search for specific keywords (Enterprise plan)
posts = client.get_posts(
    search="bitcoin halving"
)
get_portfolio()

Retrieve your portfolio. Available only for GROWTH and ENTERPRISE API plans.

Returns: PortfolioResponse object

Example:

portfolio = client.get_portfolio()

Data Models

Post

Represents a news post from CryptoPanic.

class Post:
    id: int
    slug: str
    title: str
    description: str
    published_at: datetime
    created_at: datetime
    kind: str  # "news", "media", "blog", "twitter", "reddit"
    source: Source
    original_url: str
    url: str
    image: str | None
    instruments: list[Instrument]
    votes: Votes
    panic_score: int | None  # 0-100
    panic_score_1h: int | None  # 0-100
    author: str | None
    content: Content | None

Instrument

Represents a cryptocurrency instrument.

class Instrument:
    code: str  # e.g., "BTC"
    title: str  # e.g., "Bitcoin"
    slug: str
    url: str
    market_cap_usd: float | None
    price_in_usd: float | None
    price_in_btc: float | None
    price_in_eth: float | None
    price_in_eur: float | None
    market_rank: int | None

Source

Represents a news source.

class Source:
    title: str
    region: str  # Language code (e.g., "en", "fr")
    domain: str
    type: str  # "feed", "blog", "twitter", "media", "reddit"

Votes

Represents vote counts for a post.

class Votes:
    negative: int
    positive: int
    important: int
    liked: int
    disliked: int
    lol: int
    toxic: int
    saved: int
    comments: int

Error Handling

The library provides specific exception classes for different error scenarios:

from cryptopanic import (
    CryptoPanicClient,
    CryptoPanicAuthenticationError,
    CryptoPanicForbiddenError,
    CryptoPanicRateLimitError,
    CryptoPanicServerError,
    CryptoPanicAPIError,
)

client = CryptoPanicClient(auth_token="your_token")

try:
    posts = client.get_posts()
except CryptoPanicAuthenticationError:
    print("Invalid API token")
except CryptoPanicRateLimitError:
    print("Rate limit exceeded. Please wait before making more requests.")
except CryptoPanicForbiddenError:
    print("Access forbidden. Check your API plan limits.")
except CryptoPanicServerError:
    print("Server error. Please try again later.")
except CryptoPanicAPIError as e:
    print(f"API error: {e}")

Exception Classes

  • CryptoPanicAPIError: Base exception for all API errors
  • CryptoPanicAuthenticationError: Raised on 401 Unauthorized
  • CryptoPanicForbiddenError: Raised on 403 Forbidden (rate limit or access denied)
  • CryptoPanicRateLimitError: Raised on 429 Too Many Requests
  • CryptoPanicServerError: Raised on 500 Internal Server Error

Examples

Filter by Multiple Currencies

posts = client.get_posts(
    currencies=["BTC", "ETH", "SOL"],
    filter="hot"
)

for post in posts.results:
    print(f"{post.title}")
    for instrument in post.instruments:
        print(f"  - {instrument.code}: ${instrument.price_in_usd}")

Get Posts with Full Content

# Enterprise plan only
posts = client.get_posts(
    currencies=["BTC"],
    with_content=True
)

for post in posts.results:
    if post.content:
        print(f"Title: {post.title}")
        print(f"Clean content: {post.content.clean}")

Pagination

posts = client.get_posts(currencies=["BTC"])

# Process first page
for post in posts.results:
    print(post.title)

# Get next page (you would need to parse the URL or implement pagination helper)
if posts.next:
    print(f"Next page: {posts.next}")

RSS Feed

# Get RSS feed (max 20 items)
posts = client.get_posts(
    currencies=["BTC"],
    format="rss"
)

Development

Setup

# Clone the repository
git clone https://github.com/guilyx/cryptopanic.git
cd cryptopanic

# Install in development mode
pip install -e ".[dev]"

# Install pre-commit hooks
pre-commit install

Running Tests

# Run all tests (unit tests only, uses mocked requests)
pytest

# Run with coverage
pytest --cov=cryptopanic --cov-report=html

# Run specific test file
pytest tests/test_client.py

# Run integration tests (requires CRYPTOPANIC_AUTH_TOKEN env var)
CRYPTOPANIC_AUTH_TOKEN=your_token pytest tests/test_integration.py

# Run all tests including integration tests
CRYPTOPANIC_AUTH_TOKEN=your_token pytest

Note: Unit tests use mocked API responses and don't require a real API token. Integration tests make real API calls and require the CRYPTOPANIC_AUTH_TOKEN environment variable to be set.

Code Quality

# Format code
black .

# Lint code
ruff check .

# Type checking
mypy cryptopanic

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass and code is formatted
  6. Commit your changes (following the commit message guidelines)
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • CryptoPanic for providing the API
  • All contributors who help improve this library

Release Process

Development Flow

  1. Feature Development: Work happens on feature branches
  2. Merge to Master: Features are merged to master after review
  3. Release Candidates: When enough features accumulate (typically 3-5), create a release candidate:
    # Update version in pyproject.toml (e.g., 0.2.0rc1)
    git add pyproject.toml CHANGELOG.md
    git commit -m "chore: prepare release 0.2.0rc1"
    git tag v0.2.0rc1
    git push origin master --tags
    
    • Optional: Create a GitHub Release marked as "pre-release" for testing (won't publish to PyPI)
    • Test: Install and test the release candidate: pip install cryptopanic==0.2.0rc1
  4. Final Release: After testing passes, create final release:
    # Update version in pyproject.toml (e.g., 0.2.0)
    git add pyproject.toml CHANGELOG.md
    git commit -m "chore: release 0.2.0"
    git tag v0.2.0
    git push origin master --tags
    
  5. GitHub Release: Create a GitHub Release with the tag (via UI or gh release create v0.2.0)
  6. Auto-publish: Workflow automatically publishes final releases to PyPI (pre-releases are skipped)

Setup (One-time)

PyPI Trusted Publishing:

  1. Create GitHub Environment: Settings → Environments → New (pypi)
  2. Configure at https://pypi.org/manage/account/publishing/:
    • Project: cryptopanic
    • Workflow: publish.yml
    • Environment: pypi
    • Repository: guilyx/cryptopanic

Version Format: Follow Semantic Versioning (MAJOR.MINOR.PATCH)

Support

For issues, questions, or contributions, please open an issue on GitHub.

Changelog

See CHANGELOG.md for detailed release notes.

Metadata

Release files for cryptopanic 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cryptopanic 0.1.0
File Size Uploaded
cryptopanic-0.1.0.tar.gz 19.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cryptopanic 0.1.0
File Interpreter ABI Platform
cryptopanic-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.9 kB

Release files / cryptopanic-0.1.0.tar.gz

Download URL cryptopanic-0.1.0.tar.gz
Size 19.0 kB
Tags Source
SHA-256 checksum
How to use checksums
0cb0ee38b7a213f3571c313be8af69d253301454b1b14ca99e2fca3d599b3b3b
BLAKE2b-256 checksum
How to use checksums
e3491d34c757281652a391e5a7fa1c3847a62a4797a9d13637cd9f01cfb9c6d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 8, 2026.

Transparency log

Release files / cryptopanic-0.1.0-py3-none-any.whl

Download URL cryptopanic-0.1.0-py3-none-any.whl
Size 11.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a6cc116954c46b4e34e6265fc36bc221423b0d516fccf850468f535337b80c43
BLAKE2b-256 checksum
How to use checksums
778583a2dfade6470d5f1f5af3965e4110398d96165ab364d5d458ab432329e3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page