Frage

Ich mag multipart / POST form-data-codierte Daten. Ich habe ein externes Modul gefunden, die es tut: http://atlee.ca/software/poster/index .html aber ich würde eher diese Abhängigkeit vermeiden. Gibt es eine Möglichkeit, dies mit den Standardbibliotheken zu tun?

Dank

War es hilfreich?

Lösung

Die Standardbibliothek zur Zeit nicht, dass unterstützen. Es gibt Kochbuch Rezept dass ein ziemlich kurzes umfasst Stück Code, den Sie allerdings nur wünschen können, kopieren, zusammen mit langen Diskussionen von Alternativen.

Andere Tipps

Es ist ein alter Thread, aber immer noch ein beliebter ein, also hier ist mein Beitrag nur Standardmodule verwenden.

Die Idee ist das gleiche als hier aber Unterstützung Python 2.x und Python 3. X. Es hat auch einen Körper Generator unnötig Speicherverbrauch zu vermeiden.

import codecs
import mimetypes
import sys
import uuid
try:
    import io
except ImportError:
    pass # io is requiered in python3 but not available in python2

class MultipartFormdataEncoder(object):
    def __init__(self):
        self.boundary = uuid.uuid4().hex
        self.content_type = 'multipart/form-data; boundary={}'.format(self.boundary)

    @classmethod
    def u(cls, s):
        if sys.hexversion < 0x03000000 and isinstance(s, str):
            s = s.decode('utf-8')
        if sys.hexversion >= 0x03000000 and isinstance(s, bytes):
            s = s.decode('utf-8')
        return s

    def iter(self, fields, files):
        """
        fields is a sequence of (name, value) elements for regular form fields.
        files is a sequence of (name, filename, file-type) elements for data to be uploaded as files
        Yield body's chunk as bytes
        """
        encoder = codecs.getencoder('utf-8')
        for (key, value) in fields:
            key = self.u(key)
            yield encoder('--{}\r\n'.format(self.boundary))
            yield encoder(self.u('Content-Disposition: form-data; name="{}"\r\n').format(key))
            yield encoder('\r\n')
            if isinstance(value, int) or isinstance(value, float):
                value = str(value)
            yield encoder(self.u(value))
            yield encoder('\r\n')
        for (key, filename, fd) in files:
            key = self.u(key)
            filename = self.u(filename)
            yield encoder('--{}\r\n'.format(self.boundary))
            yield encoder(self.u('Content-Disposition: form-data; name="{}"; filename="{}"\r\n').format(key, filename))
            yield encoder('Content-Type: {}\r\n'.format(mimetypes.guess_type(filename)[0] or 'application/octet-stream'))
            yield encoder('\r\n')
            with fd:
                buff = fd.read()
                yield (buff, len(buff))
            yield encoder('\r\n')
        yield encoder('--{}--\r\n'.format(self.boundary))

    def encode(self, fields, files):
        body = io.BytesIO()
        for chunk, chunk_len in self.iter(fields, files):
            body.write(chunk)
        return self.content_type, body.getvalue()

Demo

# some utf8 key/value pairs
fields = [('প্রায়', 42), ('bar', b'23'), ('foo', 'ން:')]
files = [('myfile', 'image.jpg', open('image.jpg', 'rb'))]

# iterate and write chunk in a socket
content_type, body = MultipartFormdataEncoder().encode(fields, files)

Sie können diese schnell mit dem stdlib nicht tun. Howevewr finden Sie in der MultiPartForm Klasse in diesem PyMOTW. Sie können sich wahrscheinlich, dass verwenden oder modifizieren zu erreichen, was Sie brauchen:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top