paint-brush
How to Programatically Get Photos Matching Content in Your Apps With Python and Unsplash APIby@horosin
151 reads

How to Programatically Get Photos Matching Content in Your Apps With Python and Unsplash API

by Karol HorosinSeptember 29th, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

I often look for ways to make my projects visually interesting but struggle with finding content. For instance, when displaying city-related info on a subpage, having a header photo of that city would be great. While AI can generate images, there are issues with that approach. Instead, I found a solution using Unsplash, which has a great API for fetching photos based on search queries. I walk through how to set up the API in Python, handle rate limits, and ensure proper attribution. It’s an easy way to add images dynamically to your projects.
featured image - How to Programatically Get Photos Matching Content in Your Apps With Python and Unsplash API
Karol Horosin HackerNoon profile picture


Introduction

I often want to add visually interesting elements to my projects and struggle with content. Let’s say you have a subpage that shows all the posts/any other information related to a city. It would be great to have a photo of said city in the header, wouldn’t it?


You may think that the way to go is to generate something with AI. It may work, but there are many issues with this approach.


There are great free stock photo sites like Pexels or Unsplash. But how to find the right picture?


I stumbled upon this problem while working on one of my side projects. It turns out Unsplash has a great API. In Python, we need to call it manually but there are client packages for JS, Ruby, PHP, mobile, etc.

Unsplash API

The API basically allows you to find photos matching your search query. A few caveats:


  1. Make sure you use direct links from Unsplash. Downloading and re-hosting images is not allowed.


  2. You must attribute Unsplash and the author.


  3. The API is rate limited to 50 requests per hour for unverified apps, 5k after approval and more if you need it.


More on usage guidelines: Unsplash.


Getting started (in-depth guide):


  1. Sign up for an account: https://unsplash.com/oauth/applications


  2. Go to your apps: https://unsplash.com/oauth/applications


  3. Create a “New application.”


  4. Go to your app and save Access key; we’ll need it in the following steps

Fetching an Image

Have a look at this sample function; you can adapt it to your needs.


import requests
import os

# Load Unsplash API key from environment variables
UNSPLASH_ACCESS_KEY = os.getenv('UNSPLASH_ACCESS_KEY')

def fetch_image_info(query):
    url = "<https://api.unsplash.com/search/photos>"
    params = {
        "query": query,
        "client_id": UNSPLASH_ACCESS_KEY,
        "per_page": 1,
        "orientation": "landscape",
    }
    response = requests.get(url, params=params)

    if response.status_code == 200:
        data = response.json()
        if data['results']:
            return data['results'][0]
    elif response.status_code == 403:
		    raise ConnectionError("Rate limited or not authorized")

    return None


When you call this function for a “New York” query, you should receive an object like that:


{
   "id": "string",
   "slug": "string",
   "created_at": "string",
   "width": "integer",
   "height": "integer",
   "color": "string",
   "blur_hash": "string",
   "alt_description": "string",
   "breadcrumbs": "array",
   "urls": "object",
   "links": "object",
   "likes": "integer",
   "user": "object",
   "tags": "array",
   "...": "..."
}


You should pay attention to three of them really.


First, urls - this is what you will use in your app.


 "urls": {
    "raw": "<https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?ixid=M3w2MjA1MzR8MHwxfHNlYXJjaHwxfHxOZXclMjBZb3JrfGVufDB8MHx8fDE3MjA5MDAxMTd8MA&ixlib=rb-4.0.3>",
    "full": "<https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?crop=entropy&cs=srgb&fm=jpg&ixid=M3w2MjA1MzR8MHwxfHNlYXJjaHwxfHxOZXclMjBZb3JrfGVufDB8MHx8fDE3MjA5MDAxMTd8MA&ixlib=rb-4.0.3&q=85>",
    "regular": "<https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w2MjA1MzR8MHwxfHNlYXJjaHwxfHxOZXclMjBZb3JrfGVufDB8MHx8fDE3MjA5MDAxMTd8MA&ixlib=rb-4.0.3&q=80&w=1080>",
    "small": "<https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w2MjA1MzR8MHwxfHNlYXJjaHwxfHxOZXclMjBZb3JrfGVufDB8MHx8fDE3MjA5MDAxMTd8MA&ixlib=rb-4.0.3&q=80&w=400>",
    "thumb": "<https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w2MjA1MzR8MHwxfHNlYXJjaHwxfHxOZXclMjBZb3JrfGVufDB8MHx8fDE3MjA5MDAxMTd8MA&ixlib=rb-4.0.3&q=80&w=200>",
    "small_s3": "<https://s3.us-west-2.amazonaws.com/images.unsplash.com/small/photo-1496442226666-8d4d0e62e6e9>",
 },


Second, user - you will use this info for proper attribution, namely:


  • user.name : Author name


  • user.links.html : Link to their profile, you must use. Make sure to append utm_source=your_app_name&utm_medium=referral to it, per guidelines.


Third, alt_description , make sure to add it to your final IMG tags for accessibility and SEO.


This piece of code is really everything you need to get going. With one caveat.

Watching for Rate Limit

When you’re in initial demo mode, you will only have 50 requests per hour. When trying to fetch more images, hitting rate limit is a given. What to do?


Simply wait for a bit if the function above throws ConnectionError. I wait for around 70 seconds.


Also mind that if no results are found, you will receive None. In this case, I am using a simplified query (country instead of city).


Once the website is online, you can request higher quota in the dashboard.

Summary

We've covered how to use Python and the Unsplash API to automatically fetch photos for your apps and websites.


I hope you’ll build something cool with it. Send your projects my way in the comments or on Twitter.


Subscribe to my profile by filling in your email address on the left, and be up-to-date with my articles! I will soon be releasing a crazy interesting project that uses this solution!

Don't forget to follow me on Twitter @horosin, and subscribe to my blog’s newsletter for more tips and insights!