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)

Commits related to this issue

Most upvoted comments

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-testclient

Both tools thanks to @Kludex 🙇🚀

Doesn’t 0.x.x imply that breaking changes could occur anytime?

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.

I’m quite sure that if I open an issue on Starlette repo they’ll tell me to go back to FastAPI repo sweat_smile

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 DELETE method, you can replace client.delete(...) by client.request(...), as mentioned in the README of bump-testclient:

image

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?

https://github.com/encode/httpx/discussions/1587

As I already said, using payloads is highly discouraged but not forbidden! Furthermore, before this update everything worked fine

I suspect that also the GET method does not support now payloads. I get the following in my tests now.

response = pytest.client.get("/myfunc", json={"some-key": "some-value"})
E       TypeError: get() got an unexpected keyword argument 'json'

It is (maybe discouraged but) allowed to use payloads with GET, and this was working with FastAPI. Still, since the introcution of httpx in 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.

Technically not…

By specification, yes: Paragraph 4 of https://semver.org/

Doesn’t 0.x.x imply that breaking changes could occur anytime?

Technically not…

1589209257533

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 requests with httpx. fastapi.testclient.TestClient is only a shortcut for starlette.testclient.TestClient, thus, IMO, you should open an issue in Starlette’s issues. You’ll also probably receive an answer faster there.