hackbrightacademy / cloudinary-demo

Cloudinary and Media Uploads Primer

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cloudinary and Media Uploads Primer

Learn how to use the Cloudinary API (Python SDK) with a Flask app in order to save user-uploaded media.

This resource was originally created by @poemusica

Who is this guide for?

The guide, instructions, and demos are designed with new developers in mind, specifically students at the coding bootcamp Hackbright Academy.

Why include media uploads in a project?

Images and videos make your web pages more exciting. Does your web app have user accounts? Why not let your users upload a profile photo!? Does your web app have log entries? Make entries more interesting by allowing users to attach a photo or video.

Why image hosting?

We don’t want to save entire image or video files in our databases. Images and videos are large! Our web servers (currently, our personal computers) would run out of storage if we saved all that data in our databases or on our servers. Instead, we can use a third-party service that will store, manage, optimize and deliver the media for us on their servers. Then, we can simply save the image or video URLs as strings in our database. Strings take up way less storage space than entire media files.

There are many media-hosting and file management services to choose from, but Cloudinary has a free tier and is easy to use.

Discussion of Approaches

The demo code includes two approaches to handling user-uploaded media.

Simple Media Upload

This approach uses the browser's default form action on submit.

The browser makes a request to the server (Flask backend), providing the data in the form. Then the server makes a request to the Cloudinary API, passing along the form data. After receiving the response from Cloudinary, the server sends a response to the browser (frontend) and the browser displays the response after reloading the page.

The tutorial below explains this approach in more detail.

Asynchronous Media Upload

This approach uses the JavaScript Fetch API to process the form submission asynchronously.

On the frontend (browser), JavaScript prevents the default form action and instead sends the form data to the server (Flask backend) using a fetch request. Just as before, the server makes a request to the Cloudinary API, passing along the form data. After receiving the response from Cloudinary, the server sends a response to the browser (frontend), but this time the browser uses JavaScript to display the response and the page does not reload.

While this approach is not covered in this primer, the demo code is available in this repository.

Other Cloudinary Approaches

In both demos, the Flask server uses the Cloudinary Python SDK and acts as an intermediary between the browser and the Cloudinary API. (This is a useful technique in cases where the browser is not allowed to make requests to an API directly due to CORS restrictions.)

Cloudinary's REST API can be called directly via JavaScript, however it requires generating authentication signatures, which adds some complexity.

Alternatively, Cloudinary offers a JavaScript SDK, which allows the browser to make requests to the Cloudinary API directly (via JavaScript), but this approach requires the assistance of frontend tooling and frameworks.

Lastly, Cloudinary provides a premade upload widget, which can be configured with JavaScript, to assist with media uploads.

Walkthough Guide of the Simple Media Upload Approach

Part 1: Make a FREE Cloudinary account

Step 1: Go to cloudinary.com and create a free account.

Since we're primarily using Cloudinary to save and display images, select Programmable Media from the Product dropdown menu.

Step 2: Create your Cloud Name.

During the signup process, you will also make your Cloud Name. Your Cloud Name will be part of the URL that Cloudinary creates for your image uploads.

Part 2: Get Your API Credentials

Step 1: Locate your credentials.

On your Cloudinary Dashboard, locate your:

  • Cloud Name
  • API Key
  • API Secret

You need these three pieces of information to make requests to the Cloudinary API.

⚠️ WARNING: NEVER COMMIT your API Key or API Secret to git/Github.

Step 2: Keep your credentials secret.

Add secrets.sh to your .gitignore file. Put your API Key and API Secret in your secrets.sh file in your project directory.

.gitignore and secrets.sh screenshot

Step 3: Load your secrets

In the terminal, load your API credentials as shell environment variables by running the command:

source secrets.sh

(Note: Similar to the way you must activate your virtual environment whenever you start working on your project in a new terminal, you must also re-load your secrets by re-running the command above.)

Part 3: Make a Form

Below is a snippet of an HTML page that contains a simple form for uploading an image.

form screenshot

To upload an image, your form must include:

  • An input tag with the attribute type=”file” and a name attribute.
  • The action attribute specifying a route that will handle the request from this form. Additionally, the method used should be “post” because we plan to create data on the backend when this form is submitted.
  • The enctype attribute specifying that the data will be encoded as “multipart/form-data”.

Part 4: Install and Import

Step 1: Install the Cloudinary SDK for Python.

⚠️ WARNING: Make sure you have activated your virtual environment!

Cloudinary has a Python library that makes it easier to use the Cloudinary API.

In the terminal, run the command:

pip3 install cloudinary

Step 2: Update your project requirements

Now that you’ve installed cloudinary, you’ll want to make sure it’s included in your requirements.txt file.

In the terminal, run the command:

pip3 freeze > requirements.txt

Step 3: Import libraries and access secrets

In your server.py file,

  • import the os module from the Python standard library.
  • import cloudinary.uploader from the cloudinary library.
  • use the os module to access your API credentials (shell environment variables).
  • Replace “YOUR-CLOUD-NAME-HERE” with your actual Cloud Name as a string.

server screenshot

Part 5: Make the API request

Step 1: Make a route that handles the form from Part 3.

In your server.py, you need two routes:

  • One to show the form from Part 3
  • One to process the form from Part 3

You already know how to create routes that render HTML, so these instructions will not include how to create the first route, which simply shows the form.

For the second route (the one that processes the form), start by creating a route that accepts POST requests.

Step 2: Get the form data

Your route needs to access the uploaded file and save it to a variable. Use the Flask request object to get this information.

my_file = request.files['my-file']

💡 Debugging Tip: Make sure the key you are using to access the file matches the name attribute you used in Part 3.

Step 3: Make the Cloudinary API request

Next, we need to save the uploaded file to Cloudinary by making an API request.

Make sure you store the result of the request in a variable! It contains important information.

result = cloudinary.uploader.upload(my_file,
         api_key=CLOUDINARY_KEY,
         api_secret=CLOUDINARY_SECRET,
         cloud_name=CLOUD_NAME)

Step 4: Save the generated URL to your database

The result variable is a dictionary of information about the file and the API request. When Cloudinary saved the image file to its servers, it created a URL for the file. You can use this URL to access the image later.

img_url = result['secure_url']

Save this URL to your database so that you can display the image back to the user later.

For example, if you have a user record from a users table with the column/field profile_url, you could use the user record in your jinja template to display the user’s profile photo like this:

<img src="{{ user.profile_url }}">

That’s it! Now you know how to use the Cloudinary API to save images that users upload to your web app.

Cloudinary Academy

To learn more about Cloudinary (for free!) head to the Cloudinary Academy at training.cloudinary.com.

For a Python Specific learning resource within the Cloudinary Academy, check out this 90 minute Intro to Cloudinary for Python developers course.

Check out the associated repository for the Python course (and all of their developer courses!). Also feel free to pattern match what you see in the repository.

Cloudinary Fun Facts

  • With Cloudinary, almost everything you can do with image assets, you can also do with video assets.
  • Aside from image and video assets, Cloudinary can also handle any file type, and treats it as a "raw" file. i.e. PDFs, audio files. With raw files, you can store and deliver with Cloudinary, but you are not able to perform the same optimizations.
  • If using Cloudinary, there are two really wonderful features that you may not initially see in the docs. You can very easily adjust a file's format and quality with f_auto, q_auto. Check out the attached docs to learn more about these awesome Cloudinary features that go together like peanut butter and jelly.
  • Cloudinary offers a generous amount of free usage, so there's a good chance you'll never need to pay to use this service if only using it for your bootcamp final project.

About

Cloudinary and Media Uploads Primer


Languages

Language:HTML 74.8%Language:Python 25.2%