More complex APIs: Upload and Download Files with Flask

This example demonstrates uploading and downloading files to and from a Flask API.

Python Source Code

import os

from flask import Flask, request, abort, jsonify, send_from_directory

UPLOAD_DIRECTORY = "/project/api_uploaded_files"

if not os.path.exists(UPLOAD_DIRECTORY):

api = Flask(__name__)

def list_files():
    """Endpoint to list files on the server."""
    files = []
    for filename in os.listdir(UPLOAD_DIRECTORY):
        path = os.path.join(UPLOAD_DIRECTORY, filename)
        if os.path.isfile(path):
    return jsonify(files)

def get_file(path):
    """Download a file."""
    return send_from_directory(UPLOAD_DIRECTORY, path, as_attachment=True)

@api.route("/files/<filename>", methods=["POST"])
def post_file(filename):
    """Upload a file."""

    if "/" in filename:
        # Return 400 BAD REQUEST
        abort(400, "no subdirectories allowed")

    with open(os.path.join(UPLOAD_DIRECTORY, filename), "wb") as fp:

    # Return 201 CREATED
    return "", 201

if __name__ == "__main__":, port=8000)


Assuming that you store this file as to /project/myapidirectory in your project workspace, create an API in Faculty with the following settings:

  • Type: Flask

  • Working Directory: /project/myapidirectory

  • Python module: myapi

  • Python object: api


Once you’ve spun up a development server for your API in Faculty, get the URL and API Key for the server for the interface. Then, using Python requests (or any other suitable HTTP client), you can list the files on the server with:

import requests

API_URL = ''
API_KEY = 'i0cgsdYL3hpeOGkoGmA2TxzJ8LbbU1HpbkZo8B3kFG2bRKjx3V'

headers = {'UserAPI-Key': API_KEY}

response = requests.get('{}/files'.format(API_URL), headers=headers)

>>> ['file1.txt', 'data.csv']

Upload new files with

with open('newdata.csv') as fp:
    content =

response =
    '{}/files/newdata.csv'.format(API_URL), headers=headers, data=content

>>> 201

And download them with requests.get():

response = requests.get(
    '{}/files/newdata.csv'.format(API_URL), headers=headers

>>> '1,Joe Bloggs,27\n'