A Python caching API wrapper for the Numista numismatic database with RFC 9111-compliant HTTP caching, intelligent rate limiting, and resilient retry logic.
Includes an optional command-line interface with rich terminal output and sixel image support.
numistalib is a caching API client for Numista, the collaborative online catalogue of world coins, banknotes, and exonumia. The library:
- Caches all GET requests using hishel with configurable TTL (default 7 days)
- Rate limits requests automatically (45 requests/minute by default) via pyrate-limiter
- Retries failed requests with exponential backoff and jitter using tenacity
- Validates all responses with strict Pydantic models
- Provides both sync and async client implementations via httpx
Includes a CLI for interactive exploration with Rich terminal output and sixel protocol image display.
Read the Docs β Complete documentation with search, versioning, and offline formats.
Quick Links:
- RFC 9111-Compliant HTTP Caching: Persistent SQLite cache with configurable TTL and LRU eviction
- Intelligent Rate Limiting: Transport-level throttling with configurable limits (respects Numista quotas)
- Resilient Retry Logic: Exponential backoff with jitter for network failures and rate limit errors
- Complete Type Safety: Full Pydantic v2 models with strict validation for all API entities
- Sync & Async Support: Both synchronous and asynchronous client implementations
- Cache Indicators: Visual feedback (πΎ/π) for cache hits/misses in responses
- Rich Terminal UI: Beautiful tables, panels, and formatted output via Rich
- Sixel Image Support: Display coin images directly in terminal via sixel protocol (textual-image)
- Flexible Display Modes: Table or panel mode for different output preferences
- Command Aliases: Short and long form commands (e.g.,
catalogues/cat)
pip install numistalib
# or with uv
uv pip install numistalibFor development:
git clone https://github.com/wells01440/numistalib
cd numistalib
uv sync-
Get your API key from Numista API
-
Set environment variable:
export NUMISTA_API_KEY=your_api_key_hereOr create
.envfile:cp .env.example .env # Edit .env and add: NUMISTA_API_KEY=your_api_key_here
from numistalib.client import NumistaApiClient
from numistalib.config import Settings
from numistalib.services.types.service import TypeService
settings = Settings() # Loads from environment/env file
with NumistaApiClient(settings) as client:
service = TypeService(client)
# Search for types (cached automatically)
results = service.search_types(query="dollar", page=1, count=10)
for coin_type in results:
print(f"{coin_type.numista_id}: {coin_type.title}")
print(f" Cached: {coin_type.cached_indicator}") # Shows πΎ or π
# Get full details with specifications
full_type = service.get_type(95420)
print(f"Weight: {full_type.weight}g")
print(f"Composition: {full_type.composition}")See Python API Guide for complete examples.
Interactive exploration with rich terminal output.
# Search for types
numistalib types search -q "dollar"
numistalib types search --issuer united-states --year 2020
# Get detailed specifications
numistalib types get 95420
# List available catalogues
numistalib catalogues
# List issuers in different languages
numistalib issuers --lang es
# View configuration
numistalib config listThe CLI uses the sixel protocol to display coin images in your terminal.
Sixel-compatible terminals:
- Kitty (macOS, Linux) β GPU-accelerated with full sixel support
- WezTerm (macOS, Linux, Windows) β GPU-accelerated, full sixel support
- iTerm2 (macOS) β Inline image display
- mlterm (Linux) β Lightweight sixel support
- foot (Linux/Wayland) β Fast, minimal
- yaft (Linux framebuffer) β Console sixel
Testing Your Terminal:
# Install imagemagick for testing
convert -size 100x100 xc:red sixel:- | catIf you see a red square, your terminal supports sixel! If not, the CLI will gracefully fall back to text-only output.
Example Output:
See CLI Guide for complete command reference.
numistalib follows a layered architecture optimized for caching efficiency and maintainability:
- client.py: HTTP client layer with caching (hishel), rate limiting (pyrate-limiter), and retry (tenacity)
- services/: Business logic per API endpoint, inheriting from abstract base classes
- models/: Pydantic v2 models for strict API validation and type safety
- config.py: Settings management with pydantic-settings
- cli/: Optional Click-based interface with Rich formatting and textual-image sixel support
See Architecture Documentation for detailed design patterns.
numistalib is built on excellent open-source libraries:
- httpx β Modern HTTP client with sync/async support
- hishel β RFC 9111-compliant HTTP caching for httpx
- pydantic β Data validation using Python type annotations
- pydantic-settings β Settings management
- pyrate-limiter β Rate limiting strategies
- tenacity β Retrying library with configurable backoff
- click β Command-line interface creation kit
- rich β Rich text and beautiful formatting in terminal
- textual-image β Sixel protocol image rendering
- uv β Fast Python package installer and resolver
- ruff β Fast Python linter and formatter
- pytest β Testing framework
- mypy & pyright β Static type checkers
Contributions are welcome! This project follows community best practices:
- Code of Conduct: Be respectful and inclusive
- Issues: Report bugs or request features via GitHub Issues
- Pull Requests: Fork, branch, and submit PRs with clear descriptions
- Code Quality: All PRs must pass linting (ruff), type checking (mypy/pyright), and tests (pytest)
- Documentation: Update relevant docs for user-facing changes
See Contributing Guide and AGENTS.md for coding standards.
- License: MIT License β Free and open source
- Versioning: Semantic Versioning (MAJOR.MINOR.PATCH)
- Changelog: Keep a Changelog format in CHANGELOG
- Code Quality: Enforced via CI (ruff, mypy, pyright, radon complexity checks)
- Testing: Comprehensive test suite with pytest
- Documentation: Complete user and API documentation on ReadTheDocs
- Unofficial: This library is an independent, community project and is not affiliated with Numista.
- Attribution: Numista is a trademark/service of Numista. Please provide appropriate attribution when displaying data from Numista's API.
- Terms of Use: Users must comply with Numista's published terms:
- Data Usage: Follow Numista's guidelines for caching, rate limits, and redistribution. Configure TTL and cache behavior according to Numista's restrictions, especially for pricing data.
- Rate Limiting: This project implements conservative rate limiting by default (45 requests/minute); always respect Numista's published limits and guidance.
This project is licensed under the MIT License. See the license file for details.
Questions? Check the documentation or open an issue.



