Cloudinary API in Flask

I have been using Cloudinary to host images on my personal website for about a year. Upload image, resize, crop, etc., then grab the URL to put in my anchor tag. Its pretty easy, but fairly manual. Also, the process involves no Python. Where’s the fun in that? I decided to look into what could be done with the Cloudinary API.

There’s plenty of Django specific documentation that I can work off even though I am using Flask. My needs are fairly basic at this point: Alter my images, generate URLs, and dynamically insert them. First, I activate my virtual environment and install the Cloudinary package.

pip install cloudinary

Great. Cloudinary is now installed. I use a file called content.py that I pull content from for my site. I will import the package there. I used “import … as …” because cloudinary I kept misspelling cloudinary.

import cloudinary as Cloud

Now that the package is available, I have to configure it with my API credentials. I don’t have a dedicated settings file (I think Django has one?) so I have to update the config myself. I can use the cloudinary object’s config method to update the dict with my credentials. I have stored my actual credentials in a .env file.

Cloud.config.update = ({
'cloud_name':os.environ.get('CLOUDINARY_CLOUD_NAME'),
'api_key': os.environ.get('CLOUDINARY_API_KEY'),
'api_secret': os.environ.get('CLOUDINARY_API_SECRET')
})

I am all set up now. So what can I do with the API? What I want a URL for this image to use as an href:

Medium scales it a little bit, but the final image needs to be resized. I might check out some color correction and Cloudinary’s instagram-esque filters too. First, I have to upload the photo to Cloudinary. Then I can create a image object using the name I gave my photo:

pipeshelf = Cloud.CloudinaryImage("pipeshelf.jpg")
>>> type(pipeshelf)
<class 'cloudinary.CloudinaryImage'>

Now that I have my object, I can start manipulating the image through the API. I can grab the URL for the unaltered image like so:

>>> pipeshelf.url
'http://res.cloudinary.com/hohwgqd6t/image/upload/pipeshelf.jpg'

Lets scale it. I can add parameters by updating the object’s url_options dictionary. This will generate a new image and give me a new URL with alterations applied without changing the original.

pipeshelf.url_options.update({"width":600})

Now when I call the url, my scaling is in place:

>>> pipeshelf.url
'http://res.cloudinary.com/hohwgqd6t/image/upload/w_600/pipeshelf.jpg'

Lets put a filter on it in now:

pipeshelf.url_options.update({"effect":"art:hokusai"})
>>> pipeshelf.url
'http://res.cloudinary.com/hohwgqd6t/image/upload/e_art:hokusai,w_600/pipeshelf.jpg'

I now have a scaled, filtered image and didn’t have to open Photoshop. On my site I keep a dictionary of the content. Within that is a to-do list of projects that may require images. I manipulate the images outside of the dictionary and store the URLs and text as a list of tuples. Kind of like this:

'2017': {
'done': [
('Pipe Shelf', pipeshelf.url)
]
}

Then in my Jinja template I can loop through the ‘done’ list and if the item is a tuple (aka has a url that I need) I place it. Otherwise, just place the text:

{% for item in CONTENT_DICT['todo']['2017']['done'] %}
{% if item|length is equalto 2 %}
<li class='done'><a href="{{ item[1] }}" target="_blank">{{ item[0] }}</a></li>
{% else %}
<li class='done'>{{ item }}</li>
{% endif %}
{% endfor %}

That is it! Check out my To-Do page to see this in action.