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):
os.makedirs(UPLOAD_DIRECTORY)
api = Flask(__name__)
@api.route("/files")
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):
files.append(filename)
return jsonify(files)
@api.route("/files/<path:path>")
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:
fp.write(request.data)
# Return 201 CREATED
return "", 201
if __name__ == "__main__":
api.run(debug=True, port=8000)
Deployment¶
Assuming that you store this file as myapi.py
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
Usage¶
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 = 'https://cube-64e0d7d8-1a3d-4fec-82da-fa7afea9138e.api.my.faculty.ai'
API_KEY = 'i0cgsdYL3hpeOGkoGmA2TxzJ8LbbU1HpbkZo8B3kFG2bRKjx3V'
headers = {'UserAPI-Key': API_KEY}
response = requests.get('{}/files'.format(API_URL), headers=headers)
response.json()
>>> ['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
)
response.status_code
>>> 201
And download them with requests.get()
:
response = requests.get(
'{}/files/newdata.csv'.format(API_URL), headers=headers
)
response.text
>>> '1,Joe Bloggs,27\n'