Every API expects data in a specific format, and HTTPX separates the options more strictly than Requests.
Request options in HTTPX:
params=: query parameters as a dict (list values repeat the key) or list of tuples. They are encoded and merged into the URL.headers=: a dict of headers.json=: any JSON-serialisable object, sent withContent-Type: application/json.data=: a dict sent as an HTML form (application/x-www-form-urlencoded), or, together withfiles=, as multipart.files=: uploads, as{"field": file_obj}or{"field": (filename, file_obj, content_type)}.content=: rawbytesorstr(or an iterator for streaming) sent as is. Set your ownContent-Type.cookies=: cookies for this request (setting them per request is deprecated in favour of client cookies).
A difference from Requests: raw bytes and strings go in content=, not data=. Passing bytes to data= is deprecated and warns.
Also, httpx.get and httpx.delete do not accept a body argument, because bodies on GET and DELETE are unusual. If an API really requires a DELETE with JSON, use the generic form: httpx.request("DELETE", url, json={...}) or client.request(...).
You can build requests explicitly too: client.build_request("POST", url, json=...) returns an httpx.Request you can inspect, modify and send with client.send(request).
To check what was sent, look at r.request.headers, r.request.url and r.request.content.
Example
import httpx
base = "https://httpbin.org"
r = httpx.get(f"{base}/get", params={"tag": ["a", "b"], "n": 3},
headers={"X-Client": "demo"})
print(r.request.url.query) # b'tag=a&tag=b&n=3'
print(r.json()["headers"]["X-Client"]) # demo
r = httpx.post(f"{base}/post", data={"name": "Ada"},
files={"doc": ("a.txt", b"hello", "text/plain")})
print(r.json()["form"], r.json()["files"]) # {'name': 'Ada'} {'doc': 'hello'}
r = httpx.post(f"{base}/post", content=b"<x/>", headers={"Content-Type": "application/xml"})
print(r.json()["data"]) # <x/>
r = httpx.request("DELETE", f"{base}/delete", json={"id": 7})
print(r.json()["json"]) # {'id': 7}Remember
- params, headers, json, data, files: same ideas as Requests
- Raw bytes or text go in content=, not data=
- Use request('DELETE', ..., json=...) for bodies on DELETE
Watch out for
- Passing bytes to data= as in Requests; HTTPX expects content=.