diff --git a/README.rst b/README.rst index 93d7f94e..f09325ec 100644 --- a/README.rst +++ b/README.rst @@ -71,7 +71,8 @@ pythonic API to write self contained views. return html - app.run(port=8080) + if __name__ == '__main__': + app.run(port=8080, live_reload=True) **More information:** `Getting Started `_ diff --git a/bin/lona b/bin/lona index f79ba4d9..63e1489e 100755 --- a/bin/lona +++ b/bin/lona @@ -5,4 +5,5 @@ import sys from lona.command_line.handle_command_line import handle_command_line -handle_command_line(sys.argv) +if __name__ == '__main__': + handle_command_line(sys.argv) diff --git a/doc/content/api-reference/frontends.rst b/doc/content/api-reference/frontends.rst index 93496c50..d78cc12b 100644 --- a/doc/content/api-reference/frontends.rst +++ b/doc/content/api-reference/frontends.rst @@ -34,36 +34,7 @@ The default frontend template includes ``lona/style.css`` which can be overridden. .. code-block:: html - - - - - - {{ Lona.load_stylesheets() }} - - - - {% include "lona/header.html" %} -
- {% include "lona/footer.html" %} - {{ Lona.load_scripts() }} - - - - + :include: ../../../lona/templates/lona/frontend.html Loading static files diff --git a/doc/content/api-reference/getting-started.rst b/doc/content/api-reference/getting-started.rst index 42d3e4ff..5f4748cf 100644 --- a/doc/content/api-reference/getting-started.rst +++ b/doc/content/api-reference/getting-started.rst @@ -44,7 +44,8 @@ python script. self.sleep(1) - app.run(port=8080) + if __name__ == '__main__': + app.run(port=8080) **More information:** {{ link('api-reference/lona-scripts.rst', 'Lona Scripts') }} diff --git a/doc/content/api-reference/lona-scripts.rst b/doc/content/api-reference/lona-scripts.rst index 7186e589..528c2f57 100644 --- a/doc/content/api-reference/lona-scripts.rst +++ b/doc/content/api-reference/lona-scripts.rst @@ -39,7 +39,8 @@ python script. self.sleep(1) - app.run() + if __name__ == '__main__': + app.run() Command Line Arguments @@ -125,7 +126,8 @@ Views can be added by using the ``LonaApp.route()`` decorator or by setting return H1('Hello World') - app.run() + if __name__ == '__main__': + app.run() Setting The Frontend View @@ -269,4 +271,5 @@ Custom error views can be set using the decorators ``LonaApp.error_403_view``, return '500: Internal Error' - app.run() + if __name__ == '__main__': + app.run() diff --git a/doc/content/api-reference/settings.rst b/doc/content/api-reference/settings.rst index 4cc89e23..d0d4480f 100644 --- a/doc/content/api-reference/settings.rst +++ b/doc/content/api-reference/settings.rst @@ -134,6 +134,19 @@ Client :name: CLIENT_DEBUG :path: lona.default_settings.CLIENT_DEBUG +.. setting:: + :name: CLIENT_AUTO_RECONNECT + :path: lona.default_settings.CLIENT_AUTO_RECONNECT + + When set to ``True`` the client will try to reconnect to the server + periodically when the websocket connection closes + +.. setting:: + :name: CLIENT_AUTO_RECONNECT_TIMEOUT + :path: lona.default_settings.CLIENT_AUTO_RECONNECT_TIMEOUT + + Auto reconnect timeout in ms + .. setting:: :name: CLIENT_VIEW_START_TIMEOUT :path: lona.default_settings.CLIENT_VIEW_START_TIMEOUT @@ -344,4 +357,4 @@ Feature Flags When ``settings.USE_FUTURE_NODE_CLASSES`` is set to ``True``: - 1. ``lona.html.Select2`` gets used instead of ``lona.html.Select`` \ No newline at end of file + 1. ``lona.html.Select2`` gets used instead of ``lona.html.Select`` diff --git a/doc/content/contrib/chartjs/index.rst b/doc/content/contrib/chartjs/index.rst index ccbd4df2..2e0eef84 100644 --- a/doc/content/contrib/chartjs/index.rst +++ b/doc/content/contrib/chartjs/index.rst @@ -93,4 +93,5 @@ your view. self.show(html) - app.run() + if __name__ == '__main__': + app.run() diff --git a/doc/content/cookbook/auto-reconnect.rst b/doc/content/cookbook/auto-reconnect.rst deleted file mode 100644 index a2f488b4..00000000 --- a/doc/content/cookbook/auto-reconnect.rst +++ /dev/null @@ -1,57 +0,0 @@ - - -Auto-Reconnect -============== - -For development or kiosk applications it can be useful to have a frontend that -reconnects automatically when the server restarts. - -This example implements a simple clock that updates the current time once per -second. The script adds a simple snipped to the frontend, which uses the -`server disconnect hook `_ -to try to reconnect the Lona client once per second, when the server restarts. - - -.. code-block:: python - - from datetime import datetime - - from lona import LonaApp, LonaView - from lona.html import HTML, H1, P - - app = LonaApp(__file__) - - - @app.route('/') - class MyLonaView(LonaView): - def handle_request(self, request): - timestamp = P() - - html = HTML( - H1('Clock'), - timestamp, - ) - - while True: - timestamp.set_text(str(datetime.now())) - - self.show(html) - - self.sleep(1) - - - app.add_template('lona/frontend.js', """ - lona_context.add_disconnect_hook(function(lona_context, event) { - document.querySelector('#lona').innerHTML = ` - Server disconnected
Trying to reconnect... - `; - - setTimeout(function() { - lona_context.reconnect(); - - }, 1000); - }); - """) - - - app.run(port=8080) diff --git a/doc/content/demos/bootstrap-5-confirmation-popup/bootstrap-5-confirmation-popup.py b/doc/content/demos/bootstrap-5-confirmation-popup/bootstrap-5-confirmation-popup.py index fd09154d..f1105e52 100644 --- a/doc/content/demos/bootstrap-5-confirmation-popup/bootstrap-5-confirmation-popup.py +++ b/doc/content/demos/bootstrap-5-confirmation-popup/bootstrap-5-confirmation-popup.py @@ -134,4 +134,5 @@ def handle_request(self, request): return self.html -app.run(port=8080) +if __name__ == '__main__': + app.run(port=8080) diff --git a/doc/content/demos/channels/demo.py b/doc/content/demos/channels/demo.py index 696df3f3..44a08f56 100644 --- a/doc/content/demos/channels/demo.py +++ b/doc/content/demos/channels/demo.py @@ -93,4 +93,5 @@ def on_cleanup(self): Channel('clock.leave').send() -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/demos/counter/counter.py b/doc/content/demos/counter/counter.py index 2df43b0c..8bbe86ce 100644 --- a/doc/content/demos/counter/counter.py +++ b/doc/content/demos/counter/counter.py @@ -42,4 +42,5 @@ def handle_request(self, request): ) -app.run(port=8080) +if __name__ == '__main__': + app.run(port=8080) diff --git a/doc/content/demos/daemonized-view/daemonized-view.py b/doc/content/demos/daemonized-view/daemonized-view.py index 61736019..6a9014c7 100644 --- a/doc/content/demos/daemonized-view/daemonized-view.py +++ b/doc/content/demos/daemonized-view/daemonized-view.py @@ -61,4 +61,5 @@ def handle_request(self, request): points.pop(0) -app.run(port=8080) +if __name__ == '__main__': + app.run(port=8080) diff --git a/doc/content/demos/function-plotter/function-plotter.py b/doc/content/demos/function-plotter/function-plotter.py index 83c5a107..87e6bda9 100644 --- a/doc/content/demos/function-plotter/function-plotter.py +++ b/doc/content/demos/function-plotter/function-plotter.py @@ -171,4 +171,5 @@ def handle_text_input_change(self, input_event): self.chart.data = CHART_DATA -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/demos/game-of-life/game-of-life.py b/doc/content/demos/game-of-life/game-of-life.py index 6730acc9..00ac59da 100644 --- a/doc/content/demos/game-of-life/game-of-life.py +++ b/doc/content/demos/game-of-life/game-of-life.py @@ -276,4 +276,5 @@ def handle_request(self, request): self.enable_controls() -app.run(port=8080) +if __name__ == '__main__': + app.run(port=8080) diff --git a/doc/content/demos/multi-user-chat/demo.py b/doc/content/demos/multi-user-chat/demo.py index 27ad38dc..ea44b9c1 100644 --- a/doc/content/demos/multi-user-chat/demo.py +++ b/doc/content/demos/multi-user-chat/demo.py @@ -329,4 +329,5 @@ def handle_request(self, request): return self.html -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/demos/styled-qr-code-generator/example_make_qr.py b/doc/content/demos/styled-qr-code-generator/example_make_qr.py index 51596f1d..793ef101 100644 --- a/doc/content/demos/styled-qr-code-generator/example_make_qr.py +++ b/doc/content/demos/styled-qr-code-generator/example_make_qr.py @@ -116,4 +116,5 @@ def handle_request(self, request): ) -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/deployment/deploying-on-linux.rst b/doc/content/deployment/deploying-on-linux.rst index 680a4df0..e3ab01ed 100644 --- a/doc/content/deployment/deploying-on-linux.rst +++ b/doc/content/deployment/deploying-on-linux.rst @@ -72,7 +72,8 @@ Lona return html - app.run(port=8080) + if __name__ == '__main__': + app.run(port=8080) Apache2 diff --git a/doc/content/deployment/hello-world.py b/doc/content/deployment/hello-world.py index e1a0eb8d..2cc6cbcb 100644 --- a/doc/content/deployment/hello-world.py +++ b/doc/content/deployment/hello-world.py @@ -22,4 +22,5 @@ def handle_request(self, request): ) -app.run(host='0.0.0.0', port=8080) +if __name__ == '__main__': + app.run(host='0.0.0.0', port=8080) diff --git a/doc/content/faq.rst b/doc/content/faq.rst index 97ed9b47..917e91c6 100644 --- a/doc/content/faq.rst +++ b/doc/content/faq.rst @@ -72,23 +72,3 @@ he had to add ~20 lines of extra Python code. Web is a very powerful tool for visualization and interaction. Python is a powerful tool for an unlimited range of tasks. Lona tries to bridge this gap and is designed to be very accessible and good for rapid prototyping. - - -Why has Lona no live-reload feature like aiohttp-devtools? ----------------------------------------------------------- - -**fscherf:** Early versions of Lona had such a feature, but it got removed due -bad user experience: Reloading your view helps when the view is fully self -contained, but when it uses widgets or helper functions from another module, -things become inconsistent. - -To make that a reliable feature you would have to maintain a list of all loaded -files and directories and track changes, file removes and addition of new -files. And you would have to maintain this list between restarts, to not miss -events, if files get changed fast after each other, like in a git rebase. - -Also people use different editors that save files at different times and -sometimes multiple times and/or periodically. - -It's hard to get this right, therefore I focused on making the server fast to -restart and easier to maintain. diff --git a/doc/content/index.rst b/doc/content/index.rst index 6259c9f0..89eb1b35 100644 --- a/doc/content/index.rst +++ b/doc/content/index.rst @@ -48,7 +48,8 @@ pythonic API to write self contained views. return html - app.run(port=8080) + if __name__ == '__main__': + app.run(port=8080) **More information:** {{ link('/tutorial/01-getting-started/index.rst', 'Getting Started') }} diff --git a/doc/content/tutorial/01-getting-started/example-1.py b/doc/content/tutorial/01-getting-started/example-1.py index a93b5cfe..33ba6ad1 100644 --- a/doc/content/tutorial/01-getting-started/example-1.py +++ b/doc/content/tutorial/01-getting-started/example-1.py @@ -6,4 +6,6 @@ install_picocss(app, debug=True) -app.run() \ No newline at end of file + +if __name__ == '__main__': + app.run(port=8080, live_reload=True) diff --git a/doc/content/tutorial/01-getting-started/example-2.py b/doc/content/tutorial/01-getting-started/example-2.py index b1fada0f..81444d16 100644 --- a/doc/content/tutorial/01-getting-started/example-2.py +++ b/doc/content/tutorial/01-getting-started/example-2.py @@ -17,4 +17,5 @@ def handle_request(self, request): ) -app.run() +if __name__ == '__main__': + app.run(port=8080, live_reload=True) diff --git a/doc/content/tutorial/01-getting-started/example-3.py b/doc/content/tutorial/01-getting-started/example-3.py index a89d4174..c390550e 100644 --- a/doc/content/tutorial/01-getting-started/example-3.py +++ b/doc/content/tutorial/01-getting-started/example-3.py @@ -25,5 +25,5 @@ def handle_request(self, request): ) -app.run() - +if __name__ == '__main__': + app.run(port=8080, live_reload=True) diff --git a/doc/content/tutorial/01-getting-started/index.rst b/doc/content/tutorial/01-getting-started/index.rst index 73c2b162..28e76bfd 100644 --- a/doc/content/tutorial/01-getting-started/index.rst +++ b/doc/content/tutorial/01-getting-started/index.rst @@ -91,8 +91,7 @@ app, like template paths, static directories or routes, will be relative to this directory. The last line of the script (``app.run()``), will run the application server, -and block until ``CTRL-C`` was hit. - +and block until ``CTRL-C`` was hit. Run the script using: .. code-block:: @@ -105,6 +104,9 @@ If port 8080 is taken by another application, you can set environment variable ``LONA_DEFAULT_PORT`` to some other port, affecting all examples that do not set the port explicitly. +When ``live_reload`` is set to ``True`` Lona will watch the scripts project +root and restart the server when a file in it gets written. + The script should print that it opened a webserver on ``http://localhost:8080``. If you navigate your browser there, you should see this: diff --git a/doc/content/tutorial/02-html/example-1.py b/doc/content/tutorial/02-html/example-1.py index 31761166..faeedfae 100644 --- a/doc/content/tutorial/02-html/example-1.py +++ b/doc/content/tutorial/02-html/example-1.py @@ -24,4 +24,5 @@ def handle_request(self, request): return html -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/02-html/example-2.py b/doc/content/tutorial/02-html/example-2.py index cbf16558..a4e782b6 100644 --- a/doc/content/tutorial/02-html/example-2.py +++ b/doc/content/tutorial/02-html/example-2.py @@ -35,4 +35,5 @@ def handle_request(self, request): self.sleep(1) -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/02-html/example-3.py b/doc/content/tutorial/02-html/example-3.py index 2e5d158f..ebab3d17 100644 --- a/doc/content/tutorial/02-html/example-3.py +++ b/doc/content/tutorial/02-html/example-3.py @@ -72,4 +72,5 @@ def handle_request(self, request): current_color += 1 -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/03-events/example-1.py b/doc/content/tutorial/03-events/example-1.py index 50c26c3f..cba2e4be 100644 --- a/doc/content/tutorial/03-events/example-1.py +++ b/doc/content/tutorial/03-events/example-1.py @@ -28,4 +28,5 @@ def handle_request(self, request): ) -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/03-events/example-2.py b/doc/content/tutorial/03-events/example-2.py index bbe23410..34f72d9f 100644 --- a/doc/content/tutorial/03-events/example-2.py +++ b/doc/content/tutorial/03-events/example-2.py @@ -54,4 +54,5 @@ def handle_request(self, request): ) -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/03-events/example-3.py b/doc/content/tutorial/03-events/example-3.py index 979f4fc2..3dabb2c2 100644 --- a/doc/content/tutorial/03-events/example-3.py +++ b/doc/content/tutorial/03-events/example-3.py @@ -45,4 +45,6 @@ def handle_request(self, request): P(f'{first_number} + {second_number} = {first_number+second_number}') ) -app.run() + +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/04-user-input/example-1.py b/doc/content/tutorial/04-user-input/example-1.py index 8f5adf8f..ab395e71 100644 --- a/doc/content/tutorial/04-user-input/example-1.py +++ b/doc/content/tutorial/04-user-input/example-1.py @@ -33,4 +33,5 @@ def handle_request(self, request): self.show(self.html) -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/05-routing/example-1.py b/doc/content/tutorial/05-routing/example-1.py index 5431ad95..6c319226 100644 --- a/doc/content/tutorial/05-routing/example-1.py +++ b/doc/content/tutorial/05-routing/example-1.py @@ -45,4 +45,5 @@ def handle_request(self, request): ) -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/05-routing/example-2.py b/doc/content/tutorial/05-routing/example-2.py index 03575ca4..c8e10662 100644 --- a/doc/content/tutorial/05-routing/example-2.py +++ b/doc/content/tutorial/05-routing/example-2.py @@ -41,4 +41,5 @@ def handle_request(self, request): ) -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/06-responses/index.rst b/doc/content/tutorial/06-responses/index.rst index a6ee62bd..c271dc28 100644 --- a/doc/content/tutorial/06-responses/index.rst +++ b/doc/content/tutorial/06-responses/index.rst @@ -32,7 +32,8 @@ traditional views, like JSON-APIs for example: ) - app.run() + if __name__ == '__main__': + app.run() Lona responses can be used for redirects, HTTP-redirects, to return JSON or binary data. diff --git a/doc/content/tutorial/07-daemon-views/example-1.py b/doc/content/tutorial/07-daemon-views/example-1.py index 2eb695b0..5475ec75 100644 --- a/doc/content/tutorial/07-daemon-views/example-1.py +++ b/doc/content/tutorial/07-daemon-views/example-1.py @@ -41,4 +41,5 @@ def handle_request(self, request): return self.html -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/07-daemon-views/example-2.py b/doc/content/tutorial/07-daemon-views/example-2.py index 3f9dbd50..ecc956ff 100644 --- a/doc/content/tutorial/07-daemon-views/example-2.py +++ b/doc/content/tutorial/07-daemon-views/example-2.py @@ -115,4 +115,5 @@ def handle_request(self, request): return self.html -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/08-channels/example.py b/doc/content/tutorial/08-channels/example.py index 191183dc..0c5b5a46 100644 --- a/doc/content/tutorial/08-channels/example.py +++ b/doc/content/tutorial/08-channels/example.py @@ -54,4 +54,5 @@ def handle_request(self, request): return self.html -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/09-state/index.rst b/doc/content/tutorial/09-state/index.rst index 5779fb36..63f0985a 100644 --- a/doc/content/tutorial/09-state/index.rst +++ b/doc/content/tutorial/09-state/index.rst @@ -41,7 +41,8 @@ locking interface as `HTML nodes `_. ) - app.run() + if __name__ == '__main__': + app.run() Node State @@ -104,7 +105,8 @@ browser-side data in one transaction. return html - app.run() + if __name__ == '__main__': + app.run() .. rst-buttons:: diff --git a/doc/content/tutorial/10-middlewares/example-1.py b/doc/content/tutorial/10-middlewares/example-1.py index 0366f15f..32677298 100644 --- a/doc/content/tutorial/10-middlewares/example-1.py +++ b/doc/content/tutorial/10-middlewares/example-1.py @@ -36,4 +36,5 @@ def handle_request(self, request): ) -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/11-static-files/example-1.py b/doc/content/tutorial/11-static-files/example-1.py index 3eb13bed..24762a3d 100644 --- a/doc/content/tutorial/11-static-files/example-1.py +++ b/doc/content/tutorial/11-static-files/example-1.py @@ -38,5 +38,5 @@ def handle_request(self, request): ) -app.run() - +if __name__ == '__main__': + app.run() diff --git a/doc/content/tutorial/12-widgets/example-1.py b/doc/content/tutorial/12-widgets/example-1.py index d59bd08a..94679a8a 100644 --- a/doc/content/tutorial/12-widgets/example-1.py +++ b/doc/content/tutorial/12-widgets/example-1.py @@ -111,4 +111,5 @@ def handle_request(self, request): ) -app.run() +if __name__ == '__main__': + app.run() diff --git a/doc/settings.py b/doc/settings.py index aa194c7d..1450aba2 100644 --- a/doc/settings.py +++ b/doc/settings.py @@ -103,7 +103,6 @@ ['Writing A Traditional Form', 'cookbook/writing-a-traditional-form.rst'], - ['Auto-Reconnect', 'cookbook/auto-reconnect.rst'], ['URL Reverse Resolving', 'cookbook/url-reverse-resolving.rst'], ['Using Server State', 'cookbook/using-server-state.rst'], diff --git a/lona/app.py b/lona/app.py index ac5bec2d..feef0c0c 100644 --- a/lona/app.py +++ b/lona/app.py @@ -11,6 +11,7 @@ from typing_extensions import Literal from aiohttp.web import Application +from watchfiles import run_process from lona.command_line.run_server import run_server from lona.worker_pool import WorkerPool @@ -353,6 +354,11 @@ def parse_command_line(self) -> dict: type=int, ) + parser.add_argument( + '--live-reload', + action='store_true', + ) + parser.add_argument( '--shutdown-timeout', type=float, @@ -421,6 +427,18 @@ def setup_server( self.server._loop = loop self.server._worker_pool = worker_pool + def _run(self, loop, server_args): + self.setup_server( + loop=loop, + settings_pre_overrides=server_args.settings_pre_overrides, + settings_post_overrides=server_args.settings_post_overrides, + ) + + run_server( + args=server_args, + server=self.server, + ) + def run( self, loop: None | AbstractEventLoop = None, @@ -432,6 +450,7 @@ def run( server_args = Namespace( host=os.environ.get('LONA_DEFAULT_HOST', 'localhost'), port=os.environ.get('LONA_DEFAULT_PORT', '8080'), + live_reload=False, shell_server_url='', shutdown_timeout=0, log_level='info', @@ -454,18 +473,15 @@ def run( setup_logging(server_args) - # setup server - self.setup_server( - loop=loop, - settings_pre_overrides=server_args.settings_pre_overrides, - settings_post_overrides=server_args.settings_post_overrides, - ) + if server_args.live_reload: + run_process( + self.project_root, + target=self._run, + args=(loop, server_args), + ) - # start server - run_server( - args=server_args, - server=self.server, - ) + else: + self._run(loop, server_args) LonaApp = App # TODO: remove in 2.0 diff --git a/lona/command_line/handle_command_line.py b/lona/command_line/handle_command_line.py index 32d0c92d..772b73c4 100644 --- a/lona/command_line/handle_command_line.py +++ b/lona/command_line/handle_command_line.py @@ -2,6 +2,7 @@ import logging import os +from watchfiles import run_process from jinja2 import Environment from lona.command_line.collect_static import collect_static @@ -141,6 +142,11 @@ def handle_command_line(argv): default='', ) + parser_run_server.add_argument( + '--live-reload', + action='store_true', + ) + # collect-static ########################################################## parser_collect_static = sub_parsers.add_parser( 'collect-static', @@ -235,7 +241,15 @@ def handle_command_line(argv): # run if args.command == 'run-server': - run_server(args) + if args.live_reload: + run_process( + args.project_root, + target=run_server, + args=(args, ), + ) + + else: + run_server(args) elif args.command == 'collect-static': collect_static(args) diff --git a/lona/command_line/run_server.py b/lona/command_line/run_server.py index be9e5f50..33c8a099 100644 --- a/lona/command_line/run_server.py +++ b/lona/command_line/run_server.py @@ -49,6 +49,9 @@ async def shutdown(app): server._worker_pool = worker_pool # run server + if args.live_reload: + logger.warning('live-reload is enabled') + if args.shell: async def start_shell(server): def _start_shell(): diff --git a/lona/default_settings.py b/lona/default_settings.py index dee98f8e..4dfc8237 100644 --- a/lona/default_settings.py +++ b/lona/default_settings.py @@ -48,6 +48,8 @@ CLIENT_VIEW_START_TIMEOUT = 2 CLIENT_INPUT_EVENT_TIMEOUT = 2 CLIENT_PING_INTERVAL = 60 +CLIENT_AUTO_RECONNECT = True +CLIENT_AUTO_RECONNECT_TIMEOUT = 1000 # sessions diff --git a/lona/templates/lona/disconnect-message.html b/lona/templates/lona/disconnect-message.html new file mode 100644 index 00000000..5b9084eb --- /dev/null +++ b/lona/templates/lona/disconnect-message.html @@ -0,0 +1,4 @@ +

Server Disconnected

+{% if Lona.settings.CLIENT_AUTO_RECONNECT %} + Trying to reconnect... +{% endif %} diff --git a/lona/templates/lona/frontend.html b/lona/templates/lona/frontend.html index 2d1ac26a..31d5cd0e 100644 --- a/lona/templates/lona/frontend.html +++ b/lona/templates/lona/frontend.html @@ -1,3 +1,4 @@ + @@ -12,8 +13,8 @@ {% include "lona/footer.html" %} {{ Lona.load_scripts() }} diff --git a/lona/templates/lona/frontend.js b/lona/templates/lona/frontend.js index d2dc82d5..e69de29b 100644 --- a/lona/templates/lona/frontend.js +++ b/lona/templates/lona/frontend.js @@ -1,3 +0,0 @@ -lona_context.add_disconnect_hook(function(lona_context, event) { - document.querySelector('#lona').innerHTML = 'Server disconnected'; -}); diff --git a/lona/templates/lona/waiting-for-server-message.html b/lona/templates/lona/waiting-for-server-message.html new file mode 100644 index 00000000..822b970d --- /dev/null +++ b/lona/templates/lona/waiting-for-server-message.html @@ -0,0 +1 @@ +Waiting for Server... diff --git a/pyproject.toml b/pyproject.toml index ef239e60..693704d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ requires-python = ">=3.8" dependencies = [ 'aiohttp>=3,<4', + 'watchfiles', 'jinja2', 'rlpython', 'typing-extensions', diff --git a/test_project/Makefile b/test_project/Makefile index 504229ad..e2e237de 100644 --- a/test_project/Makefile +++ b/test_project/Makefile @@ -1,7 +1,7 @@ PYTHON=python3 PYTHON_VENV=env -LONA_SHELL_SERVER_URL=file://socket +LONA_SHELL_SERVER_URL=file://../socket LONA_DEFAULT_ARGS=--shell-server-url=$(LONA_SHELL_SERVER_URL) CLIENT_VERSION=2