Python client for the Unsplash API
Project description
Unsplash Client
Lightweight, typed Python client for the Unsplash API focusing on the photo search endpoint. Includes:
- Async HTTP powered by
httpx - Pydantic models for responses & request params
- A fluent builder (
UnsplashSearchParamsBuilder) for ergonomic query construction - Direct kwargs usage if you prefer no builder
- Automatic retry on rate-limit responses (429) via the
async_retrydecorator
Installation
Requires Python 3.13+.
pip install unsplash-wrapper
Set your Unsplash access key (Create one in your Unsplash developer dashboard):
export UNSPLASH_API_KEY=your_access_key_here # macOS/Linux
$env:UNSPLASH_API_KEY='your_access_key_here' # PowerShell
Quick Start
from unsplash_client import UnsplashClient
client = UnsplashClient() # Uses UNSPLASH_API_KEY from environment
response = await client.search_photos(query="mountains")
print("Total found:", response.total)
for photo in response.results:
print(photo.id, photo.url)
Search Parameter Options
You can provide parameters in two styles: Builder or Raw kwargs.
1. Builder style
from unsplash_client import (
UnsplashClient,
UnsplashSearchParamsBuilder,
Orientation,
ContentFilter,
OrderBy,
)
builder = (
UnsplashSearchParamsBuilder()
.with_query("sunset beach")
.with_limit(20)
.with_landscape_orientation()
.with_high_quality()
.with_order_by_latest()
.with_page(2)
)
params = builder.build()
client = UnsplashClient()
response = await client.search_photos(params)
print(f"Returned {len(response.results)} of {response.total} total")
2. Direct kwargs style
All fields mirror the Pydantic model UnsplashSearchParams:
from unsplash_client import UnsplashClient, Orientation, ContentFilter, OrderBy
client = UnsplashClient()
response = await client.search_photos(
query="architecture",
per_page=15,
orientation=Orientation.PORTRAIT,
content_filter=ContentFilter.HIGH,
page=1,
order_by=OrderBy.RELEVANT,
)
for p in response.results:
print(p.id, p.user.username)
Models Overview
from unsplash_client import UnsplashSearchResponse
# UnsplashSearchResponse fields:
# total: int -> total matching results
# total_pages: int -> number of pages available
# results: list[UnsplashPhoto]
#
# UnsplashPhoto exposes convenient properties like:
# photo.url (regular size URL)
Error Handling
The client raises typed exceptions from unsplash_client.exceptions:
UnsplashAuthenticationException– missing/invalid key (401)UnsplashNotFoundException– resource not found (404)UnsplashRateLimitException– rate limited (429) (containsretry_afterif provided)UnsplashServerException– server error 5xxUnsplashClientException– other 4xx errorsUnsplashTimeoutException– request timed out
Example:
from unsplash_client import (
UnsplashClient,
UnsplashRateLimitException,
UnsplashAuthenticationException,
)
client = UnsplashClient()
try:
response = await client.search_photos(query="forest")
except UnsplashRateLimitException as e:
if e.retry_after:
print(f"Rate limited; retry after {e.retry_after}s")
else:
print("Rate limited; no retry window provided")
except UnsplashAuthenticationException:
print("Invalid API key configured")
Retry Behavior
search_photos automatically retries 429 responses up to 3 times with exponential backoff (1s, 2s, 4s). Other errors fail fast.
Logging
The client uses a library-specific logger name: unsplash_client.UnsplashClient. Attach handlers or configure globally:
import logging
logging.basicConfig(level=logging.INFO)
Advanced: Custom Param Object
If you need to construct params manually (validation enforced):
from unsplash_client import UnsplashSearchParams, Orientation
params = UnsplashSearchParams(query="minimal", per_page=5, orientation=Orientation.SQUARISH)
client = UnsplashClient()
response = await client.search_photos(params)
Development
Run tests:
uv run pytest -q
Type check (if mypy configured):
mypy unsplash_client
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 unsplash_wrapper-0.1.0.tar.gz.
File metadata
- Download URL: unsplash_wrapper-0.1.0.tar.gz
- Upload date:
- Size: 52.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7cd3e2f662491f7fcfdd2974a466b9060ff96567f8aa1298a4c354bc49664252
|
|
| MD5 |
7cb371b68ba3948ce06d087717b9ec3b
|
|
| BLAKE2b-256 |
67db1e1b771127c3f0273f5d053625744758d02b82cb2831827782b132bd2ff0
|
File details
Details for the file unsplash_wrapper-0.1.0-py3-none-any.whl.
File metadata
- Download URL: unsplash_wrapper-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ddc17ee10237dd744e665fd81f80ca4c9bbdec428a32be9586b507abcd2e4324
|
|
| MD5 |
0ce40bb534872d64a79d07bf7b57a9a0
|
|
| BLAKE2b-256 |
6f34953c23408e9595238c2fb4c2a919e57a77fb17f152a6a6156c1fcddfed65
|