You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
AsyncClient.request runtime error: "Attempted to send an sync request with an AsyncClient instance" #2491
Ran into this issue as well. It was surprising to end up with a RuntimeError: Attempted to send an sync request with an AsyncClient instance error, when my actual issue had nothing to do with sync/async (in my case submitting the wrong type by accident through data kwarg). It feels like it might be a bug / that the type being submitted could be checked before trying to send the request?
Originally posted by mdlincoln August 16, 2022
I need to interact with an API that accepts DELETE requests requiring JSON content in the body. Since AsyncClient's shortcut delete() method does not allow this, I followed the docs to instead use the request() method, but I received an unexpected error. Minimal example:
this raises a RuntimeError: Attempted to send an sync request with an AsyncClient instance. (full traceback in the <details> below.)
Am I missing the right way for calling the request() method with an AsyncClient?
Details
Traceback (most recent call last):
File "*******/minimal.py", line 14, in
asyncio.run(test_request_method())
File "/opt/homebrew/Cellar/python@3.9/3.9.13_3/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/opt/homebrew/Cellar/python@3.9/3.9.13_3/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
return future.result()
File "*********minimal.py", line 11, in test_request_method
response = await ac.request(method="DELETE", url="/", content={"foo": "bar"})
File "*********/lib/python3.9/site-packages/httpx/_client.py", line 1527, in request
return await self.send(request, auth=auth, follow_redirects=follow_redirects)
File "*********/lib/python3.9/site-packages/httpx/_client.py", line 1614, in send
response = await self._send_handling_auth(
File "*********/lib/python3.9/site-packages/httpx/_client.py", line 1642, in _send_handling_auth
response = await self._send_handling_redirects(
File "*********/lib/python3.9/site-packages/httpx/_client.py", line 1679, in _send_handling_redirects
response = await self._send_single_request(request)
File "*********/lib/python3.9/site-packages/httpx/_client.py", line 1711, in _send_single_request
raise RuntimeError(
RuntimeError: Attempted to send an sync request with an AsyncClient instance.
To improve our UX here we ought to be raising a TypeError if a dictionary is passed in the content=... argument.
Because it won't do what you're expecting it to do.
In the async case you'll end up with this really confusing error message.
This is because content=... should be a str, bytes, or bytes iterator. Because dict instances happen to be iterators, the internals assume a bytes-iterator has been passed, and treat it as a valid argument.
Really we'd like the same behaviour that we currently have if you pass some other incorrect type to content=..., eg:
Activity
lovelydinosaur commentedon Dec 6, 2022
That's a really confusing error message that you're seeing, which I need to dig into.
But the short answer to your question is...
Okay, so use
json=...to send JSON data...lovelydinosaur commentedon Dec 6, 2022
To improve our UX here we ought to be raising a
TypeErrorif a dictionary is passed in thecontent=...argument.Because it won't do what you're expecting it to do.
In the async case you'll end up with this really confusing error message.
In the sync case, you'll end up with...
This is because
content=...should be a str, bytes, or bytes iterator. Becausedictinstances happen to be iterators, the internals assume a bytes-iterator has been passed, and treat it as a valid argument.Really we'd like the same behaviour that we currently have if you pass some other incorrect type to
content=..., eg:It would be good if we switch the behaviour for the
dictcase to match this...