문제

멀티파트/폼 데이터로 인코딩된 데이터를 POST하고 싶습니다.이를 수행하는 외부 모듈을 찾았습니다. http://atlee.ca/software/poster/index.html그러나 나는 오히려 이러한 의존성을 피하고 싶습니다.표준 라이브러리를 사용하여 이를 수행할 수 있는 방법이 있습니까?

감사해요

도움이 되었습니까?

해결책

표준 라이브러리 현재이를 지원하지 않습니다. 거기 있습니다 요리 책 레시피 여기에는 대안에 대한 긴 토론과 함께 복사하고 싶을 수도있는 상당히 짧은 코드가 포함됩니다.

다른 팁

그것은 오래된 스레드이지만 여전히 인기있는 스레드이므로 표준 모듈 만 사용하는 나의 기여가 있습니다.

아이디어는 동일합니다 여기 그러나 Python 2.X 및 Python 3.X를 지원하십시오. 또한 불필요하게 메모리 사용을 피하기위한 바디 생성기가 있습니다.

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()

데모

# 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)

stdlib로는 이 작업을 빠르게 수행할 수 없습니다.그러나 다음을 참조하십시오. MultiPartForm 이 PyMOTW의 클래스입니다.필요한 모든 것을 달성하기 위해 이를 사용하거나 수정할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top