Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask / Python. Get mimetype from uploaded file

Tags:

I am using Flask micro-framework 0.6 and Python 2.6

I need to get the mimetype from an uploaded file so I can store it.

Here is the relevent Python/Flask code:

@app.route('/upload_file', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        mimetype = #FIXME
        if file:
            file.save(os.path.join(UPLOAD_FOLDER, 'File-Name')
            return redirect(url_for('uploaded_file'))
        else:
            return redirect(url_for('upload'))


And here is the code for the webpage:

<form action="upload_file" method=post enctype=multipart/form-data> 
Select file to upload: <input type=file name=file> 
<input type=submit value=Upload> 
</form> 


The code works, but I need to be able to get the mimetype when it uploads. I've had a look at the Flask docs here: http://flask.pocoo.org/docs/api/#incoming-request-data
So I know it does get the mimetype, but I can't work out how to retrieve it - as a text string, e.g. 'txt/plain'.

Any ideas?

Thank you.

like image 276
Jon Cox Avatar asked Aug 10 '10 10:08

Jon Cox


People also ask

How do I access my uploaded files on Flask?

Handling file upload in Flask is very easy. It needs an HTML form with its enctype attribute set to 'multipart/form-data', posting the file to a URL. The URL handler fetches file from request. files[] object and saves it to the desired location.

How do you get multipart form data in Flask?

Installing Flask We create a / route for rendering the index. html template that will display a form and /handle_form route that will process the multipart form, get the uploaded file from the requests. files[] array and return. We'll use this method to send the form to the django server using the requests library.

What is MIME type in Flask?

Project description. Flask-Mime is Flask extension that enables applications to dispatch requests based on Accept header of it.

What is MIME type in Python?

The mimetypes module converts between a filename or URL and the MIME type associated with the filename extension. Conversions are provided from filename to MIME type and from MIME type to filename extension; encodings are not supported for the latter conversion.


2 Answers

From the docs, file.content_type contains the full type with encoding, mimetype contains just the mime type.

@app.route('/upload_file', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files.get('file')
        if file:
            mimetype = file.content_type
            filename = werkzeug.secure_filename(file.filename)
            file.save(os.path.join(UPLOAD_FOLDER, filename)
            return redirect(url_for('uploaded_file'))
        else:
            return redirect(url_for('upload'))
like image 107
MattH Avatar answered Sep 21 '22 08:09

MattH


You could in theory use request.files['YOUR_FILE_KEY'].content_type, but the implementation (included below, found in werkzeug.datastructures) either trust whatever the client is providing, or uses mimetypes.guess_type which only checks the file extension (see Python doc here).

class FileMultiDict(MultiDict):

    """A special :class:`MultiDict` that has convenience methods to add
    files to it.  This is used for :class:`EnvironBuilder` and generally
    useful for unittesting.
    .. versionadded:: 0.5
    """

    def add_file(self, name, file, filename=None, content_type=None):
        """Adds a new file to the dict.  `file` can be a file name or
        a :class:`file`-like or a :class:`FileStorage` object.
        :param name: the name of the field.
        :param file: a filename or :class:`file`-like object
        :param filename: an optional filename
        :param content_type: an optional content type
        """
        if isinstance(file, FileStorage):
            value = file
        else:
            if isinstance(file, string_types):
                if filename is None:
                    filename = file
                file = open(file, 'rb')
            if filename and content_type is None:
                content_type = mimetypes.guess_type(filename)[0] or \
                    'application/octet-stream'
            value = FileStorage(file, filename, name, content_type)

        self.add(name, value)

Depending on your use case, you might want to use python-magic which will use the actual file to get the mimetype. It would something like that:

import magic


def get_mimetype(data: bytes) -> str:
    """Get the mimetype from file data."""
    f = magic.Magic(mime=True)
    return f.from_buffer(data)


get_mimetype(request.files['YOUR_FILE_KEY'].stream.read(MAX_LENGTH))
like image 40
charlax Avatar answered Sep 21 '22 08:09

charlax