h2o-lightwave


Nameh2o-lightwave JSON
Version 1.2.0 PyPI version JSON
download
home_pageNone
SummaryH2O Wave Python driver for integration with arbitrary python web frameworks.
upload_time2024-05-06 12:38:40
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseNone
keywords data science low code machine learning realtime ui
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # H2O Lightwave

H2O Lightwave is a lightweight, pure-Python version of [H2O Wave](https://wave.h2o.ai/) that can be embedded in popular async web frameworks like FastAPI, Starlette, etc.

In other words, H2O Lightwave works without the Wave server.

The integration consists of 2 steps:

* Add Wave's web assets directory to your framework's static file handler.
* Add a webSocket handler, and use `wave_serve()` to connect Wave to your web UI.

That's it. You can now render UI elements using pure Python. Lightwave aims to be as minimal as possible and only provides:

* A simple way to render your UI.
* A simple way of capturing the user interactions (like button clicks, dropdown values etc.).
* Minimal state management.

Nothing more, nothing less.

Example FastAPI integration:

```py
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.staticfiles import StaticFiles
from h2o_lightwave import Q, ui, wave_serve
from h2o_lightwave_web import web_directory


# Lightwave callback function.
async def serve(q: Q):
    # Paint our UI on the first page visit.
    if not q.client.initialized:
        # Create a local state.
        q.client.count = 0
        # Add a "card" with a text and a button
        q.page['hello'] = ui.form_card(box='1 1 2 2', items=[
            ui.text_xl('Hello world'),
            ui.button(name='counter', label=f'Current count: {q.client.count}'),
        ])
        q.client.initialized = True

    # Handle counter button click.
    if q.args.counter:
        # Increment the counter.
        q.client.count += 1
        # Update the counter button.
        q.page['hello'].items[1].button.label = f'Current count: {q.client.count}'

    # Send the UI changes to the browser.
    await q.page.save()


# Run: uvicorn hello_fastapi:app.
# FastAPI boilerplate.
app = FastAPI()


# FastAPI: WebSocket must be registered before index.html handler.
@app.websocket("/_s/")
async def ws(ws: WebSocket):
    try:
        await ws.accept()
        await wave_serve(serve, ws.send_text, ws.receive_text)
        await ws.close()
    except WebSocketDisconnect:
        print('Client disconnected')

app.mount("/", StaticFiles(directory=web_directory, html=True), name="/")
```

We also recommend reading the [blog post](https://medium.com/@unusualcode/h2o-lightwave-building-web-uis-with-fastapi-and-python-88a915383490) and other [integration examples](https://github.com/h2oai/wave/tree/main/py/h2o_lightwave/examples).

## Installation

```bash
pip install "h2o-lightwave[web]"
```

Lightwave requires websockets to function properly. Not all libraries come with them out of the box so you might need to install them additionally. For example, Starlette & FastAPI requires

```bash
pip install websockets
```

to be able to expose websocket handlers. This might differ from framework to framework.

## Widgets

All available widgets can be found [here](https://wave.h2o.ai/docs/widgets/overview). We are working on separate docs for Lightwave.

## Custom HTML page

Lightwave can also be used only for certain parts of your HTML pages, e.g. for charts. In addition to the integration steps above:

* Use the `get_web_files` function which HTML links to scripts and styles for you to inject into your existing HTML.
* Render a `div` with an id `wave-root` (`<div id='wave-root'></div>`) into which you want Lightwave to render.
* Render a parent container for `wave-root` that has `position: relative` and has some dimensions attached.

```html
{# index_template.html #}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- Scripts and stylesheets required for Wave to work properly. -->
  {{ wave_files }}
</head>
<style>
  /* Must have position: relative and some size specified (e.g. height, flexbox, absolute positioning etc.). */
  .wave-container {
    position: relative;
    height: 800px;
  }
</style>

<!-- Websocket URL can be changed if needed. Defaults to "/_s/". -->
<body data-wave-socket-url="/custom_socket/">
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div class="wave-container">
    <!-- Wave renders here. -->
    <div id="wave-root"></div>
  </div>
</body>

</html>
```

### Configuration

By default, Lightwave tries to connect to websocket route at `/_s/`. This can be configured by adding a `data-wave-socket-url` attribute on the HTML body element (`<body data-wave-socket-url='/my_socket_url/'>`).

## Links

* Website: [https://wave.h2o.ai/](https://wave.h2o.ai/)
* Releases: [https://pypi.org/project/h2o-wave/](https://pypi.org/project/h2o-wave/)
* Code: [https://github.com/h2oai/wave](https://github.com/h2oai/wave)
* Issue tracker: [https://github.com/h2oai/wave/issues](https://github.com/h2oai/wave/issues)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "h2o-lightwave",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "Data Science, Low code, Machine Learning, Realtime, UI",
    "author": null,
    "author_email": "Martin Turoci <martin.turoci@h2o.ai>",
    "download_url": null,
    "platform": null,
    "description": "# H2O Lightwave\n\nH2O Lightwave is a lightweight, pure-Python version of [H2O Wave](https://wave.h2o.ai/) that can be embedded in popular async web frameworks like FastAPI, Starlette, etc.\n\nIn other words, H2O Lightwave works without the Wave server.\n\nThe integration consists of 2 steps:\n\n* Add Wave's web assets directory to your framework's static file handler.\n* Add a webSocket handler, and use `wave_serve()` to connect Wave to your web UI.\n\nThat's it. You can now render UI elements using pure Python. Lightwave aims to be as minimal as possible and only provides:\n\n* A simple way to render your UI.\n* A simple way of capturing the user interactions (like button clicks, dropdown values etc.).\n* Minimal state management.\n\nNothing more, nothing less.\n\nExample FastAPI integration:\n\n```py\nfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect\nfrom fastapi.staticfiles import StaticFiles\nfrom h2o_lightwave import Q, ui, wave_serve\nfrom h2o_lightwave_web import web_directory\n\n\n# Lightwave callback function.\nasync def serve(q: Q):\n    # Paint our UI on the first page visit.\n    if not q.client.initialized:\n        # Create a local state.\n        q.client.count = 0\n        # Add a \"card\" with a text and a button\n        q.page['hello'] = ui.form_card(box='1 1 2 2', items=[\n            ui.text_xl('Hello world'),\n            ui.button(name='counter', label=f'Current count: {q.client.count}'),\n        ])\n        q.client.initialized = True\n\n    # Handle counter button click.\n    if q.args.counter:\n        # Increment the counter.\n        q.client.count += 1\n        # Update the counter button.\n        q.page['hello'].items[1].button.label = f'Current count: {q.client.count}'\n\n    # Send the UI changes to the browser.\n    await q.page.save()\n\n\n# Run: uvicorn hello_fastapi:app.\n# FastAPI boilerplate.\napp = FastAPI()\n\n\n# FastAPI: WebSocket must be registered before index.html handler.\n@app.websocket(\"/_s/\")\nasync def ws(ws: WebSocket):\n    try:\n        await ws.accept()\n        await wave_serve(serve, ws.send_text, ws.receive_text)\n        await ws.close()\n    except WebSocketDisconnect:\n        print('Client disconnected')\n\napp.mount(\"/\", StaticFiles(directory=web_directory, html=True), name=\"/\")\n```\n\nWe also recommend reading the [blog post](https://medium.com/@unusualcode/h2o-lightwave-building-web-uis-with-fastapi-and-python-88a915383490) and other [integration examples](https://github.com/h2oai/wave/tree/main/py/h2o_lightwave/examples).\n\n## Installation\n\n```bash\npip install \"h2o-lightwave[web]\"\n```\n\nLightwave requires websockets to function properly. Not all libraries come with them out of the box so you might need to install them additionally. For example, Starlette & FastAPI requires\n\n```bash\npip install websockets\n```\n\nto be able to expose websocket handlers. This might differ from framework to framework.\n\n## Widgets\n\nAll available widgets can be found [here](https://wave.h2o.ai/docs/widgets/overview). We are working on separate docs for Lightwave.\n\n## Custom HTML page\n\nLightwave can also be used only for certain parts of your HTML pages, e.g. for charts. In addition to the integration steps above:\n\n* Use the `get_web_files` function which HTML links to scripts and styles for you to inject into your existing HTML.\n* Render a `div` with an id `wave-root` (`<div id='wave-root'></div>`) into which you want Lightwave to render.\n* Render a parent container for `wave-root` that has `position: relative` and has some dimensions attached.\n\n```html\n{# index_template.html #}\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Document</title>\n  <!-- Scripts and stylesheets required for Wave to work properly. -->\n  {{ wave_files }}\n</head>\n<style>\n  /* Must have position: relative and some size specified (e.g. height, flexbox, absolute positioning etc.). */\n  .wave-container {\n    position: relative;\n    height: 800px;\n  }\n</style>\n\n<!-- Websocket URL can be changed if needed. Defaults to \"/_s/\". -->\n<body data-wave-socket-url=\"/custom_socket/\">\n  <noscript>You need to enable JavaScript to run this app.</noscript>\n  <div class=\"wave-container\">\n    <!-- Wave renders here. -->\n    <div id=\"wave-root\"></div>\n  </div>\n</body>\n\n</html>\n```\n\n### Configuration\n\nBy default, Lightwave tries to connect to websocket route at `/_s/`. This can be configured by adding a `data-wave-socket-url` attribute on the HTML body element (`<body data-wave-socket-url='/my_socket_url/'>`).\n\n## Links\n\n* Website: [https://wave.h2o.ai/](https://wave.h2o.ai/)\n* Releases: [https://pypi.org/project/h2o-wave/](https://pypi.org/project/h2o-wave/)\n* Code: [https://github.com/h2oai/wave](https://github.com/h2oai/wave)\n* Issue tracker: [https://github.com/h2oai/wave/issues](https://github.com/h2oai/wave/issues)\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "H2O Wave Python driver for integration with arbitrary python web frameworks.",
    "version": "1.2.0",
    "project_urls": {
        "Changelog": "https://github.com/h2oai/wave/releases",
        "Documentation": "https://wave.h2o.ai/",
        "Homepage": "https://wave.h2o.ai/",
        "Repository": "https://github.com/h2oai/wave"
    },
    "split_keywords": [
        "data science",
        " low code",
        " machine learning",
        " realtime",
        " ui"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0915349fd43c878f03d40863a5d2d92eedced1ec9e6917988e132e4b8bff0f03",
                "md5": "2edaa2882fc09e9ba114b4744e9dca50",
                "sha256": "5276a864e5dcd64583b52a7aded01967ac1d449f8c604eeda6db519422e61291"
            },
            "downloads": -1,
            "filename": "h2o_lightwave-1.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2edaa2882fc09e9ba114b4744e9dca50",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 124105,
            "upload_time": "2024-05-06T12:38:40",
            "upload_time_iso_8601": "2024-05-06T12:38:40.074580Z",
            "url": "https://files.pythonhosted.org/packages/09/15/349fd43c878f03d40863a5d2d92eedced1ec9e6917988e132e4b8bff0f03/h2o_lightwave-1.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-06 12:38:40",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "h2oai",
    "github_project": "wave",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "h2o-lightwave"
}
        
Elapsed time: 0.28852s