ijd8.COM

A simple blog for an old Ma Nong.

用 Python SDK 尝试上传文件到 BCS

Permalink

在python SDK 下尝试上传文件到 BCS 时遇到错误,出现提示是 UnicodeDecodeError: 'utf8' codec can't decode byte 0xa7 in position 6: invalid start byte。又是编码问题,看看折腾过程:

我上传的是图片,因为以前在用官方的代码测试时能正确上传。以下是官方部分重要代码:

Python: BAE BCS python SDK sample http://pythondoc.duapp.com/bcs.html 官方示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def test_bcs():
    ### 首先通过云存储管理界面,创建一个bucket
    bname = 'test-bucket'

    ### 创建BCS管理对象
    baebcs = bcs.BaeBCS(HOST, AK, SK)

    ### 读取一个测试文件的内容
    filename = os.path.dirname(__file__) + "/testdata"
    with open(filename) as fd:
        data = fd.read()

    ### 将文件内容上传到 '/obj1' 下
    o1 = '/obj1'
    e, d = baebcs.put_object(bname, o1, data)
    assert e == 0

既然是编码的问题,那尝试转换一下编码,encode、decode都轮流上马。但还是没用,尝试用其它方式,如StringIO,tmpfile等,还用到PIL 对图像转换一下。还是出现类似下面的提示:

plaintext: UnicodeDecodeError
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Traceback (most recent call last):
  File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/site-packages/tornado/web.py", line 954, in _execute
    getattr(self, self.request.method.lower())(*args, **kwargs)
  File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/site-packages/tornado/web.py", line 1667, in wrapper
    return method(self, *args, **kwargs)
  File "/home/bae/instanceall/instance1/codefs/bae4py.duapp.com/admin.py", line 126, in post
    d = upload(BUCKET, "/upload/%s" % new_file_name, myfile['body'])
  File "/home/bae/instanceall/instance1/codefs/bae4py.duapp.com/admin.py", line 91, in upload
    e,r = mybcs.put_object(bucketname, savename, filedata)
  File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/bae/api/bcs/bcs.py", line 74, in put_object
    r = self.httpc.put(url, data, headers={})
  File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/bae/api/bcs/httpc.py", line 132, in put
    return self.request('PUT', url, body, headers)
  File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/bae/api/bcs/httpc.py", line 90, in request
    response = self.send_request(verb, url, data, headers)
  File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/bae/api/bcs/httpc.py", line 118, in send_request
    conn.request(verb, path, data, headers)
  File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/httplib.py", line 973, in request
    self._send_request(method, url, body, headers)
  File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/httplib.py", line 1007, in _send_request
    self.endheaders(body)
  File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/httplib.py", line 969, in endheaders
    self._send_output(message_body)
  File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/httplib.py", line 818, in _send_output
    msg += message_body
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa7 in position 6: invalid start byte

尝试上传其它文件,如文本文件,正常!

找到以前测试成功的代码,在线一步一步调试,看哪个地方出问题。

最后怎么着?

"/upload/" + new_file_name 改为 "/upload/" + str(new_file_name)即可,简直太牛B了,花了半天发现的问题!

附一个可用的上传代码,tornado 框架下

Python: BCS python 上传文件示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def upload(bucketname=BUCKET, savename="/test.txt", filedata=None):
    if bucketname and savename and filedata:
        if DEBUG:
            return None
        from bae.api import bcs
        mybcs = bcs.BaeBCS(BCSHOST, AK, SK)
        e,r = mybcs.put_object(bucketname, savename, filedata)
        return r
    else:
        return "no data"

class UploadPage(BaseHandler):
    @tornado.web.authenticated
    def get(self):
        self.echo("upload-test.html", {"title": "file upload"})

    @tornado.web.authenticated
    def post(self):
        rspd = {'status': 201, 'msg':'ok'}
        upfile = self.request.files.get('fileupload', None)

        if upfile:
            myfile = upfile[0]

            try:
                 file_type = myfile['filename'].split('.')[-1].lower()
                 new_file_name = "%s.%s"% (str(int(time())), file_type)
            except:
                 file_type = ''
                 new_file_name = str(int(time()))

            d = upload(BUCKET, "/upload/" + str(new_file_name), myfile['body'])
            if d is None:
                #self.write("upload well done.")
                rspd['status'] = 200
                rspd['filename'] = myfile['filename']
                rspd['msg'] = "http://%s/%s/upload/%s" % (BCSHOST, BUCKET, new_file_name)
            else:
                #self.write(d)
                rspd['status'] = 500
                rspd['msg'] = '500 error, pls try it again.'
        else:
            rspd['msg'] = 'none file uploaded.'

        self.set_header('Content-Type','text/html')
        self.write(json.dumps(rspd))
        return

Write a Comment

Submit Comment Login
Based on Golang + fastHTTP + sdb | go1.16.7 Processed in 2ms