Make a httpx GET request with data body

1k views Asked by At

When I do a curl request for GET endpoint of a REST API, I would go it like this

curl -X 'GET' \
  'http://localhost:8000/user/?limit=10' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '[
  {
    "item_type": "user",
    "skip": 0
  }
]'

Directly translated into requests, I would get

import requests

headers = {
    'accept': 'application/json',
    'Content-Type': 'application/json',
}

params = {
    'limit': '10'
}

json_data = [
    {
        'item_type': 'user',
        'skip': 0,
    },
]

response = requests.get('http://localhost:8000/user/', params=params, headers=headers, json=json_data)

# Note: json_data will not be serialized by requests
# exactly as it was in the original request.
#data = '[\n  {\n    "item_type": "document",\n    "skip": 0\n  }\n]'
#response = requests.get('http://localhost:8000/user/', params=params, headers=headers, data=data)

Now for my test environment I am going to use httpx's AsyncClient, but I cannot find a way to use the data part, i.e., [{"item_type": "user", "skip": 0}], in a get request.

It would be terrific, if you know how to address this.

1

There are 1 answers

2
Woodford On BEST ANSWER

According to the httpx docs, .get doesn't support request bodies. It suggests you use the more generic .request function instead.

The HTTP GET, DELETE, HEAD, and OPTIONS methods are specified as not supporting a request body. To stay in line with this, the .get, .delete, .head and .options functions do not support content, files, data, or json arguments.

# possible alternative
httpx.request(
  method="GET",
  url="https://www.example.com/",
  content=b'A request body on a GET request.'
)

Important note: the HTTP spec states clients should not use body content with GET requests and if they do, there's no guarantee that it will show up at the server (as intermediaries are allowed to strip it off):

Although request message framing is independent of the method used, content received in a GET request has no generally defined semantics, cannot alter the meaning or target of the request, and might lead some implementations to reject the request and close the connection because of its potential as a request smuggling attack (Section 11.2 of [HTTP/1.1]). A client SHOULD NOT generate content in a GET request unless it is made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported. An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain