Skip to main content

Python client for the Unsplash API

Project description

Unsplash Wrapper

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_retry decorator

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_wrapper import UnsplashClient

client = UnsplashClient()
photos = await client.search_photos(query="mountains")

for photo in photos:
    print(photo.id, photo.url)

Search Parameter Options

You can provide parameters in two styles: Builder or Raw kwargs.

1. Builder style

from unsplash_wrapper 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()
photos = await client.search_photos(params)

for photo in photos:
	print(photo.id, photo.description, photo.url)

2. Direct kwargs style

All fields mirror the Pydantic model UnsplashSearchParams:

from unsplash_wrapper import UnsplashClient, Orientation, ContentFilter, OrderBy

client = UnsplashClient()
photos = await client.search_photos(
    query="architecture",
    per_page=15,
    orientation=Orientation.PORTRAIT,
    content_filter=ContentFilter.HIGH,
    page=1,
    order_by=OrderBy.RELEVANT,
)

for photo in photos:
    print(photo.id, photo.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) (contains retry_after if provided)
  • UnsplashServerException – server error 5xx
  • UnsplashClientException – other 4xx errors
  • UnsplashTimeoutException – 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

unsplash_wrapper-0.2.0.tar.gz (52.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

unsplash_wrapper-0.2.0-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

Details for the file unsplash_wrapper-0.2.0.tar.gz.

File metadata

  • Download URL: unsplash_wrapper-0.2.0.tar.gz
  • Upload date:
  • Size: 52.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.8

File hashes

Hashes for unsplash_wrapper-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e3ad925873c238a4195b34f6e0332f1cd3b3e5571eebfc50dfea1d9950bb95be
MD5 b947ba879c5377726cc2cd57e0aeb5db
BLAKE2b-256 c64a3da3bf704acfb3a57830d593ce0bbf508fdd9fe5f6e818b489853aa5e4dc

See more details on using hashes here.

File details

Details for the file unsplash_wrapper-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for unsplash_wrapper-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93b14196cf3cb24d2e4994681186d9cc0f09b6840be034fcbd3b3af803d12f93
MD5 cd2ffc4381d46e2db885bfe3dd830b60
BLAKE2b-256 191b2b5e4be297333b63392ab096a82bc75d604559b7ae9997ec9660869cd248

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page