Coverage for tests / test_dependency_yield_scope_websockets.py: 100%
119 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-12 18:15 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-12 18:15 +0000
1from contextvars import ContextVar 1abcd
2from typing import Annotated, Any 1abcd
4import pytest 1abcd
5from fastapi import Depends, FastAPI, WebSocket 1abcd
6from fastapi.exceptions import FastAPIError 1abcd
7from fastapi.testclient import TestClient 1abcd
9global_context: ContextVar[dict[str, Any]] = ContextVar("global_context", default={}) # noqa: B039 1abcd
12class Session: 1abcd
13 def __init__(self) -> None: 1abcd
14 self.open = True 1qhkrensiltfoujmvgp
17async def dep_session() -> Any: 1abcd
18 s = Session() 1qhkrensiltfoujmvgp
19 yield s 1qhkrensiltfoujmvgp
20 s.open = False 1qhkrensiltfoujmvgp
21 global_state = global_context.get() 1qhkrensiltfoujmvgp
22 global_state["session_closed"] = True 1qhkrensiltfoujmvgp
25SessionFuncDep = Annotated[Session, Depends(dep_session, scope="function")] 1abcd
26SessionRequestDep = Annotated[Session, Depends(dep_session, scope="request")] 1abcd
27SessionDefaultDep = Annotated[Session, Depends(dep_session)] 1abcd
30class NamedSession: 1abcd
31 def __init__(self, name: str = "default") -> None: 1abcd
32 self.name = name 1hkeilfjmg
33 self.open = True 1hkeilfjmg
36def get_named_session(session: SessionRequestDep, session_b: SessionDefaultDep) -> Any: 1abcd
37 assert session is session_b 1efg
38 named_session = NamedSession(name="named") 1efg
39 yield named_session, session_b 1efg
40 named_session.open = False 1efg
41 global_state = global_context.get() 1efg
42 global_state["named_session_closed"] = True 1efg
45NamedSessionsDep = Annotated[tuple[NamedSession, Session], Depends(get_named_session)] 1abcd
48def get_named_func_session(session: SessionFuncDep) -> Any: 1abcd
49 named_session = NamedSession(name="named") 1hij
50 yield named_session, session 1hij
51 named_session.open = False 1hij
52 global_state = global_context.get() 1hij
53 global_state["named_func_session_closed"] = True 1hij
56def get_named_regular_func_session(session: SessionFuncDep) -> Any: 1abcd
57 named_session = NamedSession(name="named") 1klm
58 return named_session, session 1klm
61BrokenSessionsDep = Annotated[ 1abcd
62 tuple[NamedSession, Session], Depends(get_named_func_session)
63]
64NamedSessionsFuncDep = Annotated[ 1abcd
65 tuple[NamedSession, Session], Depends(get_named_func_session, scope="function")
66]
68RegularSessionsDep = Annotated[ 1abcd
69 tuple[NamedSession, Session], Depends(get_named_regular_func_session)
70]
72app = FastAPI() 1abcd
75@app.websocket("/function-scope") 1abcd
76async def function_scope(websocket: WebSocket, session: SessionFuncDep) -> Any: 1abcd
77 await websocket.accept() 1qsu
78 await websocket.send_json({"is_open": session.open}) 1qsu
81@app.websocket("/request-scope") 1abcd
82async def request_scope(websocket: WebSocket, session: SessionRequestDep) -> Any: 1abcd
83 await websocket.accept() 1rtv
84 await websocket.send_json({"is_open": session.open}) 1rtv
87@app.websocket("/two-scopes") 1abcd
88async def get_stream_session( 1abcd
89 websocket: WebSocket,
90 function_session: SessionFuncDep,
91 request_session: SessionRequestDep,
92) -> Any:
93 await websocket.accept() 1nop
94 await websocket.send_json( 1nop
95 {"func_is_open": function_session.open, "req_is_open": request_session.open}
96 )
99@app.websocket("/sub") 1abcd
100async def get_sub(websocket: WebSocket, sessions: NamedSessionsDep) -> Any: 1abcd
101 await websocket.accept() 1efg
102 await websocket.send_json( 1efg
103 {"named_session_open": sessions[0].open, "session_open": sessions[1].open}
104 )
107@app.websocket("/named-function-scope") 1abcd
108async def get_named_function_scope( 1abcd
109 websocket: WebSocket, sessions: NamedSessionsFuncDep
110) -> Any:
111 await websocket.accept() 1hij
112 await websocket.send_json( 1hij
113 {"named_session_open": sessions[0].open, "session_open": sessions[1].open}
114 )
117@app.websocket("/regular-function-scope") 1abcd
118async def get_regular_function_scope( 1abcd
119 websocket: WebSocket, sessions: RegularSessionsDep
120) -> Any:
121 await websocket.accept() 1klm
122 await websocket.send_json( 1klm
123 {"named_session_open": sessions[0].open, "session_open": sessions[1].open}
124 )
127client = TestClient(app) 1abcd
130def test_function_scope() -> None: 1abcd
131 global_context.set({}) 1qsu
132 global_state = global_context.get() 1qsu
133 with client.websocket_connect("/function-scope") as websocket: 1qsu
134 data = websocket.receive_json() 1qsu
135 assert data["is_open"] is True 1qsu
136 assert global_state["session_closed"] is True 1qsu
139def test_request_scope() -> None: 1abcd
140 global_context.set({}) 1rtv
141 global_state = global_context.get() 1rtv
142 with client.websocket_connect("/request-scope") as websocket: 1rtv
143 data = websocket.receive_json() 1rtv
144 assert data["is_open"] is True 1rtv
145 assert global_state["session_closed"] is True 1rtv
148def test_two_scopes() -> None: 1abcd
149 global_context.set({}) 1nop
150 global_state = global_context.get() 1nop
151 with client.websocket_connect("/two-scopes") as websocket: 1nop
152 data = websocket.receive_json() 1nop
153 assert data["func_is_open"] is True 1nop
154 assert data["req_is_open"] is True 1nop
155 assert global_state["session_closed"] is True 1nop
158def test_sub() -> None: 1abcd
159 global_context.set({}) 1efg
160 global_state = global_context.get() 1efg
161 with client.websocket_connect("/sub") as websocket: 1efg
162 data = websocket.receive_json() 1efg
163 assert data["named_session_open"] is True 1efg
164 assert data["session_open"] is True 1efg
165 assert global_state["session_closed"] is True 1efg
166 assert global_state["named_session_closed"] is True 1efg
169def test_broken_scope() -> None: 1abcd
170 with pytest.raises( 1wxy
171 FastAPIError,
172 match='The dependency "get_named_func_session" has a scope of "request", it cannot depend on dependencies with scope "function"',
173 ):
175 @app.websocket("/broken-scope") 1wxy
176 async def get_broken( 1wxy
177 websocket: WebSocket, sessions: BrokenSessionsDep 1wxy
178 ) -> Any: # pragma: no cover 1wxy
179 pass
182def test_named_function_scope() -> None: 1abcd
183 global_context.set({}) 1hij
184 global_state = global_context.get() 1hij
185 with client.websocket_connect("/named-function-scope") as websocket: 1hij
186 data = websocket.receive_json() 1hij
187 assert data["named_session_open"] is True 1hij
188 assert data["session_open"] is True 1hij
189 assert global_state["session_closed"] is True 1hij
190 assert global_state["named_func_session_closed"] is True 1hij
193def test_regular_function_scope() -> None: 1abcd
194 global_context.set({}) 1klm
195 global_state = global_context.get() 1klm
196 with client.websocket_connect("/regular-function-scope") as websocket: 1klm
197 data = websocket.receive_json() 1klm
198 assert data["named_session_open"] is True 1klm
199 assert data["session_open"] is True 1klm
200 assert global_state["session_closed"] is True 1klm