feat: create httpx.AsyncClient in lifespan for federation

This commit is contained in:
Brian Krabach
2026-04-01 10:43:31 -07:00
parent f09068c1f1
commit c03c85c76a
2 changed files with 34 additions and 0 deletions
+5
View File
@@ -20,6 +20,7 @@ import sys
import time
from typing import Literal
import httpx
import websockets
import websockets.exceptions
from websockets.typing import Subprotocol
@@ -175,8 +176,12 @@ async def lifespan(app: FastAPI):
except Exception:
pass # tmux not running at startup is OK; hook will be set on first poll
app.state.federation_client = httpx.AsyncClient(timeout=5.0, follow_redirects=False)
yield
await app.state.federation_client.aclose()
# Shutdown: cancel the poll loop task and wait for it to finish.
if _poll_task is not None:
_poll_task.cancel()
+29
View File
@@ -1435,3 +1435,32 @@ def test_federation_bearer_auth_accepted(monkeypatch):
)
assert response.status_code == 200
# ---------------------------------------------------------------------------
# httpx.AsyncClient federation client on app.state (task-7)
# ---------------------------------------------------------------------------
def test_federation_client_exists_on_app_state(monkeypatch):
"""app.state.federation_client is set during lifespan and is not None.
Verifies that the lifespan creates an httpx.AsyncClient and attaches it to
app.state.federation_client before the application begins serving requests.
"""
import httpx
monkeypatch.setenv("MUXPLEX_PASSWORD", "test-password")
with TestClient(app) as c:
# Inside the context manager the lifespan has completed startup,
# so app.state.federation_client must be set.
assert hasattr(app.state, "federation_client"), (
"app.state.federation_client must be set during lifespan startup"
)
assert app.state.federation_client is not None, (
"app.state.federation_client must not be None"
)
assert isinstance(app.state.federation_client, httpx.AsyncClient), (
"app.state.federation_client must be an httpx.AsyncClient instance"
)