Simple Flask Application to Test API Endpoints
This article is a short instruction on building small Flask application to view a post request.
In the same application we will have one route that is an endpoint and one route that is a website to view the POST request.
Here is the github repo if you just want to clone it quickly and run it. It’s very simple.
I have seen other tutorials on building APIs that get more sophisticated. There may be a good reason for this but I haven’t found one yet. I would be interested in understanding setbacks even convention.
Environment
After creating the pip env
python -m venv endpointTester
I only had to install two packages
pip install flask
pip install python-dotenv
You can get away without the dotenv but I am becoming a fan of using the .flaskenv file. This allows me to run the application from the terminal like so
Flask run --port=5001
Setup Python Script (run.py)
To setup the script I have my flask imports. Os and json are used because we will save the posts requests in a json file. The webpage will then read the .json files. Every new post requests overwrites the previous one.
from flask import Flask, render_template, request, jsonify, make_response, current_app
import os
import json
app = Flask(__name__)
app.secret_key = 'Necessary_to_have'
app.debug = True
app.config['DESTINATION_PASSWORD']='bulljive'
# code goes here
if __name__ == '__main__':
app.run()
The password is not necessary, but this has been my method of access restriction/security. In a future app I think I’ll try to use auth, but I would be interested in hearing about other’s method of having some sort of access restriction.
Setup POST route
In this route we are just receiving a post request sent to http://localhost:5001/post. POST requests are checked for the password and then the headers and data included are saved in .json files. Each new POST request overwrites the previous one.
@app.route('/post', methods = ["POST"])
def receive_api_calls():
print("- In post endpoint -")
request_headers = request.headers
if request_headers.get('password') == current_app.config.get('DESTINATION_PASSWORD'):
req_head_dict = {i[0]:i[1] for i in request_headers}
f = open("headers.json", "w")
json.dump(req_head_dict, f)
f.close
request_data = request.get_json()
f = open("data.json", "w")
json.dump(request_data, f)
f.close
return jsonify({"message": "successfully received call!! "})
else:
return make_response('Could not verify',401)
Setup Webpage route
In the webpage route we are just reading from the .json files to post to the website.
@app.route('/', methods=["GET"])
def get_stuff():
print('- In post_view endpoint -')
f = open("headers.json")
headers_dict = json.load(f)
f.close()
f = open("data.json")
data_dict = json.load(f)
f.close()
return render_template("home.html", headers_dict=headers_dict, data_dict=data_dict)
The HTML and CSS are in the github repo. If you want to use it you can just copy the templates and static folders into your project.
Send the post request
I have gotten in the habit of calling the data dictionary payload because of someone else’s tutorial. The payload can have many key:value pairs.
import requests
import json
headers = {'password':'bulljive','Content-Type': 'application/json'}
payload = {'sent_data':'Sending something cool EVEN more Cool to /post!'}
response = requests.post("http://localhost:5001/post", headers=headers, data=str(json.dumps(payload)))