Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - What type is flask.request.files.stream supposed to be?

In Flask (Flask-0.10.1 installed via pip) I've tried to handle uploaded files like this

f = flask.request.files[input_name]
stream = f.stream
# then use the stream

But it's confusing that in some cases stream is a BytesIO instance, but also a chance to be a file object.

I've tested in this way

from flask import Flask, request
import cStringIO

app = Flask('test')

@app.route("/", methods=['POST'])
def index():
    if request.method == 'POST':
        f = request.files['file']
        print type(f.stream)

def send_file(client, name):
    with open(name, 'rb') as f:
        client.post('/', data={'file': (cStringIO.StringIO(f.read()), name)})

if __name__ == "__main__":
    with app.test_client() as client:
        send_file(client, 'homercat.png')
        send_file(client, 'megacat-2.png')

It prints

<type '_io.BytesIO'>
<type 'file'>

The PNG files are from github:

http://octodex.github.com/images/homercat.png http://octodex.github.com/images/megacat-2.png

I wonder why Flask behaves in such way. And if I want the uploaded data to go to the database, is it ok to call f.stream.read() in both cases?

like image 879
neuront Avatar asked Mar 23 '23 18:03

neuront


1 Answers

Files smaller than 1024 * 500 bytes are written to a StringIO object, while files greater than that threshold are written to temporary files.

It's part of Werkzeug's testing framework, but that function isn't part of the online documentation:

def stream_encode_multipart(values, use_tempfile=True, threshold=1024 * 500,
                            boundary=None, charset='utf-8'):
    """Encode a dict of values (either strings or file descriptors or
    :class:`FileStorage` objects.) into a multipart encoded string stored
    in a file descriptor.
    """

    ...

Source

like image 159
Blender Avatar answered Apr 26 '23 11:04

Blender