K iddlmZddlZddlZddlZddlmZm Z m Z m Z ddl m Z ddlmZmZddlmZmZdd lmZmZmZgd ZGd d Zdddd  ddZ d ddZy)) annotationsN)Any AwaitableCallableLiteral)NotFound)MapRequestRedirect)RequestResponse)ServerServerConnectionserve)route unix_routeRouterc`eZdZdZ d d dZd dZd dZd dZ ddZddZ y)rz*WebSocket router supporting :func:`route`.Ncz||_||_||_|jjD] }d|_ y)NT)url_map server_name url_scheme iter_rules websocket)selfrrrrules _/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/websockets/asyncio/router.py__init__zRouter.__init__s=  &$LL++- "D!DN "cP|j|jdS|jS)NHost)rheaders)r connectionrequests rget_server_namezRouter.get_server_name!s)    #??6* *## #r c~|jtjjd|}||jd<|S)Nz Found at Location)respondhttp HTTPStatusFOUNDr#)rr$urlresponses rredirectzRouter.redirect's:%%doo&;&;y=NO'*$r cV|jtjjdS)Nz Not Found)r)r*r+ NOT_FOUNDrr$s r not_foundzRouter.not_found,s!!$//";";[IIr c|jj|j|||j} tj j |j}|j|j|j\}}||c|_|_y#t$r&}|j||jcYd}~Sd}~wt$r|j|cYSwxYw)zRoute incoming request.)rr) path_info query_argsN)rbindr&rurllibparseurlparsepathmatchqueryr r/new_urlrr3handlerhandler_kwargs)rr$r%url_map_adapterparsedr?kwargsr/s r route_requestzRouter.route_request/s,,++,,ZA,  .\\**7<<8F-33 ++!<<4OGV9@5 J5  ?==X-=-=> > .>>*- - .s$AB C&%CC&C&%C&cXK|j|fi|jd{S7w)zHandle a connection.N)r?r@r2s rr?zRouter.handlerDs*'Z'' Pj6O6OPPPPs !*(*)Nws)rr r str | NonerstrreturnNone)r$rr%r rIrH)r$rr-rHrIr )r$rrIr r$rr%r rIzResponse | None)r$rrIrJ) __name__ __module__ __qualname____doc__rr&r/r3rDr?r rrrsk4 #' " "  " "  "$  J*5< *Qr r)rssl create_routerc |dnd}|dur|||d<|t}|||| |jdd j}n d fd }t jg|d|i|S) a- Create a WebSocket server dispatching connections to different handlers. This feature requires the third-party library `werkzeug`_: .. code-block:: console $ pip install werkzeug .. _werkzeug: https://werkzeug.palletsprojects.com/ :func:`route` accepts the same arguments as :func:`~websockets.sync.server.serve`, except as described below. The first argument is a :class:`werkzeug.routing.Map` that maps URL patterns to connection handlers. In addition to the connection, handlers receive parameters captured in the URL as keyword arguments. Here's an example:: from websockets.asyncio.router import route from werkzeug.routing import Map, Rule async def channel_handler(websocket, channel_id): ... url_map = Map([ Rule("/channel/", endpoint=channel_handler), ... ]) # set this future to exit the server stop = asyncio.get_running_loop().create_future() async with route(url_map, ...) as server: await stop Refer to the documentation of :mod:`werkzeug.routing` for details. If you define redirects with ``Rule(..., redirect_to=...)`` in the URL map, when the server runs behind a reverse proxy that modifies the ``Host`` header or terminates TLS, you need additional configuration: * Set ``server_name`` to the name of the server as seen by clients. When not provided, websockets uses the value of the ``Host`` header. * Set ``ssl=True`` to generate ``wss://`` URIs without actually enabling TLS. Under the hood, this bind the URL map with a ``url_scheme`` of ``wss://`` instead of ``ws://``. There is no need to specify ``websocket=True`` in each rule. It is added automatically. Args: url_map: Mapping of URL patterns to connection handlers. server_name: Name of the server as seen by clients. If :obj:`None`, websockets uses the value of the ``Host`` header. ssl: Configuration for enabling TLS on the connection. Set it to :obj:`True` if a reverse proxy terminates TLS connections. create_router: Factory for the :class:`Router` dispatching requests to handlers. Set it to a wrapper or a subclass to customize routing. NrFwssTrQprocess_requestcK||}t|tr |d{}||Sj||S7wN) isinstancerrD)r$r%r._process_requestrouters rrUzroute..process_requestsI( G#'' G< <*s ?=?rK)rpoprDrr?) rrrQrRargsrCrrUrYrZs @@rrrIsR%J $3?u  7K ris" 44(1&33 ,4Q4Qt#8<)- jS jS jSjS 6 jS ' jS  jSjS^: : :: :r