MCPcopy Create free account
hub / github.com/pallets/quart / ASGIWebsocketConnection

Class ASGIWebsocketConnection

src/quart/asgi.py:179–351  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

177
178
179class ASGIWebsocketConnection:
180 def __init__(self, app: Quart, scope: WebsocketScope) -> None:
181 self.app = app
182 self.scope = scope
183 self.queue: asyncio.Queue = asyncio.Queue()
184 self._accepted = False
185 self._closed = False
186
187 async def __call__(
188 self, receive: ASGIReceiveCallable, send: ASGISendCallable
189 ) -> None:
190 websocket = self._create_websocket_from_scope(send)
191 receiver_task = asyncio.ensure_future(self.handle_messages(receive))
192 handler_task = asyncio.ensure_future(self.handle_websocket(websocket, send))
193 done, pending = await asyncio.wait(
194 [handler_task, receiver_task], return_when=asyncio.FIRST_COMPLETED
195 )
196 await cancel_tasks(pending)
197 raise_task_exceptions(done)
198
199 async def handle_messages(self, receive: ASGIReceiveCallable) -> None:
200 while True:
201 event = await receive()
202 if event["type"] == "websocket.receive":
203 message = event.get("bytes") or event["text"]
204 await websocket_received.send_async(message)
205 await self.queue.put(message)
206 elif event["type"] == "websocket.disconnect":
207 return
208
209 def _create_websocket_from_scope(self, send: ASGISendCallable) -> Websocket:
210 headers = Headers()
211 headers["Remote-Addr"] = (self.scope.get("client") or ["<local>"])[0]
212 for name, value in self.scope["headers"]:
213 headers.add(name.decode("latin1").title(), value.decode("latin1"))
214
215 path = self.scope["path"]
216 path = path if path[0] == "/" else urlparse(path).path
217 root_path = self.scope.get("root_path", "")
218 if root_path != "":
219 try:
220 path = path.split(root_path, 1)[1]
221 path = " " if path == "" else path
222 except IndexError:
223 path = " " # Invalid in paths, hence will result in 404
224
225 return self.app.websocket_class(
226 path,
227 self.scope["query_string"],
228 self.scope["scheme"],
229 headers,
230 self.scope.get("root_path", ""),
231 self.scope.get("http_version", "1.1"),
232 list(self.scope.get("subprotocols", [])),
233 self.queue.get,
234 partial(self.send_data, send),
235 partial(self.accept_connection, send),
236 partial(self.close_connection, send),

Calls

no outgoing calls

Used in the wild real call sites across dependent graphs

searching dependent graphs…