Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AsyncClient app parameter deprecation #16

Closed
TheoBabilon opened this issue May 2, 2024 · 2 comments · Fixed by #17
Closed

AsyncClient app parameter deprecation #16

TheoBabilon opened this issue May 2, 2024 · 2 comments · Fixed by #17

Comments

@TheoBabilon
Copy link
Contributor

Hi @Kludex ,

Not sure if relevant, but whilst following tip 5 Use HTTPX's AsyncClient instead of TestClient in one of my current FastAPIs, I was only receiving 302s status codes:

async def test_client():
    async with AsyncClient(app=dividend_app, base_url="http://testserver") as client:
        resp = await client.get("/user/me")

getting

(Pdb++) resp
<Response [302 Found]>
(Pdb++) resp.text
'<HTML>\r\n<HEAD><TITLE>Redirection</TITLE></HEAD>\r\n<BODY><H1>Redirect</H1></BODY>\r\n</HTML>\r\n'

I can reproduce from current README's MCVE.
Steps to reproduce:

uv venv
source .venv/bin/activate
uv pip install fastapi[all]

Then running mcve.py:

from fastapi import FastAPI


app = FastAPI()


@app.get("/")
async def read_root():
    return {"Hello": "World"}


# Using TestClient
from starlette.testclient import TestClient

client = TestClient(app)
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"Hello": "World"}

# Using AsyncClient
import anyio
from httpx import AsyncClient


async def main():
    async with AsyncClient(app=app, base_url="http://test") as client:
        response = await client.get("/")
        assert response.status_code == 200
        assert response.json() == {"Hello": "World"}


anyio.run(main)

gives

  File "/path/to/mcve.py", line 29, in main
    assert response.status_code == 200
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError

status_code is indeed 302.

I believe it comes from httpx's AsyncClient app parameter deprecation in 0.27.0.

Changing to

async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client

fixes the issue, making the above MCVE pass.

FWIW, uv pip list gives

$> uv pip list
Package              Version
-------------------- --------
annotated-types      0.6.0
anyio                4.3.0
certifi              2024.2.2
click                8.1.7
dnspython            2.6.1
email-validator      2.1.1
fastapi              0.110.3
h11                  0.14.0
httpcore             1.0.5
httptools            0.6.1
httpx                0.27.0
idna                 3.7
itsdangerous         2.2.0
jinja2               3.1.3
markupsafe           2.1.5
orjson               3.10.2
pydantic             2.7.1
pydantic-core        2.18.2
pydantic-extra-types 2.7.0
pydantic-settings    2.2.1
python-dotenv        1.0.1
python-multipart     0.0.9
pyyaml               6.0.1
sniffio              1.3.1
starlette            0.37.2
typing-extensions    4.11.0
ujson                5.9.0
uvicorn              0.29.0
uvloop               0.19.0
watchfiles           0.21.0
websockets           12.0
@Kludex
Copy link
Owner

Kludex commented May 2, 2024

It's relevant, and the example needs to be updated to use the ASGITransport. But... If you add a slash at the end of the /user/me/, does still redirects?

In any case, PR welcome to add the ASGITransport. :)

@TheoBabilon
Copy link
Contributor Author

Can confirm that status_code is still 302 when targeting /user/me/, so the trailing slash makes no difference here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants