Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

393
Views
¿La mejor manera de crear un enlace de descarga para un archivo en Flask?

En mi proyecto, cuando un usuario hace clic en un enlace, una solicitud de AJAX envía la información necesaria para crear un CSV. El CSV tarda mucho en generarse, por lo que quiero poder incluir un enlace de descarga para el CSV generado en la respuesta de AJAX. es posible?

La mayoría de las respuestas que he visto devuelven el CSV de la siguiente manera:

 return Response( csv, mimetype="text/csv", headers={"Content-disposition": "attachment; filename=myplot.csv"})

Sin embargo, no creo que esto sea compatible con la respuesta AJAX que estoy enviando con:

 return render_json(200, {'data': params})

Idealmente, me gustaría poder enviar el enlace de descarga en el dictado de parámetros. Pero tampoco estoy seguro de si esto es seguro. ¿Cómo se suele resolver este problema?

about 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Creo que una solución puede ser la biblioteca de futures ( pip install futures ). El primer punto final puede poner en cola la tarea y luego devolver el nombre del archivo, y luego se puede usar otro punto final para recuperar el archivo. También gzip porque podría ser una buena idea si envías archivos más grandes. Creo que las soluciones más robustas usan Celery o Rabbit MQ o algo por el estilo. Sin embargo, esta es una solución simple que debería lograr lo que está pidiendo.

 from flask import Flask, jsonify, Response from uuid import uuid4 from concurrent.futures import ThreadPoolExecutor import time import os import gzip app = Flask(__name__) # Global variables used by the thread executor, and the thread executor itself NUM_THREADS = 5 EXECUTOR = ThreadPoolExecutor(NUM_THREADS) OUTPUT_DIR = os.path.dirname(os.path.abspath(__file__)) # this is your long running processing function # takes in your arguments from the /queue-task endpoint def a_long_running_task(*args): time_to_wait, output_file_name = int(args[0][0]), args[0][1] output_string = 'sleeping for {0} seconds. File: {1}'.format(time_to_wait, output_file_name) print(output_string) time.sleep(time_to_wait) filename = os.path.join(OUTPUT_DIR, output_file_name) # here we are writing to a gzipped file to save space and decrease size of file to be sent on network with gzip.open(filename, 'wb') as f: f.write(output_string) print('finished writing {0} after {1} seconds'.format(output_file_name, time_to_wait)) # This is a route that starts the task and then gives them the file name for reference @app.route('/queue-task/<wait>') def queue_task(wait): output_file_name = str(uuid4()) + '.csv' EXECUTOR.submit(a_long_running_task, [wait, output_file_name]) return jsonify({'filename': output_file_name}) # this takes the file name and returns if exists, otherwise notifies it is not yet done @app.route('/getfile/<name>') def get_output_file(name): file_name = os.path.join(OUTPUT_DIR, name) if not os.path.isfile(file_name): return jsonify({"message": "still processing"}) # read without gzip.open to keep it compressed with open(file_name, 'rb') as f: resp = Response(f.read()) # set headers to tell encoding and to send as an attachment resp.headers["Content-Encoding"] = 'gzip' resp.headers["Content-Disposition"] = "attachment; filename={0}".format(name) resp.headers["Content-type"] = "text/csv" return resp if __name__ == '__main__': app.run()
about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!