DEV Community

Cover image for Automating Contentful Photo Publishing with Python
Max Mitchell
Max Mitchell

Posted on

Automating Contentful Photo Publishing with Python

Hi, I'm Max Mitchell, a senior at UIUC studying Computer Engineering. I recently created my personal website with the images hosted on Contentful, but found it time consuming to upload the images and create new photo collections. To fix this, I created a python script to upload a folder of images and put them in a Contentful photo collection!

In this tutorial I'll be teaching you how to integrate Contentful with Python in order to upload a folder of images from your command line.

Setting Up Contentful

To start, I'll be assuming that you already have an account and space with Contentful. If you need help with that, this tutorial from Contentful should help get you started.

Once you have an account and space created, you need a content model that resembles a photo album. In my example, I call it a "Photo Collection" but the important part is having a Media field with many files. You can look at all the fields I have below:

Alt Text

Coding Time

First, install the Contentful Management API with sudo pip install contentful_management.

Next, you need two keys to use the API: your Contentful Management Token and Space ID.

  • You can create a Management Token by going under Settings > API keys > Content management tokens > Generate personal token.
  • Your Space ID can be found under Settings > General settings.

Let's add these constants and import the library, along with os to make dealing with the filepath to the images easier:

import contentful_management
import os
CONTENTFUL_MANAGEMENT_TOKEN = "YOUR_TOKEN"
CONTENTFUL_SPACE_ID = "YOUR_SPACE_ID"

Now we need to authenticate Contentful (note that this assumes we are using the master environment, but can be switched with what you want):

client = contentful_management.Client(CONTENTFUL_MANAGEMENT_TOKEN)
portfolio_space = client.spaces().find(CONTENTFUL_SPACE_ID)
master_env = portfolio_space.environments().find('master')

Next, we need a folder of images to upload. For the sake of simplicity, I'll be hard coding the path to the folder that contains the images I want to upload, but you can look at my final code to see how I handled passing the folder names into the script. This also assumes you're on windows.

directory = os.fsencode("D:/edited pics/testFolder")

A quick note about how Contentful handles media uploads:

  1. You create an upload.
  2. You pass a link to this upload into the attributes for a new asset.
  3. You process the asset, which is an asynchronous task on Contentful's back-end.
  4. Once it's processed, it can be added to a photo collection and published.
photos = []
for file in os.listdir(directory):
   if filename.endswith(".jpg"):
      filename = os.fsdecode(file)
      contentful_upload = portfolio_space.uploads().create(os.fsdecode(filepath))
      asset_attributes = {
         'fields': {
            'title': {
               "en-US": filename
            },
            'file': {
               'en-US': {
                  'fileName': filename,
                  'contentType': 'image/jpeg',
                  'uploadFrom': contentful_upload.to_link().to_json()
               }
            }
         }
      }
      contentful_asset = master_env.assets().create(None, asset_attributes) # None lets API generate ID
      contentful_asset = contentful_asset.process()  # Processing is an async task, so I need to wait to publish it
      photos.append(contentful_asset) # Store an array of assets so we can later publish them all (once they process)

Nice! This should upload your images, but we still have the inconvenience of having to open up Contentful and add them all to a new photo collection. Let's automate that!

photoCollection_attributes = {
   'content_type_id': 'photoCollection',
   'fields': {
      'photos': {
         'en-US': [item.to_link().to_json() for item in photos]
      },
   }
}
new_photoCollection = master_env.entries().create(None, photoCollection_attributes) # None lets API auto generate unique ID

The final step is to publish all the images we uploaded! This is optional, but I found it very tedious to individually publish them on the Contentful website, so instead I publish each image but wait to manually publish the photo collection myself.

for photo in photos:
   master_env.assets().find(photo.id).publish()

Final Thoughts

I wanted this tutorial to be pretty bare bones and show that it is possible to easily integrate Python with Contentful. This also means that it lacks usability. That being said, an improved version of this script (with support for uploading to Google Drive) that I actually use regularly to upload my own images is located in the below GitHub Repo:

GitHub logo maxemitchell / photo_manager

A Python script that uploads a folder of images to both Contentful and Google Drive.

If you're interested, I also made a YouTube video covering my thought process and some of the issues I ran into creating my script. Feel free to check it out below!

If you have any issues or questions about this, please feel free to reach out!

Top comments (0)