I have built a python flask app that I'm hosting on the Digital Ocean app as a web app using gunicorn. The app basically does the following:
- Makes a call to an external API based on inputs submitted on an html form, applies python logic to the response json.
- Uses that response json above to make several additional API calls.
- Applies logic to collect those outputs and delivers them as an html table to the user.
The app seems to work fine during testing, but the external API limits the amount of calls that can be made from a specific IP address. I do not want to circumvent their limit, for instance I don't want a single user to be able to exceed the limit, but right now I believe all of the API calls are being executed server-side so they appear to come from the server's single IP address, rather than many different client IP addresses.
Am I correct that, based on the way I've set things up below, these external API calls will appear to come from the server IP address rather than the client's IP? Is it possible to set up the app so it will make API calls on the client side, so that the calls appear to come from the client's IP address, and deliver the response payload to the server side for processing? Is it inadvisable to go back and forth in this way?
Toy example:
form.html:
<form action="/data" method = "POST">
<p>Explanation text</p>
<p>Input 1: <input type = "text" name = "input_1" /></p>
<p>Input 2: <input type = "text" name = "input_2" /></p>
<p>Input 3: <input type = "text" name = "input_3" /></p>
<p><input type = "submit" value = "Submit" /></p>
</form>
app.py:
from flask import Flask, render_template, request
import pandas as pd
import requests
from modules.additional_function import some_function
app = Flask(__name__)
@app.route('/')
def form():
return render_template('form.html')
@app.route('/data/', methods = ['POST', 'GET'])
def data():
if request.method == 'GET':
return f"The URL /data is accessed directly. Try going to '/form' to submit form"
if request.method == 'POST':
# read in form data
form_data = request.form
# make first api call
first_api_response = requests.get('external_api.com/something?input1={input1}'.format(input1=form_data['input_1']))
# build subsequent api calls based on first api response
base_urls = [x['foo']['bar']+form_data['input_2'] for x in first_api_response['boo']]
# some function that calls all apis from base urls, adds additional filtering
# and stitches together output into pandas table
result_table = some_function(base_urls, form_data['input_3'])
return render_template('simple.html',tables=result_table.to_html(classes='data'))