Python: how to use the Unsplash API

In this article we will see how to download and resize an image using the Unsplash API with Python.

For our purpose, three additional modules are needed:

  1. requests to make HTTP requests.
  2. python-dotenv to read the Unsplash API key which we will store in a .env file .
  3. Pillow for image manipulation.

After setting up the virtual environment and installing the required modules, we save the Unsplash API key in a .env file.

ACCESS_KEY=chiave_API

So we call the load_dotenv() function at the beginning of our code to load the newly created file into memory that will populate our environment variables.

import sys
import os
import requests
from dotenv import load_dotenv
from PIL import Image

load_dotenv()

Now we can create a function for remote image download.

def download_image(url=None, name='image.jpg'):
    if url is None:
        return None
    try:
        res = requests.get(url, allow_redirects=True)
        data = res.content
        with open(name, 'wb') as img:
            img.write(data)
        return True
    except requests.exceptions.RequestException:
        return False

The content of the response, the content property, contains the binary data of the image that we are going to save locally with the specified name.

Now with the Pillow module we need to create a function that performs the resizing of the image.

def resize_image(img=None, dimensions=(2000, 850)):
    if img is None:
        return False
    with Image.open(img) as im:
        im.resize(dimensions)
        im.save(f'./resized/{img}')
    os.unlink(img)
    return True

The image to be resized is the previously saved image. The dimensions tuple specifies the height and width that will be used by the resize() method. Then the image is saved in a new destination and the downloaded image is deleted.

At this point we just have to define a function which, given a search term as an argument, makes a request to the Unsplash API and returns the URL of the image contained in the first search result.

def unsplash_api_search(query=None):
    if query is None:
        return None
    api_url = 'https://api.unsplash.com/search/photos'
    params = {'query': query, 'client_id': os.getenv('ACCESS_KEY')}

    try:
        res = requests.get(api_url, params=params, allow_redirects=True)
        data = res.json()
        if not data.get('total'):
            return None
        return data['results'][0]['urls']['raw']

    except requests.exceptions.RequestException:
        return None

We can use the functions we have defined directly from the shell with a minimum of user interaction in choosing the search term.

def main():
    search_query = input('Query: ')
    if not search_query:
        print('Invalid query.')
        sys.exit(1)
    results_url = unsplash_api_search(search_query)
    if results_url is None:
        print('Request error.')
        sys.exit(1)
    print('Got a result from the API.')
    img_name = f'{search_query.strip()}.jpg'
    print('Downloading image...')
    is_image_downloaded = download_image(results_url, img_name)
    if not is_image_downloaded:
        print('Download error.')
        sys.exit(1)
    print(f'Downloaded {img_name}')
    resized_img = resize_image(img_name)
    if not resized_img:
        print('Resize error')
        os.unlink(img_name)
        sys.exit(1)
    print(f'Resized image in ./resized/{img_name}')


if __name__ == '__main__':
    main()
Back to top