Unsplash¶
Unsplash provides royalty-free, high-resolution photography through a clean REST API. The xanax Unsplash and AsyncUnsplash clients wrap that API with typed, validated access.
Note
Unlike Wallhaven’s SFW tier, the Unsplash API requires an access key for all requests — including read-only search. Register at unsplash.com/developers to obtain one.
Authentication¶
Pass your access key directly, or set the UNSPLASH_ACCESS_KEY environment variable:
from xanax.sources import Unsplash
# Explicit key
unsplash = Unsplash(access_key="your-access-key")
# From environment (UNSPLASH_ACCESS_KEY=...)
unsplash = Unsplash()
Searching for photos¶
from xanax.sources import Unsplash
from xanax.sources.unsplash import UnsplashSearchParams
unsplash = Unsplash(access_key="your-access-key")
result = unsplash.search(UnsplashSearchParams(query="mountains"))
print(result.total)
for photo in result.results:
print(photo.id, photo.resolution, photo.urls.regular)
Filter by orientation or color¶
from xanax.sources.unsplash.enums import UnsplashOrientation, UnsplashColor
result = unsplash.search(UnsplashSearchParams(
query="ocean",
orientation=UnsplashOrientation.LANDSCAPE,
color=UnsplashColor.BLUE,
))
Iterating all pages¶
iter_media() flattens all pages into individual photo objects automatically:
for photo in unsplash.iter_media(UnsplashSearchParams(query="landscape")):
print(photo.id, photo.resolution)
Getting a random photo¶
photo = unsplash.random()
print(photo.id, photo.urls.full)
Downloading¶
download() handles the Unsplash attribution tracking step automatically:
from pathlib import Path
photo = unsplash.random()
data: bytes = unsplash.download(photo)
unsplash.download(photo, path=Path("wallpaper.jpg"))
Note
Unsplash requires a GET to photo.links.download_location before downloading the actual image. download() does both steps automatically to satisfy the Unsplash Terms of Service.
Async client¶
import asyncio
from xanax.sources import AsyncUnsplash
from xanax.sources.unsplash import UnsplashSearchParams
async def main():
async with AsyncUnsplash(access_key="your-access-key") as unsplash:
async for photo in unsplash.aiter_media(UnsplashSearchParams(query="forest")):
data = await unsplash.download(photo)
asyncio.run(main())
Rate limiting¶
Unsplash allows 50 demo requests per hour (1000 for production apps). Enable automatic retry:
unsplash = Unsplash(access_key="your-key", max_retries=3)
See also¶
Clients — complete method signatures
Search Parameters — search parameter reference
Error Handling — exception hierarchy