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

377
Views
Descargar un archivo desde un s3 Bucket a la computadora USUARIOS

Meta

Descargue el archivo de s3 Bucket a la computadora de los usuarios.

Contexto

Estoy trabajando en una API Python/Flask para una aplicación React. Cuando el usuario hace clic en el botón Descargar en el front-end, quiero descargar el archivo apropiado en su máquina.

lo que he probado

import boto3 s3 = boto3.resource('s3') s3.Bucket('mybucket').download_file('hello.txt', '/tmp/hello.txt')

Actualmente estoy usando un código que encuentra la ruta de la carpeta de descargas y luego conecto esa ruta en download_file() como el segundo parámetro, junto con el archivo en el depósito que están tratando de descargar.

Esto funcionó localmente y las pruebas funcionaron bien, pero me encontré con un problema una vez que se implementó. El código encontrará la ruta de descarga del SERVIDOR y descargará el archivo allí.

Pregunta

¿Cuál es la mejor manera de abordar esto? He investigado y no puedo encontrar una buena solución para poder descargar un archivo del depósito s3 a la carpeta de descargas de los usuarios. Cualquier ayuda/consejo es muy apreciada.

about 4 years ago · Santiago Trujillo
2 answers
Answer question

0

No debería necesitar guardar el archivo en el servidor. Simplemente puede descargar el archivo en la memoria y luego crear un objeto de Response que contenga el archivo.

 from flask import Flask, Response from boto3 import client app = Flask(__name__) def get_client(): return client( 's3', 'us-east-1', aws_access_key_id='id', aws_secret_access_key='key' ) @app.route('/blah', methods=['GET']) def index(): s3 = get_client() file = s3.get_object(Bucket='blah-test1', Key='blah.txt') return Response( file['Body'].read(), mimetype='text/plain', headers={"Content-Disposition": "attachment;filename=test.txt"} ) app.run(debug=True, port=8800)

Esto está bien para archivos pequeños, no habrá ningún tiempo de espera significativo para el usuario. Sin embargo, con archivos más grandes, esto afectará la UX. El archivo deberá descargarse completamente en el servidor y luego descargarse al usuario. Entonces, para solucionar este problema, use el argumento de la palabra clave Range del método get_object :

 from flask import Flask, Response from boto3 import client app = Flask(__name__) def get_client(): return client( 's3', 'us-east-1', aws_access_key_id='id', aws_secret_access_key='key' ) def get_total_bytes(s3): result = s3.list_objects(Bucket='blah-test1') for item in result['Contents']: if item['Key'] == 'blah.txt': return item['Size'] def get_object(s3, total_bytes): if total_bytes > 1000000: return get_object_range(s3, total_bytes) return s3.get_object(Bucket='blah-test1', Key='blah.txt')['Body'].read() def get_object_range(s3, total_bytes): offset = 0 while total_bytes > 0: end = offset + 999999 if total_bytes > 1000000 else "" total_bytes -= 1000000 byte_range = 'bytes={offset}-{end}'.format(offset=offset, end=end) offset = end + 1 if not isinstance(end, str) else None yield s3.get_object(Bucket='blah-test1', Key='blah.txt', Range=byte_range)['Body'].read() @app.route('/blah', methods=['GET']) def index(): s3 = get_client() total_bytes = get_total_bytes(s3) return Response( get_object(s3, total_bytes), mimetype='text/plain', headers={"Content-Disposition": "attachment;filename=test.txt"} ) app.run(debug=True, port=8800)

Esto descargará el archivo en fragmentos de 1 MB y los enviará al usuario a medida que se descargan. Ambos han sido probados con un archivo .txt de 40 MB.

about 4 years ago · Santiago Trujillo Report

0

Una mejor manera de resolver este problema es crear una URL prefirmada . Esto le da una URL temporal que es válida hasta un cierto período de tiempo. También elimina su servidor de matraz como un proxy entre el depósito de AWS s3, lo que reduce el tiempo de descarga para el usuario.

 def get_attachment_url(): bucket = 'BUCKET_NAME' key = 'FILE_KEY' client: boto3.s3 = boto3.client( 's3', aws_access_key_id=YOUR_AWS_ACCESS_KEY, aws_secret_access_key=YOUR_AWS_SECRET_KEY ) return client.generate_presigned_url('get_object', Params={'Bucket': bucket, 'Key': key}, ExpiresIn=60) `
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!