fastapi: `TestClient.delete()` no longer supports payloads
First Check
- I added a very descriptive title to this issue.
- I used the GitHub search to find a similar issue and didn’t find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google “How to X in FastAPI” and didn’t find any information.
- I already read and followed all the tutorial in the docs and didn’t find an answer.
- I already checked if it is not related to FastAPI but to Pydantic.
- I already checked if it is not related to FastAPI but to Swagger UI.
- I already checked if it is not related to FastAPI but to ReDoc.
Commit to Help
- I commit to help with one of those options 👆
Example Code
App
from fastapi import FastAPI
app = FastAPI()
@app.delete("/{user_id}")
async def _delete_user(user_id: int):
return {}
Test
def test_delete_user(client: TestClient):
user_id = 123
response = client.delete(f"/{user_id}", json={"validation_code": 789})
assert response.status_code == 200
Error
TypeError: TestClient.delete() got an unexpected keyword argument 'json'
Description
After updating my application to FastAPI 0.87.0 I found out that the new TestClient does not support anymore any kind of payload in the DELETE method. Although the use of a body within DELETE requests is highly discouraged, it is not forbidden. Hence, we should find a way to allow a full retro-compatibility.
An idea would be to wrap the httpx.delete method used within the TestClient class in order to re-enable this feature. For this to happen, the solution described here can be reused.
Operating System
macOS
Operating System Details
No response
FastAPI Version
0.87.0
Python Version
3.10
Additional Context
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 21 (4 by maintainers)
I just came across exactly the same issue after updating my project dependencies. Someone has removed the json attribute from the TestClient.delete function. You can work around it as follows:
client.request("DELETE", "http://service.endpoint", json={..})but it’s not ideal.
So, yep, you can still send payloads with HTTP operations that don’t really support it, but you have to be explicit that you are doing something that is kind of wrong. That’s also why it’s not part of HTTPX by default, to stop encouraging developers to use HTTP in a way that is kinda wrong and possibly broken in some environments that are more strict about the standard.
But, if you really need to bend the rules, you can do so, and it’s documented: https://www.python-httpx.org/compatibility/#request-body-on-http-methods
If you have a large code base, you can automatize the migration with https://github.com/Kludex/bump-testclient
And if you really don’t want to use the new
TestClient, you can use the backport of the old test client: https://github.com/Kludex/starlette-testclientBoth tools thanks to @Kludex 🙇🚀
It does. That’s why it’s documented to pin the FastAPI version.
The semver is not applied until 1.0, so the image above doesn’t count.
Given that I’m the most active contributor on Starlette, I can assure you I wouldn’t. 😃
If you want to send a body with a
DELETEmethod, you can replaceclient.delete(...)byclient.request(...), as mentioned in the README of bump-testclient:The argument that this is zero version and therefore you can break the API at any time is correct.
But it is not convincing. It looks like FastAPI is used in production. On FastAPI main page, we can see that it is already used by major player (Netflix, Uber…). I respect very much the modesty in being careful not to go too early to version 1+. But I think that waiting too long is a mistake.
In the roadmap of FastAPI, I cannot find the milestone to move up to 1.x.x., and until this discussion, I must admit that I did not realize that it is still dangerous to use FastAPI due to the risk that the API will be changed without warnings.
Is there a good reason today to keep the major version as zero?
I suspect that also the GET method does not support now payloads. I get the following in my tests now.
It is (maybe discouraged but) allowed to use payloads with GET, and this was working with FastAPI. Still, since the introcution of
httpxin FastAPI, our tests are broken.As this is a major change of the API, I think that if this change is kept, it deserves a major change to the version of fastapi.
I am not totally sure. You can always say that the change to the API that was made above was to remove a behavior that was anyway not totally supported (payload on GET and DELETE methods).
But if it was done on 1.x.x or later, I personally would expect that this would result in a major version change (as API was changed, and this has the potential to break things). This in turn would save me some time trying to understand how my tests were suddenly broken. Again, you can argue that this is not a real breaking change, as the behavior was not really supported.
The page about the versions indeed explain well that each version could potentially have breaking changes. But it also states that “FastAPI is already being used in production in many applications and systems”. This means that it should be with a major version bigger than zero.
I understand that features are still being added, but then, when there is a breaking change, you can just upgrade the major version number.
By specification, yes: Paragraph 4 of https://semver.org/
Technically not…
Doesn’t 0.x.x imply that breaking changes could occur anytime?
https://github.com/encode/httpx/discussions/1587
FastAPI’s release 0.87.0 upgrades Starlette to 0.21.0 which replaces
requestswithhttpx.fastapi.testclient.TestClientis only a shortcut forstarlette.testclient.TestClient, thus, IMO, you should open an issue in Starlette’s issues. You’ll also probably receive an answer faster there.