Python中的Podio文件上载失败

Python中的Podio文件上载失败,python,podio,Python,Podio,我正试图上传到podio,但失败了。 以下摘录: c = api.OAuthClient( podio_pw.client_id, podio_pw.client_secret, podio_pw.username, podio_pw.password, source = "dit is een test" attributes = { 'filename' : 'test.txt', 'source'

我正试图上传到podio,但失败了。 以下摘录:

c = api.OAuthClient(
    podio_pw.client_id,
    podio_pw.client_secret,
    podio_pw.username,
    podio_pw.password,  
source = "dit is een test"
    attributes = {
            'filename' : 'test.txt',
            'source' : source
            }
    filep = 

c.transport.POST(url='/file/v2/',body=attributes,type='multipart/form-data')
这总是导致以下错误

Traceback (most recent call last):
  File "C:\Python34\libs\podio-py-master\attach_invoices.py", line 43, in <module>
    filep = c.transport.POST(url='/file/v2/',body=attributes,type='multipart/form-data')
  File "C:\Python34\libs\podio-py-master\pypodio2\transport.py", line 135, in __call__
    body = "".join(body)
  File "C:\Python34\libs\podio-py-master\pypodio2\encode.py", line 376, in __next__
    return next(self)
  File "C:\Python34\libs\podio-py-master\pypodio2\encode.py", line 352, in __next__
    block = next(self.param_iter)
  File "C:\Python34\libs\podio-py-master\pypodio2\encode.py", line 245, in iter_encode
    block = self.encode(boundary)
  File "C:\Python34\libs\podio-py-master\pypodio2\encode.py", line 233, in encode
    if re.search("^--%s$" % re.escape(boundary), value, re.M):
  File "C:\Python34\lib\re.py", line 166, in search
    return _compile(pattern, flags).search(string)
TypeError: can't use a string pattern on a bytes-like object
回溯(最近一次呼叫最后一次):
文件“C:\Python34\libs\podio py master\attach_invoices.py”,第43行,在
filep=c.transport.POST(url='/file/v2/',body=attributes,type='multipart/formdata')
文件“C:\Python34\libs\podio py master\pypodio2\transport.py”,第135行,在调用中__
body=”“.连接(body)
文件“C:\Python34\libs\podio py master\pypodio2\encode.py”,第376行,下一步__
返回下一个(自我)
文件“C:\Python34\libs\podio py master\pypodio2\encode.py”,第352行,下一步__
块=下一个(自参数)
文件“C:\Python34\libs\podio py master\pypodio2\encode.py”,第245行,在iter_encode中
块=自编码(边界)
文件“C:\Python34\libs\podio py master\pypodio2\encode.py”,第233行,在encode中
如果重新搜索(“^--%s$%re.escape(boundary),value,re.M):
搜索中第166行的文件“C:\Python34\lib\re.py”
返回编译(模式、标志)。搜索(字符串)
TypeError:无法在类似字节的对象上使用字符串模式
我知道它与字节编码等有关,但我不知道如何处理它。即使我尝试将该源文件设置为文件、原始文件或其他文件,POST也会失败。

这对我来说很有效:

c = api.OAuthClient(
    client_id,
    client_secret,
    username,
    password,    
)

filename = 'screenie.png'
filedata = open(filename, 'r')

"""Create a file from raw data"""
attributes = {'filename': filename,
              'source': filedata}

file_upload = c.transport.POST(url='/file/v2/', body=attributes, type='multipart/form-data')
print(file_upload)
我从这里提取了代码:

返回“只能加入一个iterable错误”


要在Python 3.*中执行文件上载过程,必须在
pypodio
中更新两个文件

步骤1

用下面的脚本替换文件
encode.py

import urllib.request
import http.client
import mimetypes
import codecs
import uuid
import binascii
import io
import os
import sys

def multipart_encode(fields, files):
    content_type, body = MultipartFormdataEncoder().encode(fields, files)
    return body, content_type


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, fpath) 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 open(fpath, 'rb') as 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()

与source=open(“test.txt”、“rb”)的结果相同。有人能解释一下这个属性变量中的“source”应该是什么吗?文件、文件名、文件对象、二进制/原始文件或…??您使用哪个版本的pythonused@nitanshbareja我正在使用python 2.7。13@nitanshbareja也许你可以试着使用文档来滚动你自己的。
import urllib.request
import http.client
import mimetypes
import codecs
import uuid
import binascii
import io
import os
import sys

def multipart_encode(fields, files):
    content_type, body = MultipartFormdataEncoder().encode(fields, files)
    return body, content_type


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, fpath) 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 open(fpath, 'rb') as 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()
        if kwargs['type'] == 'multipart/form-data':
            fields = [('filename', kwargs['body']['filename'])]
            files = [('source', kwargs['body']['filename'],kwargs['body']['source'])]
            body, content_type = multipart_encode(fields,files)
            headers.update({'Content-Type': content_type, })
        else: