Search code examples
pythonpython-asyncioquart

python making a post file request


Hi guys I'm developing a Python 3 quart asyncio application and I'm trying to setup a test framework around my http API.

Quart has methods to build json, form and raw requests but no files request. I believe I need build the request packet myself and post a "raw" request. Using postman I can see that the requests need to look like this:

----------------------------298121837148774387758621\r\n
Content-Disposition: form-data; name="firmware"; filename="image.bin"\r\n
Content-Type: application/octet-stream\r\n
\r\n
\x00@\x00\x10\x91\xa0\t\x08+\xaa\t\x08/\xaa\t\x083\xaa\t\x087\xaa\t\x08;\xaa\t\x08\x00\x00\x00\
....
\xff\xff\xff\xff\xff\xff\xff\xa5\t\tZ\x0c\x00Rotea MLU Main V0.12\x00\x00k%\xea\x06\r\n
----------------------------298121837148774387758621--\r\n

I'd prefer not to encode this myself if there is a method that exists.

Is there an module in Python where I can build the raw packet data and send it with the Quart API?

I have tried using quart requests:

    import requests
    from .web_server import app as quart_app

    test_client = quart_app.test_client()
    firmware_image = 'test.bin'
    with open(firmware_image, 'rb') as f:
        data = f.read()
    files = {'firmware': (firmware_image, data , 'application/octet-stream')}
    firmware_req = requests.Request('POST', 'http://localhost:5000/firmware_update', files=files).prepare()
    response = await test_client.post('/firmware_update',
                                      data=firmware_req.body,
                                      headers={'Content-type': 'multipart/form-data'})

Any suggestions would be greatly appreciated.

Cheers. Mitch.


Solution

  • Python's requests module provides a prepare function that you can use to get the raw data it would send for the request.

    import requests
    
    url = 'http://localhost:8080/'
    files = {'file' : open('z',  'rb'),
             'file2': open('zz', 'rb')}
    
    req = requests.Request('POST',url, files=files)
    r = req.prepare()
    print(r.headers)
    print(r.body)