55from asyncio import Queue as AsyncQueue
66from threading import Event as ThreadEvent , Thread
77from queue import Queue as ThreadQueue
8- from typing import Union , Tuple , Dict , Any , Optional , Callable , NamedTuple
8+ from typing import Union , Tuple , Dict , Any , Optional , Callable , NamedTuple , Type , cast
99
1010from typing_extensions import TypedDict
1111from flask import Flask , Blueprint , send_from_directory , redirect , url_for
1717
1818import idom
1919from idom .client .manage import BUILD_DIR
20- from idom .core .layout import LayoutEvent , Layout
20+ from idom .core .layout import LayoutEvent , Layout , LayoutUpdate
2121from idom .core .dispatcher import AbstractDispatcher , SingleViewDispatcher
2222
2323from .base import AbstractRenderServer
@@ -36,7 +36,7 @@ class Config(TypedDict, total=False):
3636class FlaskRenderServer (AbstractRenderServer [Flask , Config ]):
3737 """Base class for render servers which use Flask"""
3838
39- _dispatcher_type : AbstractDispatcher
39+ _dispatcher_type : Type [ AbstractDispatcher ]
4040 _wsgi_server : pywsgi .WSGIServer
4141
4242 def stop (self , timeout : Optional [float ] = None ) -> None :
@@ -56,10 +56,8 @@ def _create_config(self, config: Optional[Config]) -> Config:
5656 "cors" : False ,
5757 "serve_static_files" : True ,
5858 "redirect_root_to_index" : True ,
59+ ** (config or {}), # type: ignore
5960 }
60- if config is not None :
61- # BUG: https://github.com/python/mypy/issues/6462
62- new_config .update (config ) # type: ignore
6361 return new_config
6462
6563 def _default_application (self , config : Config ) -> Flask :
@@ -79,12 +77,12 @@ def _setup_application(self, config: Config, app: Flask) -> None:
7977
8078 sockets = Sockets (app )
8179
82- @sockets .route (urljoin (config ["url_prefix" ], "/stream" ))
80+ @sockets .route (urljoin (config ["url_prefix" ], "/stream" )) # type: ignore
8381 def model_stream (ws : WebSocket ) -> None :
8482 def send (value : Any ) -> None :
8583 ws .send (json .dumps (value ))
8684
87- def recv () -> LayoutEvent :
85+ def recv () -> Optional [ LayoutEvent ] :
8886 event = ws .receive ()
8987 if event is not None :
9088 return LayoutEvent (** json .loads (event ))
@@ -104,20 +102,20 @@ def _setup_blueprint_routes(self, config: Config, blueprint: Blueprint) -> None:
104102 if config ["serve_static_files" ]:
105103
106104 @blueprint .route ("/client/<path:path>" )
107- def send_build_dir (path ) :
105+ def send_build_dir (path : str ) -> Any :
108106 return send_from_directory (str (BUILD_DIR ), path )
109107
110108 if config ["redirect_root_to_index" ]:
111109
112110 @blueprint .route ("/" )
113- def redirect_to_index ():
111+ def redirect_to_index () -> Any :
114112 return redirect (url_for ("idom.send_build_dir" , path = "index.html" ))
115113
116114 def _setup_application_did_start_event (
117115 self , config : Config , app : Flask , event : ThreadEvent
118116 ) -> None :
119117 @app .before_first_request
120- def server_did_start ():
118+ def server_did_start () -> None :
121119 event .set ()
122120
123121 def _run_application (
@@ -149,8 +147,8 @@ def _generic_run_application(
149147 port : int = 5000 ,
150148 debug : bool = False ,
151149 * args : Any ,
152- ** kwargs ,
153- ):
150+ ** kwargs : Any ,
151+ ) -> None :
154152 if debug :
155153 logging .basicConfig (level = logging .DEBUG ) # pragma: no cover
156154 logging .debug ("Starting server..." )
@@ -180,20 +178,20 @@ def run_dispatcher_in_thread(
180178 dispatch_thread_info_created = ThreadEvent ()
181179 dispatch_thread_info_ref : idom .Ref [Optional [_DispatcherThreadInfo ]] = idom .Ref (None )
182180
183- def run_dispatcher ():
181+ def run_dispatcher () -> None :
184182 loop = asyncio .new_event_loop ()
185183 asyncio .set_event_loop (loop )
186184
187- thread_send_queue = ThreadQueue ()
188- async_recv_queue = AsyncQueue ()
185+ thread_send_queue : "ThreadQueue[LayoutUpdate]" = ThreadQueue ()
186+ async_recv_queue : "AsyncQueue[LayoutEvent]" = AsyncQueue ()
189187
190188 async def send_coro (value : Any ) -> None :
191189 thread_send_queue .put (value )
192190
193191 async def recv_coro () -> Any :
194192 return await async_recv_queue .get ()
195193
196- async def main ():
194+ async def main () -> None :
197195 async with make_dispatcher () as dispatcher :
198196 await dispatcher .run (send_coro , recv_coro , context )
199197
@@ -212,12 +210,12 @@ async def main():
212210 Thread (target = run_dispatcher , daemon = True ).start ()
213211
214212 dispatch_thread_info_created .wait ()
215- dispatch_thread_info = dispatch_thread_info_ref .current
213+ dispatch_thread_info = cast ( _DispatcherThreadInfo , dispatch_thread_info_ref .current )
216214 assert dispatch_thread_info is not None
217215
218216 stop = ThreadEvent ()
219217
220- def run_send ():
218+ def run_send () -> None :
221219 while not stop .is_set ():
222220 send (dispatch_thread_info .thread_send_queue .get ())
223221
@@ -242,17 +240,19 @@ def run_send():
242240
243241class _DispatcherThreadInfo (NamedTuple ):
244242 dispatch_loop : asyncio .AbstractEventLoop
245- dispatch_future : asyncio .Future
246- thread_send_queue : ThreadQueue
247- async_recv_queue : AsyncQueue
243+ dispatch_future : " asyncio.Future[Any]"
244+ thread_send_queue : " ThreadQueue[LayoutUpdate]"
245+ async_recv_queue : " AsyncQueue[LayoutEvent]"
248246
249247
250- class _StartCallbackWSGIServer (pywsgi .WSGIServer ):
251- def __init__ (self , before_first_request : Callable [[], None ], * args , ** kwargs ):
248+ class _StartCallbackWSGIServer (pywsgi .WSGIServer ): # type: ignore
249+ def __init__ (
250+ self , before_first_request : Callable [[], None ], * args : Any , ** kwargs : Any
251+ ) -> None :
252252 self ._before_first_request_callback = before_first_request
253253 super ().__init__ (* args , ** kwargs )
254254
255- def update_environ (self ):
255+ def update_environ (self ) -> None :
256256 """
257257 Called before the first request is handled to fill in WSGI environment values.
258258
0 commit comments