I'm making an app that lets the user upload a csv of data, and generates a plot of that data, saves the plot to a pdf, then returns the plot as a download to the user. The crux of the issue is that in reality, this plot takes 1 - 2 minutes to generate.
The App
The route is as follows:
@app.route("/gen_pdf", methods=["GET","POST"])
def transform2():
f = request.files['input_file1']
if not f:
return "Main input file not found!"
# Read uploaded data as a Stream into a dataframe.
stream = io.StringIO(f.stream.read().decode("UTF8"), newline=None)
csv_input = csv.reader(stream)
contents = []
for row in csv_input:
contents.append(float(row[0]))
#Artificially increase time required to generate plot
time.sleep(60)
plt.hist(contents, bins=100)
fn = "test_histogram.pdf"
plt.savefig(app.config["CLIENT_DIR"]+"/"+fn)
return send_from_directory(app.config["CLIENT_DIR"], filename=fn, as_attachment=True)
gen_pdf.html
, for completeness (this can just be embedded within some html boilerplate)
{% extends "layout.html" %}
{% block content %}
<h1>Test</h1>
<hr/>
<form action="/transform2" method="post" enctype="multipart/form-data">
<h3>Upload input file (csv)</h3>
<input type="file" name="input_file1" id="input_file1">
<hr/>
<input type="submit" value="Create and Serve PDF" name="submit">
</form>
{% endblock content %}
The data to be uploaded are just a single csv file with a single column of randomly generated numbers.
Nginx/Uwsgi Setup
These were set up on a Ubuntu 18.04 VM, following the setup here.
The Error
As mentioned, this leads to a gateway 504 error. However, if I reduce the delay in the time.sleep()
command to, say, 10s, everything works just fine, so the error somehow stems from something timing out before the pdf plot is completed.
When checking journalctl --unit=<my_project>.service -n 100 --no-pager
, I get:
SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request /transform2 (ip <ip_address>) !!!
uwsgi_response_writev_headers_and_body_do(): Broken pipe [core/writer.c line 306] during POST /transform2 (<ip_address>)
OSError: write error
[pid: 27863|app: 0|req: 156/335] <ip_address> () {50 vars in 1083 bytes} [Mon Jul 27 02:18:38 2020] POST /transform2 => generated 0 bytes in 60835 msecs (HTTP
I'm aware of the explanation of the SIGPIPE error here, but that explanation doesn't seem relevant (it's an internal process, not between visitors).
I've also tried the solutions here and here because they look like similar errors, to no avail.