httpx: Test client usage question: how to trigger lifespan startup and shutdown ?
I have an issue switching from the TestClient from async_asgi_testclient to the httpx.AsyncClient : the startup and shutdown events of my app aren’t triggered by the latter.
It’s probably a bad usage on my end, but if anyone could pinpoint what I’m doing wrong it would be of tremendous help,
I wrote a small set of 2 tests below to better describe the situation, the one with httpx.AsyncClient fails while the other passes fine:
import logging
import pytest
from async_asgi_testclient import TestClient
from httpx import AsyncClient
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
app = Starlette()
@app.on_event("startup")
async def startup():
logger.debug("starting the app")
@app.on_event("shutdown")
async def shutdown():
logger.debug("shutdown the app")
@app.route("/")
def homepage(request: Request):
logger.debug("HOME")
return JSONResponse({"hello": "world"})
@pytest.fixture
async def asyncasgitestclient():
yield TestClient(app)
@pytest.fixture
async def httpxclient():
yield AsyncClient(app=app, base_url="https://domain.tld")
@pytest.mark.asyncio
async def test_homepage_with_httpxclient(httpxclient, caplog):
async with httpxclient:
url = app.url_path_for("homepage")
resp = await httpxclient.get(url)
assert resp.status_code == 200
assert resp.json() == {"hello": "world"}
logger.debug(caplog.messages)
assert all(
x in caplog.messages for x in ["starting the app", "HOME", "shutdown the app"]
)
@pytest.mark.asyncio
async def test_homepage_with_async_asgi_testclient(asyncasgitestclient, caplog):
async with asyncasgitestclient:
url = app.url_path_for("homepage")
resp = await asyncasgitestclient.get(url)
assert resp.status_code == 200
assert resp.json() == {"hello": "world"}
logger.debug(caplog.messages)
assert all(
x in caplog.messages for x in ["starting the app", "HOME", "shutdown the app"]
)
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 19 (16 by maintainers)
Okay so, I created https://github.com/florimondmanca/asgi-lifespan to experiment on this. It’s mostly empty for now but I’ll add
LifespanContextbased on the implementation in #352, and I plan to haveLifespanMiddlewarebe mostly ripped out from Starlette.Any thoughts on the proposed API there?
Dropping in just to say that it’s a bummer that a full ASGI use-case can’t be solved with just HTTPX. IMO this is one of our defining features as an HTTP client in the ecosystem.
@Ammar-Azman Hey! This issue is for adding support for calling lifespan events from a HTTPX client not defining them. Please open a discussion on FastAPI instead. Make sure you read the documentation on lifespan events first — I believe they are always application not router scoped.
@kernc Thanks, I logged #1441 so that we’re properly tracking this, and so that’s visible to anyone up for contributing. 😃
Yup, I’m sold on the idea of decoupling the two, definitely.
I think there’s a case to be made there, but I’m quite keen on treating it as an entierly seperate issue. (Users are also free to deal with application setup/teardown in test cases in more explicit ways rather than relying on ASGI’s lifespan messaging)