【问题标题】:Simulate multipart/form-data file upload with Falcon's Testing module使用 Falcon 的测试模块模拟 multipart/form-data 文件上传
【发布时间】:2017-03-14 12:50:40
【问题描述】:

这个简单的 Falcon API 将采用 HTTP POSTenctype=multipart/form-data 并在 file 参数中上传文件并在控制台上打印文件的内容:

# simple_api.py
import cgi
import falcon

class SomeTestApi(object):
    def on_post(self, req, resp):
        upload = cgi.FieldStorage(fp=req.stream, environ=req.env)
        upload = upload['file'].file.read()
        print(upload)


app = falcon.API()
app.add_route('/', SomeTestApi())

也可以使用falcon-multipart 中间件来实现相同的目标。

要试用它,请运行它,例如与gunicorn (pip install gunicorn),

gunicorn simple_api.py

然后使用 cUrl(或任何选择的 REST 客户端)上传文本文件:

# sample.txt
this is some sample text

curl -F "file=@sample.txt" localhost:8000

我现在想通过模拟文件上传来使用 Falcon 的 testing helpers 测试这个 API。但是,我还不明白如何做到这一点(如果可能的话?)。 simulate_request method 有一个 file_wrapper 参数,它可能很有用,但从文档中我不明白应该如何填充它。

有什么建议吗?

【问题讨论】:

    标签: python file-upload functional-testing falconframework


    【解决方案1】:

    这是我想出的,它试图模拟我的 Chrome 所做的事情。 请注意,这模拟了您只上传一个文件的情况,但您可以简单地修改此函数以上传多个文件,每个文件由两个新行分隔。

    def create_multipart(data, fieldname, filename, content_type):
        """
        Basic emulation of a browser's multipart file upload
        """
        boundry = '----WebKitFormBoundary' + random_string(16)
        buff = io.BytesIO()
        buff.write(b'--')
        buff.write(boundry.encode())
        buff.write(b'\r\n')
        buff.write(('Content-Disposition: form-data; name="%s"; filename="%s"' % \
                   (fieldname, filename)).encode())
        buff.write(b'\r\n')
        buff.write(('Content-Type: %s' % content_type).encode())
        buff.write(b'\r\n')
        buff.write(b'\r\n')
        buff.write(data)
        buff.write(b'\r\n')
        buff.write(boundry.encode())
        buff.write(b'--\r\n')
        headers = {'Content-Type': 'multipart/form-data; boundary=%s' %boundry}
        headers['Content-Length'] = str(buff.tell())
        return buff.getvalue(), headers
    

    然后你可以像下面这样使用这个函数:

    with open('test/resources/foo.pdf', 'rb') as f:
        foodata = f.read()
    
    # Create the multipart data
    data, headers = create_multipart(foodata, fieldname='uploadFile',
                                     filename='foo.pdf',
                                     content_type='application/pdf')
    
    # Post to endpoint
    client.simulate_request(method='POST', path=url,
                            headers=headers, body=data)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      相关资源
      最近更新 更多