Numista API wrapper
Project description
numistalib
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.
Overview
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.
📖 Documentation
Read the Docs — Complete documentation with search, versioning, and offline formats.
Quick Links:
Features
Core API Features
- 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
Optional CLI Features
- 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)
Installation
pip install numistalib
# or with uv
uv pip install numistalib
For development:
git clone https://github.com/wells01440/numistalib
cd numistalib
uv sync
Configuration
-
Get your API key from Numista API
-
Set environment variable:
export NUMISTA_API_KEY=your_api_key_here
Or create
.envfile:cp .env.example .env # Edit .env and add: NUMISTA_API_KEY=your_api_key_here
Quick Start
Python API
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.
CLI
Interactive exploration with rich terminal output.
Basic Commands
# 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 list
Sixel Image Support
The 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:- | cat
If 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.
Architecture
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.
Built With
numistalib is built on excellent open-source libraries:
Core Dependencies
- 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
CLI Dependencies
- click — Command-line interface creation kit
- rich — Rich text and beautiful formatting in terminal
- textual-image — Sixel protocol image rendering
Development Tools
- uv — Fast Python package installer and resolver
- ruff — Fast Python linter and formatter
- pytest — Testing framework
- mypy & pyright — Static type checkers
Contributing
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.
Community 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
Legal & Attribution
Numista
- 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.
License
This project is licensed under the MIT License. See the license file for details.
Questions? Check the documentation or open an issue.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file numistalib-0.1.2.tar.gz.
File metadata
- Download URL: numistalib-0.1.2.tar.gz
- Upload date:
- Size: 678.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce5e3d609fde71ca0fcc076ea921fcaf543bc01955dbe0624a667b045a7654f4
|
|
| MD5 |
2ee4c7b92a0e1c2f245cf3a30c06f040
|
|
| BLAKE2b-256 |
7697d08c64e4812d7277d656fa29d7e44d3e747c2fc42e48df7a69f00eedd1d2
|
Provenance
The following attestation bundles were made for numistalib-0.1.2.tar.gz:
Publisher:
release.yml on wells01440/numistalib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
numistalib-0.1.2.tar.gz -
Subject digest:
ce5e3d609fde71ca0fcc076ea921fcaf543bc01955dbe0624a667b045a7654f4 - Sigstore transparency entry: 780978694
- Sigstore integration time:
-
Permalink:
wells01440/numistalib@4e7722317508f944fc7b358680c371c2141e47a0 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/wells01440
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4e7722317508f944fc7b358680c371c2141e47a0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file numistalib-0.1.2-py3-none-any.whl.
File metadata
- Download URL: numistalib-0.1.2-py3-none-any.whl
- Upload date:
- Size: 92.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b98360215c790c7f77278634b2136c0a62eb360747b7e69de7caa2aef39aa99d
|
|
| MD5 |
99f1f191beaa1830b15008e372ac98a0
|
|
| BLAKE2b-256 |
a8c364d35611eabec8006c7df9ef9a57eb5d71949e30971dc83f22db7063938f
|
Provenance
The following attestation bundles were made for numistalib-0.1.2-py3-none-any.whl:
Publisher:
release.yml on wells01440/numistalib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
numistalib-0.1.2-py3-none-any.whl -
Subject digest:
b98360215c790c7f77278634b2136c0a62eb360747b7e69de7caa2aef39aa99d - Sigstore transparency entry: 780978697
- Sigstore integration time:
-
Permalink:
wells01440/numistalib@4e7722317508f944fc7b358680c371c2141e47a0 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/wells01440
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4e7722317508f944fc7b358680c371c2141e47a0 -
Trigger Event:
push
-
Statement type: