Example: 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 directories allowed')

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

    # Return 201 CREATED
    return '', 201

if __name__ == '__main__':
    api.run(debug=True, port=8000)


Assuming that you store this file as myapi.py to /project/myapidirectory in your project workspace, to deploy the API create the following script at /project/myapidirectory/run.sh:

exec python -u app.py

Then, create the API in SherlockML with the settings:

  • Working Directory: /project/myapidirectory
  • Script: run.sh


Once you’ve spun up a development server for your API in SherlockML, 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 = 'https://cube-64e0d7d8-1a3d-4fec-82da-fa7afea9138e.api.sherlockml.io'
API_KEY = 'i0cgsdYL3hpeOGkoGmA2TxzJ8LbbU1HpbkZo8B3kFG2bRKjx3V'

headers = {'SherlockML-UserAPI-Key': API_KEY}

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

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

Upload new files with requests.post():

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

response = requests.post(
    '{}/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'