diff --git a/CHANGELOG.md b/CHANGELOG.md index d973c4a2..8a3dd497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change log +### v0.15.2 +* Adds `register_eel_routes` to handle applying Eel routes to non-Bottle custom app instances. + ### v0.15.1 * Bump bottle dependency from 0.12.13 to 0.12.20 to address the critical CVE-2022-31799 and moderate CVE-2020-28473. diff --git a/README.md b/README.md index 9d6d1480..4ebc0a11 100644 --- a/README.md +++ b/README.md @@ -116,8 +116,7 @@ As of Eel v0.12.0, the following options are available to `start()`: - **position**, a tuple of ints specifying the (left, top) of the main window in pixels *Default: `None`* - **geometry**, a dictionary specifying the size and position for all windows. The keys should be the relative path of the page, and the values should be a dictionary of the form `{'size': (200, 100), 'position': (300, 50)}`. *Default: {}* - **close_callback**, a lambda or function that is called when a websocket to a window closes (i.e. when the user closes the window). It should take two arguments; a string which is the relative path of the page that just closed, and a list of other websockets that are still open. *Default: `None`* - - **app**, an instance of Bottle which will be used rather than creating a fresh one. This can be used to install middleware on the - instance before starting eel, e.g. for session management, authentication, etc. + - **app**, an instance of Bottle which will be used rather than creating a fresh one. This can be used to install middleware on the instance before starting eel, e.g. for session management, authentication, etc. If your `app` is not a Bottle instance, you will need to call `eel.register_eel_routes(app)` on your custom app instance. - **shutdown_delay**, timer configurable for Eel's shutdown detection mechanism, whereby when any websocket closes, it waits `shutdown_delay` seconds, and then checks if there are now any websocket connections. If not, then Eel closes. In case the user has closed the browser and wants to exit the program. By default, the value of **shutdown_delay** is `1.0` second diff --git a/eel/__init__.py b/eel/__init__.py index 1f9d8bf4..898f1da0 100644 --- a/eel/__init__.py +++ b/eel/__init__.py @@ -169,9 +169,11 @@ def run_lambda(): HOST = _start_args['host'] app = _start_args['app'] # type: btl.Bottle - for route_path, route_params in BOTTLE_ROUTES.items(): - route_func, route_kwargs = route_params - btl.route(path=route_path, callback=route_func, **route_kwargs) + + if isinstance(app, btl.Bottle): + register_eel_routes(app) + else: + register_eel_routes(btl.default_app()) return btl.run( host=HOST, @@ -264,6 +266,19 @@ def _websocket(ws): "/eel": (_websocket, dict(apply=[wbs.websocket])) } +def register_eel_routes(app): + ''' + Adds eel routes to `app`. Only needed if you are passing something besides `bottle.Bottle` to `eel.start()`. + Ex: + app = bottle.Bottle() + eel.register_eel_routes(app) + middleware = beaker.middleware.SessionMiddleware(app) + eel.start(app=middleware) + ''' + for route_path, route_params in BOTTLE_ROUTES.items(): + route_func, route_kwargs = route_params + app.route(path=route_path, callback=route_func, **route_kwargs) + # Private functions def _safe_json(obj): diff --git a/examples/10 - custom_app_routes/custom_app.py b/examples/10 - custom_app_routes/custom_app.py new file mode 100644 index 00000000..a95ab082 --- /dev/null +++ b/examples/10 - custom_app_routes/custom_app.py @@ -0,0 +1,17 @@ +import eel +import bottle +# from beaker.middleware import SessionMiddleware + +app = bottle.Bottle() +@app.route('/custom') +def custom_route(): + return 'Hello, World!' + +eel.init('web') + +# need to manually add eel routes if we are wrapping our Bottle instance with middleware +# eel.add_eel_routes(app) +# middleware = SessionMiddleware(app) +# eel.start('index.html', app=middleware) + +eel.start('index.html', app=app) diff --git a/examples/10 - custom_app_routes/web/index.html b/examples/10 - custom_app_routes/web/index.html new file mode 100644 index 00000000..e802b567 --- /dev/null +++ b/examples/10 - custom_app_routes/web/index.html @@ -0,0 +1,8 @@ + + + + + Hello, World! + + + diff --git a/setup.py b/setup.py index 4e2c0250..ec65c93d 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name='Eel', - version='0.15.1', + version='0.15.2', author='Python Eel Organisation', author_email='python-eel@protonmail.com', url='https://github.com/python-eel/Eel', diff --git a/tests/integration/test_examples.py b/tests/integration/test_examples.py index ca1556f8..6e51868d 100644 --- a/tests/integration/test_examples.py +++ b/tests/integration/test_examples.py @@ -61,3 +61,17 @@ def test_06_jinja_templates(driver: webdriver.Remote): driver.find_element_by_css_selector('a').click() WebDriverWait(driver, 2.0).until(expected_conditions.presence_of_element_located((By.XPATH, '//h1[text()="This is page 2"]'))) + + +def test_10_custom_app(driver: webdriver.Remote): + # test default eel routes are working + with get_eel_server('examples/10 - custom_app_routes/custom_app.py', 'index.html') as eel_url: + driver.get(eel_url) + # we really need to test if the page 404s, but selenium has no support for status codes + # so we just test if we can get our page title + assert driver.title == 'Hello, World!' + + # test custom routes are working + with get_eel_server('examples/10 - custom_app_routes/custom_app.py', 'custom') as eel_url: + driver.get(eel_url) + assert 'Hello, World!' in driver.page_source