diff --git a/docs/source/conf.py b/docs/source/conf.py index d89165ff8..c813e7b71 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -225,7 +225,10 @@ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { "https://docs.python.org/": None, - "https://pyalect.readthedocs.io/en/latest": None, + "pyalect": ("https://pyalect.readthedocs.io/en/latest", None), + "sanic": ("https://sanic.readthedocs.io/en/latest/", None), + "tornado": ("https://www.tornadoweb.org/en/stable/", None), + "flask": ("https://flask.palletsprojects.com/en/1.1.x/", None), } # -- Options for todo extension ---------------------------------------------- diff --git a/docs/source/core-concepts.rst b/docs/source/core-concepts.rst index 90897f2aa..cfc237eff 100644 --- a/docs/source/core-concepts.rst +++ b/docs/source/core-concepts.rst @@ -170,25 +170,32 @@ Layout Server The :ref:`Dispatcher ` allows you to animate the layout, but we still need to get the models on the screen. One of the last steps in that journey is to send them over the wire. To do that you need an -:class:`~idom.server.base.AbstractRenderServer` implementation. Right now we have a -built in subclass that relies on :mod:`sanic`, an async enabled web server. In principle -though, the base server class is capable of working with any other async enabled server -framework. Potential candidates range from newer frameworks like -`vibora `__, `starlette `__, and -`aiohttp `__ to older ones that are -starting to add support for asyncio like -`tornado `__. +:class:`~idom.server.base.AbstractRenderServer` implementation. Presently, IDOM comes +with support for the following web servers: -.. note:: - If using or implementing a bridge between IDOM and these servers interests you post - an `issue `__. +- :class:`sanic.app.Sanic` (``pip install idom[sanic]``) + + - :class:`idom.server.sanic.PerClientStateServer` + + - :class:`idom.server.sanic.SharedClientStateServer` + +- :class:`flask.Flask` (``pip install idom[flask]``) -In the case of our :class:`~idom.server.sanic.SanicRenderServer` types we have one -implementation per built in :ref:`Dispatcher `: + - :class:`idom.server.flask.PerClientStateServer` -- :class:`idom.server.sanic.PerClientStateServer` +- :class:`tornado.web.Application` (``pip install idom[tornado]``) + + - :class:`idom.server.tornado.PerClientStateServer` + +However, in principle, the base server class is capable of working with any other async +enabled server framework. Potential candidates range from newer frameworks like +`vibora `__ and `starlette `__ to +`aiohttp `__. + +.. note:: -- :class:`idom.server.sanic.SharedClientStateServer` + If using or implementing a bridge between IDOM and an async server not listed here + interests you, post an `issue `__. The main thing to understand about server implementations is that they can function in two ways - as a standalone application or as an extension to an existing application. diff --git a/docs/source/package-api.rst b/docs/source/package-api.rst index 043eb0ccf..786daf3ec 100644 --- a/docs/source/package-api.rst +++ b/docs/source/package-api.rst @@ -46,6 +46,20 @@ Sanic Servers :members: +Flask Servers +------------- + +.. automodule:: idom.server.flask + :members: + + +Tornado Servers +--------------- + +.. automodule:: idom.server.tornado + :members: + + HTML Widgets ------------ diff --git a/idom/server/flask.py b/idom/server/flask.py index 62c39c2b1..e83310e57 100644 --- a/idom/server/flask.py +++ b/idom/server/flask.py @@ -24,6 +24,8 @@ class Config(TypedDict, total=False): + """Render server config for :class:`FlaskRenderServer`""" + import_name: str url_prefix: str cors: Union[bool, Dict[str, Any]] @@ -161,6 +163,8 @@ def _generic_run_application( class PerClientStateServer(FlaskRenderServer): + """Each client view will have its own state.""" + _dispatcher_type = SingleViewDispatcher diff --git a/idom/server/sanic.py b/idom/server/sanic.py index 7fcf4b982..f143548d5 100644 --- a/idom/server/sanic.py +++ b/idom/server/sanic.py @@ -24,6 +24,8 @@ class Config(TypedDict, total=False): + """Config for :class:`SanicRenderServer`""" + cors: Union[bool, Dict[str, Any]] url_prefix: str server_static_files: bool diff --git a/idom/server/tornado.py b/idom/server/tornado.py index fbd836dd1..4d6c78c57 100644 --- a/idom/server/tornado.py +++ b/idom/server/tornado.py @@ -19,12 +19,15 @@ class Config(TypedDict): + """Render server config for :class:`TornadoRenderServer` subclasses""" + base_url: str serve_static_files: bool redirect_root_to_index: bool class TornadoRenderServer(AbstractRenderServer[Application, Config]): + """A base class for all Tornado render servers""" _model_stream_handler_type: Type[WebSocketHandler] @@ -117,6 +120,7 @@ def _run_application_in_thread( class PerClientStateModelStreamHandler(WebSocketHandler): + """A web-socket handler that serves up a new model stream to each new client""" _dispatcher_type: Type[AbstractDispatcher] = SingleViewDispatcher _dispatcher_inst: AbstractDispatcher @@ -155,4 +159,6 @@ def on_close(self): class PerClientStateServer(TornadoRenderServer): + """Each client view will have its own state.""" + _model_stream_handler_type = PerClientStateModelStreamHandler