Carga el archivo de nuevo en el Frasco sin datos de varias partes / formulario

Estoy tratando de cargar un archivo binario a un punto final de Flask sin usar ningún tipo de multipart/form-data de multipart/form-data . Me gustaría simplemente POST o PUT los datos dentro del archivo al punto final, y guardarlos en un archivo en el servidor. Los únicos ejemplos que puedo encontrar, y el único método discutido en otras preguntas, usa multipart/form-data .

El siguiente “funciona”, pero los hash SHA256 generalmente no coinciden, mientras que cargarlos como form-data funciona bien.

 @application.route("/rupload/", methods=['POST', 'PUT']) def rupload(filename): # Sanity checks and setup skipped. filename = secure_filename(filename) fileFullPath = os.path.join(UPLOAD_FOLDER, filename) with open(fileFullPath, 'wb') as f: f.write(request.get_data()) return jsonify({ 'filename': filename, 'size': os.path.getsize(fileFullPath) }) 

Además, lo anterior es muy ineficiente con la memoria. ¿Hay alguna forma de escribirlo en el archivo de salida a través de algún tipo de flujo en búfer? ¡Gracias!

Editar: Así es como estoy probando esto:

 curl -v -H 'Content-Type: application/octet-stream' -X POST --data @test.zip https://example.com/test/rupload/test.zip 

Edición: --data-binary no hace ninguna diferencia.

¿Has intentado usar hashlib?

 import hashlib ... @application.route("/rupload/", methods=['POST', 'PUT']) def rupload(filename): # Sanity checks and setup skipped. filename = secure_filename(filename) fileFullPath = os.path.join(UPLOAD_FOLDER, filename) file_hash = hashlib.sha256() with open(fileFullPath, 'wb+') as f: input = request.get_data() f.write(input) file_hash.update(input) ... fileDigest = file_hash.hexdigest() 

El problema podría ser el comando curl que está utilizando. La página del manual recomienda –data-binary: “Esto publica los datos exactamente como se especifica sin ningún procesamiento adicional”. El parámetro –data es un sinónimo de –data-ascii. Probablemente no necesite el parámetro -X, ya que debería ser POST.

 curl -v -H 'Content-Type: application/octet-stream' -X POST --data-binary @test.zip https://example.com/test/rupload/test.zip 

Hay opciones adicionales en la llamada request.get_data que podrían ayudar en caso de que se anularan en algún lugar. Pero parece que eso debería funcionar en el lado del servidor. Deshabilitar la función de caché podría beneficiar su caso de uso en particular.

 f.write(request.get_data(cache=False, as_text=False, parse_form_data=False)) 

Si es el lado del servidor, es posible que tenga que profundizar más en Werkzeug get_input_stream, que es lo que alimenta el objeto de solicitud.

Es bueno que el comando curl utilice el encabezado de tipo de contenido como ‘application / octet-stream’. Flask no parece hacer nada con eso en este caso, pero puede ayudar a un uso más general de hacer que los datos sean destruidos por proxies u otros casos.

Con respecto al manejo eficiente de archivos grandes, es posible que desee ver la propiedad del flujo de solicitud , que es la que usa get_data internamente para leer los datos.