A clean, type-safe Python client for the Wallhaven.cc API v1
Project description
xanax
A clean, type-safe Python client for the Wallhaven.cc API v1.
Features
- Type-safe: All responses are parsed into Pydantic models with full type hints
- Validated parameters: Search parameters are validated before making API requests
- Clean error handling: Structured error hierarchy for easy error handling
- Rate limit aware: Handles rate limiting with optional retry support
- Secure: API key is never logged or exposed in any output
- No magic: Explicit method calls, no hidden defaults
Installation
pip install xanax
Or with uv:
uv add xanax
Quick Start
from xanax import Xanax, SearchParams, Purity, Sort
# Create a client (optional API key for NSFW content)
client = Xanax(api_key="your-api-key")
# Search for wallpapers
params = SearchParams(
query="+anime -sketch",
purity=[Purity.SFW],
sorting=Sort.TOPLIST,
)
results = client.search(params)
# Iterate through results
for wallpaper in results.data:
print(f"{wallpaper.resolution} - {wallpaper.path}")
# Check pagination
print(f"Page {results.meta.current_page} of {results.meta.last_page}")
Authentication
The Wallhaven API requires an API key for NSFW content. You can get your API key from your Wallhaven account settings.
client = Xanax(api_key="your-api-key")
The API key is stored securely and never exposed in any string representations.
Search Parameters
SearchParams provides type-safe search parameters:
from xanax import SearchParams
from xanax.enums import Category, Purity, Sort, Order, TopRange, Color, FileType
params = SearchParams(
query="+nature -water", # Include/exclude tags
categories=[Category.GENERAL, Category.ANIME],
purity=[Purity.SFW], # SFW, SKETCHY, NSFW (requires API key)
sorting=Sort.TOPLIST, # date_added, relevance, random, views, favorites, toplist
order=Order.DESC, # desc or asc
top_range=TopRange.ONE_MONTH, # 1d, 3d, 1w, 1M, 3M, 6M, 1y (only with toplist sorting)
resolutions=["1920x1080", "2560x1440"],
ratios=["16x9", "4x3"],
colors=[Color.BLUE, Color.GREEN],
file_type=FileType.PNG, # Filter by file type (png or jpg)
like="94x38z", # Find wallpapers similar to this ID
page=1,
seed="abc123", # For random sorting consistency
)
API Reference
Xanax Client
client = Xanax(api_key=None, timeout=30.0, max_retries=0)
Methods:
client.wallpaper(id: str) -> Wallpaper- Get a specific wallpaperclient.search(params: SearchParams) -> SearchResult- Search for wallpapersclient.tag(id: int) -> Tag- Get tag informationclient.settings() -> UserSettings- Get authenticated user's settingsclient.collections(username: str | None = None) -> list[Collection]- Get collectionsclient.collection(username: str, id: int) -> CollectionListing- Get wallpapers in a collection
Error Handling
from xanax import Xanax
from xanax.errors import (
XanaxError,
AuthenticationError,
RateLimitError,
NotFoundError,
ValidationError,
APIError,
)
try:
client = Xanax(api_key="your-key")
results = client.search(SearchParams(query="anime"))
except AuthenticationError:
print("Invalid API key")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds")
except NotFoundError:
print("Resource not found")
except ValidationError as e:
print(f"Invalid parameters: {e.message}")
except APIError as e:
print(f"API error: {e.status_code}")
Pagination Helper
from xanax.pagination import PaginationHelper
results = client.search(params)
# Use the helper for easier pagination
helper = PaginationHelper(results.meta)
if helper.has_next:
next_page = helper.next_page_number()
next_params = params.with_page(next_page)
next_results = client.search(next_params)
Models
All API responses are parsed into typed Pydantic models:
Wallpaper- Single wallpaper detailsTag- Tag informationUploader- User uploader info with avatarAvatar- User avatar at different sizesThumbnails- Thumbnail URLsSearchResult- Search results with wallpapers and metaPaginationMeta- Pagination informationQueryInfo- Resolved search query infoUserSettings- User preferencesCollection- Collection infoCollectionListing- Collection wallpapers
Enumerations
All search parameters have type-safe enums:
Category- general, anime, peoplePurity- sfw, sketchy, nsfwSort- date_added, relevance, random, views, favorites, toplistOrder- desc, ascTopRange- 1d, 3d, 1w, 1M, 3M, 6M, 1yColor- All valid wallhaven colorsFileType- png, jpg
Rate Limiting
The Wallhaven API allows 45 requests per minute. By default, the client fails fast when rate limited. You can enable automatic retries:
client = Xanax(max_retries=3) # Retry up to 3 times with exponential backoff
Development
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=xanax
License
MIT
Project details
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 xanax-0.1.1.tar.gz.
File metadata
- Download URL: xanax-0.1.1.tar.gz
- Upload date:
- Size: 49.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ed797e7b6b577da108af8ef6f6cdc13bb44cbc9f1c52187e8d92d79178eacc5
|
|
| MD5 |
77dfe83dd36dd6bb8e96f79374290f42
|
|
| BLAKE2b-256 |
920f988681f8cebbfbf80c8678f1907f0252e589bc602b03ed98c34711b990ff
|
Provenance
The following attestation bundles were made for xanax-0.1.1.tar.gz:
Publisher:
publish.yml on violhex/Xanax
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xanax-0.1.1.tar.gz -
Subject digest:
3ed797e7b6b577da108af8ef6f6cdc13bb44cbc9f1c52187e8d92d79178eacc5 - Sigstore transparency entry: 996038767
- Sigstore integration time:
-
Permalink:
violhex/Xanax@60b0d7d87a6acf1e5fe6bff75f6075571cbd6581 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/violhex
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@60b0d7d87a6acf1e5fe6bff75f6075571cbd6581 -
Trigger Event:
release
-
Statement type:
File details
Details for the file xanax-0.1.1-py3-none-any.whl.
File metadata
- Download URL: xanax-0.1.1-py3-none-any.whl
- Upload date:
- Size: 16.9 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 |
a5c9ccfb0a4a359b2d5104aba8eda4f758d174a7ee413e2a2a3546757a9ebca8
|
|
| MD5 |
03701e3e6571dd61b7b8df21cc79d472
|
|
| BLAKE2b-256 |
e1b507ec24f4209eda860fddc2fe57d7745c7711896cb701bb1520010824a9d0
|
Provenance
The following attestation bundles were made for xanax-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on violhex/Xanax
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xanax-0.1.1-py3-none-any.whl -
Subject digest:
a5c9ccfb0a4a359b2d5104aba8eda4f758d174a7ee413e2a2a3546757a9ebca8 - Sigstore transparency entry: 996038832
- Sigstore integration time:
-
Permalink:
violhex/Xanax@60b0d7d87a6acf1e5fe6bff75f6075571cbd6581 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/violhex
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@60b0d7d87a6acf1e5fe6bff75f6075571cbd6581 -
Trigger Event:
release
-
Statement type: