Skip to content

HTTP Post with files works with Requests but not HTTPX #481

Closed

Description

@phishstang65

Hi. The following works with Requests, but not HTTPX. Can you please help me understand how to make it work:

import requests
import uuid
import subprocess
import json
import os
import httpx

newName = uuid.uuid4().hex
event = uuid.uuid4().hex

subprocess.call("cp index.jpeg /tmp/%s.jpeg"%(newName),shell=True)

url = 'http://myserver.us-west-2.compute.amazonaws.com'

event = "ASDGASFDASDF"
payload = {'event': "%s"%(event) , 'confidence': 95}

thermalName = "/tmp/%s.jpeg"%(newName)
newName = thermalName

files = {

        'json': (None, json.dumps(payload), 'application/json'),
        'image': (os.path.basename(newName), open(newName, 'rb'), 'application/octet-stream'),
        'image1': (os.path.basename(newName), open(newName, 'rb'), 'application/octet-stream'),
        'image2': (os.path.basename(newName), open(newName, 'rb'), 'application/octet-stream')

        }

# Do the HTTP POST
#r = requests.post(url, files=files)
r = httpx.post(url, files=files)
print(r.text)

The error I get is:

Traceback (most recent call last):
  File "test-post.py", line 32, in <module>
    r = httpx.post(url, files=files)
  File "/usr/local/lib/python3.6/dist-packages/httpx/api.py", line 183, in post
    trust_env=trust_env,
  File "/usr/local/lib/python3.6/dist-packages/httpx/api.py", line 53, in request
    trust_env=trust_env,
  File "/usr/local/lib/python3.6/dist-packages/httpx/client.py", line 718, in request
    cookies=cookies,
  File "/usr/local/lib/python3.6/dist-packages/httpx/client.py", line 336, in build_request
    cookies=cookies,
  File "/usr/local/lib/python3.6/dist-packages/httpx/models.py", line 696, in __init__
    content, content_type = self.encode_data(data, files, json)
  File "/usr/local/lib/python3.6/dist-packages/httpx/models.py", line 619, in encode_data
    content, content_type = multipart_encode(data or {}, files)
  File "/usr/local/lib/python3.6/dist-packages/httpx/multipart.py", line 103, in multipart_encode
    body.write(field.render_headers())
  File "/usr/local/lib/python3.6/dist-packages/httpx/multipart.py", line 66, in render_headers
    filename = _format_param("filename", self.filename)
  File "/usr/local/lib/python3.6/dist-packages/httpx/multipart.py", line 121, in _format_param
    value = _HTML5_FORM_ENCODING_RE.sub(replacer, value)
TypeError: expected string or bytes-like object

Activity

  1. sethmlarson commented on Oct 17, 2019

    @sethmlarson
    Contributor

    Thanks for reporting this! Our multipart support definitely isn't exercised enough in the test suite.

  2. yeraydiazdiaz commented on Oct 17, 2019

    @yeraydiazdiaz
    Contributor

    I had a quick look at this and considering our docs on multipart encoding:

    1. When specifying files as a Dict[str, tuple] the first element of the tuple must be a string. In your example you're setting it to None which is causing the error.
    2. The multipart encoding expects the second element to be a file-like object, again in that first example you're using an str which also causes an error.

    I can confirm both of those are accepted in requests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    requests-compatIssues related to Requests backwards compatibility

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions