api.video

Features

Developers

Use Flask with Dropzone.js and api.video Python Client to Upload Many Videos of Any Size

June 28, 2021 - Erikka Innes in Video upload, video create, Python

If you'd rather watch this tutorial as a video:

This tutorial is a tweak on the content provided in Use Flask with Dropzone.js to Upload Videos Under 128MB (No Client). In this version of the tutorial I'm using our new Python client. With api.video's Python client, you can upload videos of any size because chunked uploads are handled for you.

Flask is a WSGI web application framework. It makes getting started with building a web application quick and easy. It's based on the Werkzeug WSGI toolkit and the Jinja2 template engine. It's very popular for creating backends for webpages, and that's what I'll be using it for today. If you want to read more about what Flask is, check out What is Flask Python.

Dropzone.js is an opensource JavaScript library that lets you create drag n' drop file uploads with image previews (when available). It doesn't have dependencies on other libraries, and it does a lot of work for you so you can focus on styling and configuration. I'll use a very simple format in this tutorial, but you will be able to style it however you want.

Prerequisites

For this project you'll need:

Set up

To get started, you'll need to do these things:

  1. Grab the code from GitHub - flask_and_dropzone

  2. Install the api.video client. That's going to be pip install apivideo

  3. In my version of the project, Dropzone.js is attached using CDNs. You can also reference these using the static folder and placing dropzone.js and dropzone.css there. Just change the references in index.html if you want to do this instead.

Let's roll!

What's in index.HTML?

The HTML file for this project is exactly the same as for Use Flask with Dropzone.js to Upload Videos Under 128MB (no client).

EXCEPT FOR ONE THING. I added a very long timeout - it lasts about 45 minutes. If you don't plan to upload giant video files, you don't need to include this (timeout: 2700000). By default, Dropzone will wait 30 seconds, then timeout. Everything is in milliseconds, so normally this would be 30000. Even though Dropzone times out, your video file will still continue to upload. But the visual will show a file with a graphic that is X'd out. This might lead you to restart, losing the upload, or assume it's not working. So if you plan to use this sample for giant files, I recommend leaving the timeout.

What's in app.py?

Here's what's set up for the backend:

# Imports 
import os
import apivideo
from apivideo.apis import VideosApi
from flask import Flask, render_template, request, redirect, url_for, abort

app = Flask(__name__)

# You can do this for extra security. MAX_CONTENT_LENGTH lets you set how big files can be. 
# UPLOAD_EXTENSIONS lets you limit what types of files can be uploaded. 
app.config['MAX_CONTENT_LENGTH'] = 5000 * 5000 * 100000
app.config['UPLOAD_EXTENSIONS'] = ['.mov', '.mp4', '.m4v', '.jpm', '.jp2', '.3gp', '.3g2', '.mkv', '.mpg', '.ogv',
                                   '.webm', '.wmv']
app.config['UPLOAD_PATH'] = 'uploads'

# If a file is too big, you'll get this. 
@app.errorhandler(413)
def too_large(e):
    return "File is too large", 413

# State what template you want to show
@app.route('/')
def index():
    return render_template('./index.html')

@app.route('/', methods=['POST'])
def upload_file():
  
# Retrieve files and form data, they are in two separate parts of the request info from Flask. 
    my_files = request.files
    api_key = request.form['API Key']

# The files are in an immutable multi-dictionary, so loop through to grab them all. 
    for item in my_files:
        uploaded_file = my_files.get(item)

# Check if the file name was left blank or isn't in the extensions list. 
        if uploaded_file.filename != '':
            file_ext = os.path.splitext(uploaded_file.filename)[1]
        if file_ext not in app.config['UPLOAD_EXTENSIONS']:
            abort(400)

# Start up the client and connect 
        client = apivideo.AuthenticatedApiClient(api_key)
        client.connect()

# Set up to use the videos endpoint
        videos_api = VideosApi(client)

# Add the file name from the FileStorage object from Flask
        video_create_payload = {
            "title": uploaded_file.filename,
        }

# Create a video container to upload your video into and retrieve the video ID for the container
        response = videos_api.create(video_create_payload)
        video_id = response["video_id"]

# Upload your file as a stream. NOTE! IMPORTANT! If you are uploading a big file, this will take 
# awhile if it's over 128MB. 
        video_response = videos_api.upload(video_id, uploaded_file.stream)
    return redirect(url_for('index'))

This sample is based off of Miguel Grinberg's tutorial Handling File Uploads With Flask. You will recognize some of the security items in the code. MAX_CONTENT_LENGTH is a way you can limit how big the files people upload are. Because this sample is supposed to be for files of any size, the content length is massive. UPLOAD_EXTENSIONS limits what types of files people can upload.

NOTE: While this is set up to handle big files, please be aware that if you drop four or five giant files at once it will take awhile. If you want to be able to do that, you might have to experiment with the timeout setting.

Next there's an error handler to tell you if a file upload is too big (not likely with the sample settings).

The main route and definition upload_file() does a few things. First it gets all the files you put in the Dropzone. Then it retrieves the api key. The files are stored as FileStorage objects inside an immutable multidictionary. An easy way to process each file is with a loop, so you can loop through for each one (or just the one) and do a couple of checks. Check that the filename isn't empty (because you can't send it like that). Then check if the file extension is allowed.

Next you'll set up the api.video client so you can use the videos endpoint. Then you send your file. The chunked upload is handled by the client without showing progress information. Give big files some time to upload.

If you want a progress bar, there are a lot of easy ways to display progress without the client, but then you have to set up chunked uploads yourself.

Resources

Erikka Innes

Developer Evangelist

Get started now

Connect your users with videos