1212
1313import orjson
1414from asgi_tools import ResponseText , ResponseWebSocket
15- from asgiref import typing as asgi_types
1615from asgiref .compatibility import guarantee_single_callable
1716from servestatic import ServeStaticASGI
1817from typing_extensions import Unpack
2322from reactpy .core .serve import serve_layout
2423from reactpy .executors .asgi .types import (
2524 AsgiApp ,
26- AsgiHttpApp ,
27- AsgiLifespanApp ,
28- AsgiWebsocketApp ,
25+ AsgiHttpReceive ,
26+ AsgiHttpScope ,
27+ AsgiHttpSend ,
28+ AsgiReceive ,
29+ AsgiScope ,
30+ AsgiSend ,
31+ AsgiV3App ,
32+ AsgiV3HttpApp ,
33+ AsgiV3LifespanApp ,
34+ AsgiV3WebsocketApp ,
2935 AsgiWebsocketReceive ,
36+ AsgiWebsocketScope ,
3037 AsgiWebsocketSend ,
3138)
3239from reactpy .executors .utils import check_path , import_components , process_settings
@@ -42,7 +49,7 @@ class ReactPyMiddleware:
4249
4350 def __init__ (
4451 self ,
45- app : asgi_types . ASGIApplication ,
52+ app : AsgiApp ,
4653 root_components : Iterable [str ],
4754 ** settings : Unpack [ReactPyConfig ],
4855 ) -> None :
@@ -80,12 +87,12 @@ def __init__(
8087 )
8188
8289 # User defined ASGI apps
83- self .extra_http_routes : dict [str , AsgiHttpApp ] = {}
84- self .extra_ws_routes : dict [str , AsgiWebsocketApp ] = {}
85- self .extra_lifespan_app : AsgiLifespanApp | None = None
90+ self .extra_http_routes : dict [str , AsgiV3HttpApp ] = {}
91+ self .extra_ws_routes : dict [str , AsgiV3WebsocketApp ] = {}
92+ self .extra_lifespan_app : AsgiV3LifespanApp | None = None
8693
8794 # Component attributes
88- self .asgi_app : asgi_types . ASGI3Application = guarantee_single_callable (app ) # type: ignore
95+ self .asgi_app : AsgiV3App = guarantee_single_callable (app ) # type: ignore
8996 self .root_components = import_components (root_components )
9097
9198 # Directory attributes
@@ -98,10 +105,7 @@ def __init__(
98105 self .web_modules_app = WebModuleApp (parent = self )
99106
100107 async def __call__ (
101- self ,
102- scope : asgi_types .Scope ,
103- receive : asgi_types .ASGIReceiveCallable ,
104- send : asgi_types .ASGISendCallable ,
108+ self , scope : AsgiScope , receive : AsgiReceive , send : AsgiSend
105109 ) -> None :
106110 """The ASGI entrypoint that determines whether ReactPy should route the
107111 request to ourselves or to the user application."""
@@ -125,16 +129,16 @@ async def __call__(
125129 # Serve the user's application
126130 await self .asgi_app (scope , receive , send )
127131
128- def match_dispatch_path (self , scope : asgi_types . WebSocketScope ) -> bool :
132+ def match_dispatch_path (self , scope : AsgiWebsocketScope ) -> bool :
129133 return bool (re .match (self .dispatcher_pattern , scope ["path" ]))
130134
131- def match_static_path (self , scope : asgi_types . HTTPScope ) -> bool :
135+ def match_static_path (self , scope : AsgiHttpScope ) -> bool :
132136 return scope ["path" ].startswith (self .static_path )
133137
134- def match_web_modules_path (self , scope : asgi_types . HTTPScope ) -> bool :
138+ def match_web_modules_path (self , scope : AsgiHttpScope ) -> bool :
135139 return scope ["path" ].startswith (self .web_modules_path )
136140
137- def match_extra_paths (self , scope : asgi_types . Scope ) -> AsgiApp | None :
141+ def match_extra_paths (self , scope : AsgiScope ) -> AsgiApp | None :
138142 # Custom defined routes are unused by default to encourage users to handle
139143 # routing within their ASGI framework of choice.
140144 return None
@@ -146,13 +150,13 @@ class ComponentDispatchApp:
146150
147151 async def __call__ (
148152 self ,
149- scope : asgi_types . WebSocketScope ,
150- receive : asgi_types . ASGIReceiveCallable ,
151- send : asgi_types . ASGISendCallable ,
153+ scope : AsgiWebsocketScope ,
154+ receive : AsgiWebsocketReceive ,
155+ send : AsgiWebsocketSend ,
152156 ) -> None :
153157 """ASGI app for rendering ReactPy Python components."""
154158 # Start a loop that handles ASGI websocket events
155- async with ReactPyWebsocket (scope , receive , send , parent = self .parent ) as ws : # type: ignore
159+ async with ReactPyWebsocket (scope , receive , send , parent = self .parent ) as ws :
156160 while True :
157161 # Wait for the webserver to notify us of a new event
158162 event : dict [str , Any ] = await ws .receive (raw = True ) # type: ignore
@@ -175,7 +179,7 @@ async def __call__(
175179class ReactPyWebsocket (ResponseWebSocket ):
176180 def __init__ (
177181 self ,
178- scope : asgi_types . WebSocketScope ,
182+ scope : AsgiWebsocketScope ,
179183 receive : AsgiWebsocketReceive ,
180184 send : AsgiWebsocketSend ,
181185 parent : ReactPyMiddleware ,
@@ -250,10 +254,7 @@ class StaticFileApp:
250254 _static_file_server : ServeStaticASGI | None = None
251255
252256 async def __call__ (
253- self ,
254- scope : asgi_types .HTTPScope ,
255- receive : asgi_types .ASGIReceiveCallable ,
256- send : asgi_types .ASGISendCallable ,
257+ self , scope : AsgiHttpScope , receive : AsgiHttpReceive , send : AsgiHttpSend
257258 ) -> None :
258259 """ASGI app for ReactPy static files."""
259260 if not self ._static_file_server :
@@ -272,10 +273,7 @@ class WebModuleApp:
272273 _static_file_server : ServeStaticASGI | None = None
273274
274275 async def __call__ (
275- self ,
276- scope : asgi_types .HTTPScope ,
277- receive : asgi_types .ASGIReceiveCallable ,
278- send : asgi_types .ASGISendCallable ,
276+ self , scope : AsgiHttpScope , receive : AsgiHttpReceive , send : AsgiHttpSend
279277 ) -> None :
280278 """ASGI app for ReactPy web modules."""
281279 if not self ._static_file_server :
@@ -291,10 +289,7 @@ async def __call__(
291289
292290class Error404App :
293291 async def __call__ (
294- self ,
295- scope : asgi_types .HTTPScope ,
296- receive : asgi_types .ASGIReceiveCallable ,
297- send : asgi_types .ASGISendCallable ,
292+ self , scope : AsgiScope , receive : AsgiReceive , send : AsgiSend
298293 ) -> None :
299294 response = ResponseText ("Resource not found on this server." , status_code = 404 )
300295 await response (scope , receive , send ) # type: ignore
0 commit comments