jupyter-anywidget-pglite


Namejupyter-anywidget-pglite JSON
Version 0.1.10 PyPI version JSON
download
home_pageNone
SummaryNone
upload_time2024-12-07 11:54:53
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseMIT License
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # jupyter_anywidget_pglite

Jupyter [`anywidget`](https://anywidget.dev/) and magic for working with [`pglite`](https://github.com/electric-sql/pglite) (single use postgres wasm build).

Install from PyPi as: `pip install jupyter_anywidget_pglite`

![Example of usage for pglite anywidget and magic](images/pglite_anywidget_magic.png)

Usage:

- import package and magic:

```python
%load_ext jupyter_anywidget_pglite
from jupyter_anywidget_pglite import pglite_panel

pg = pglite_panel()
#This should open a panel in the right-hand sidebar
# (`split-right`) by default.
# Close the panel either manually or via:
# pg.close()

# w = pglite_panel("example panel title)`
# w = pglite_panel(None, "split-bottom")`

# Headless mode (no HTML UI, works in:
# Jupyter Lab, Jupyter Notebook, VS Code w/ Jupyter notebook support)
#from jupyter_anywidget_pglite import pglite_headless
#pg = pglite_headless()

# Inline display
# Display HTML UI as initialising code cell output
# Display will be updated with consequent queries
#from jupyter_anywidget_pglite import pglite_inline
#pg = pglite_inline()
```

Use `pg.ready()` / `pg.ready(timeout=TIME_IN_S)` function that will block until the `pglite` widget is loaded and ready to accept requests *(not JupyterLite)*.

## Persisting data in browser storage

To persist the database in browser storage, set the `idb='DBNAME`` parameter when creating a widget. For example:

`pg_headless_persist = pglite_headless(idb="pglitetest1")`

## Running queries

To run a query, place the query insde a `%%pglite` cell block magic.

- use the `-w / --widget-name` setting to set the widget within the magic and it does not need to be passed again (for example, `%%pglite_magic -w pg`)
- alternatively, prior to calling the block magic, set the widget used in the magic via a line magic: `%setwidget pg`

Running queries on the database using IPython cell block magic `%%pglite -w WIDGET_VARIABLE`:

```python
%%pglite_magic -w pg
CREATE TABLE IF NOT EXISTS test  (
        id serial primary key,
        title varchar not null
      );

#----
%%pglite_magic
INSERT INTO test (title) VALUES ('dummy');

#----
%%pglite_magic
SELECT * FROM test;

```

To run multiple SQL statements in the same cell:

- use the `-m / --multiple-statements` flag (default: `False`) when calling the cell block magic [NOT RECOMMENDED]. This will naively split the query on each `;` character, and then run each split item as a separate command. The response will be set to the response from the final query;
- use the `-M / --multiple-statement-block` flag to run all the tems using the `pglite` `.exec()` command.

We can also run queries (with the same arguments) using the `%pglite_query` line magic, with the query set via the `-q / --query` parameter:

`%pglite_query -r -q 'SELECT * FROM test LIMIT 1;'`

As if we add the `-d` flag, this will return the query result as a dataframe.

Having made a query onto the database via a magic cell, we can retrieve the response:

```python
pg.response
```

If `pandas` is installed, we can get rows returned from a query response as a dataframe:

`pg.df()`

Note that the `pglite` query runs asynchronously, so how do we know on the Python side when the response is ready?

Using the [`jupyter_ui_poll`](https://github.com/kirill888/jupyter-ui-poll) package (*not* JupyterLite), we can run a blocking wait on a response from `pglite` *(not JupyterLite)*:

`response = pg.blocking_reply()`

Optionally provide a timeout period (seconds):

`response = pg.blocking_reply(timeout=5)`

We can also use a blocking trick to return a response from the magic cell *(not JupyterLite)*. Set `-r / --response` flag when calling the magic. Optionally set the `-t / --timeout` to the timeout period in seconds (default 5s; if the timeout is explicitly set, `-r` is assumed): `%%pglite -r`, `%pglite -t 10`

![Example showing use of pg.ready() and magic -r response flag ](images/blocking_functions.png)

*Note: I think that IPython notebook cells should have cell run IDs cleared prior to running. I have seen errors if there are non-unique cell run IDs for the blocking cell.*

## Add the contents of a dataframe to the database

If we have a table already defined on the database, and a dataframe that confoms to it, we can add the data in the dataframe to the table as follows:

`%pglite_df_insert -d df -t my_table`

## Exporting data to file / reloading from file

Save and load data to / from a file.

![example of creating a datadump , saving it to a file, and seeding a widget from it](images/datadump-handling.png)

We can get an export of the data using the `pglite` data exporter ([`.dumpdatadir()`](https://github.com/electric-sql/pglite/blob/main/docs/docs/api.md#dumpdatadir)) in the database by calling:

`pg.create_data_dump()`

For a blocking wait until the datadump is read, use `pg.create_data_dump(True)` or `pg.create_data_dump(wait=True)` (not JupyterLite). You can also pass a `timeout` parameter in seconds (`wait=True` is assumed if the timeout parameter is explicitly set).

After a moment or two, the data will appear in a dictionary on: `pg.file_package`

If we make a copy of that data, we can then create a new `pglite` widget with a new `pglite` instance that can load in the data using the `pglite` data load option ([`loadDataDir`](https://github.com/electric-sql/pglite/blob/main/docs/docs/api.md#options)).

Use the `data=` argument when creating the widget to pass in the data:

```python
datadump = pg.file_package.copy()
# View info
#datadump["file_info"]
# Actual data is in: datadump["file_content"]
pg1 = pglite_inline(data=datadump)
```

We can export the datadump to a file using:

`pg.save_datadump_to_file()`

Or pass a filename: `pg.save_datadump_to_file('myfile.tar.gz')`

Load data into a datadump object:

```python
from jupyter_anywidget_pglite import load_datadump_from_file

dd = load_datadump_from_file("pgdata.tar.gz")
dd["file_info"]
```

Or create a new widget with the `pglite` database seeded from the file:

`pg2 = pglite_panel(data="pgdata.tar.gz")`

## Extensions

An increasing range of PostgreSQL extensions are available for `pglite` ([catalogue](https://pglite.dev/extensions/)), and several of these are currently supported by `jupyter_anywidget_pglite`:

```python
from jupyter_anywidget_pglite import AVAILABLE_EXTENSIONS

AVAILABLE_EXTENSIONS

>>> ['fuzzystrmatch', 'pg_trgm', 'vector']
```

When creating the widget, pass the list of required extensions via the `extensions=` parameter. For example:  `pglite_panel(extensions=["vector", "fuzzystrmatch", "pg_trgm"])`

The extension package is downloaded and the extension automatically enabled via an automaticlaly run `CREATE EXTENSION IF NOT EXISTS extension_name` call.

Examples:

- `pg_trgm`: `%pglite_query -w pg_panel -r -q "SELECT similarity('One sentence', 'Another sentence');"`
- `fuzzystrmatch`: `%pglite_query -r -q "SELECT soundex('hello world!');"`

*TO DO: provide a way for users to dynamically add references to additional extension packages.*

## Audible alerts

To provide an audible alert when a query or a data dump generation operation has completed, set: `pg.audio = True`,

## TO DO

- options to display outputs in the panel;
- button to clear input history;
- button to reset database;
- explore possibility of a JuptyerLab extension to load `pglite` "centrally" and then connect to the same instance from any notebook.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "jupyter-anywidget-pglite",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": null,
    "author": null,
    "author_email": "Tony Hirst <tony.hirst@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/33/dd/5f388ab373280913bef623c6a95db02a0aafa4e7742219e6eb260a362441/jupyter_anywidget_pglite-0.1.10.tar.gz",
    "platform": null,
    "description": "# jupyter_anywidget_pglite\n\nJupyter [`anywidget`](https://anywidget.dev/) and magic for working with [`pglite`](https://github.com/electric-sql/pglite) (single use postgres wasm build).\n\nInstall from PyPi as: `pip install jupyter_anywidget_pglite`\n\n![Example of usage for pglite anywidget and magic](images/pglite_anywidget_magic.png)\n\nUsage:\n\n- import package and magic:\n\n```python\n%load_ext jupyter_anywidget_pglite\nfrom jupyter_anywidget_pglite import pglite_panel\n\npg = pglite_panel()\n#This should open a panel in the right-hand sidebar\n# (`split-right`) by default.\n# Close the panel either manually or via:\n# pg.close()\n\n# w = pglite_panel(\"example panel title)`\n# w = pglite_panel(None, \"split-bottom\")`\n\n# Headless mode (no HTML UI, works in:\n# Jupyter Lab, Jupyter Notebook, VS Code w/ Jupyter notebook support)\n#from jupyter_anywidget_pglite import pglite_headless\n#pg = pglite_headless()\n\n# Inline display\n# Display HTML UI as initialising code cell output\n# Display will be updated with consequent queries\n#from jupyter_anywidget_pglite import pglite_inline\n#pg = pglite_inline()\n```\n\nUse `pg.ready()` / `pg.ready(timeout=TIME_IN_S)` function that will block until the `pglite` widget is loaded and ready to accept requests *(not JupyterLite)*.\n\n## Persisting data in browser storage\n\nTo persist the database in browser storage, set the `idb='DBNAME`` parameter when creating a widget. For example:\n\n`pg_headless_persist = pglite_headless(idb=\"pglitetest1\")`\n\n## Running queries\n\nTo run a query, place the query insde a `%%pglite` cell block magic.\n\n- use the `-w / --widget-name` setting to set the widget within the magic and it does not need to be passed again (for example, `%%pglite_magic -w pg`)\n- alternatively, prior to calling the block magic, set the widget used in the magic via a line magic: `%setwidget pg`\n\nRunning queries on the database using IPython cell block magic `%%pglite -w WIDGET_VARIABLE`:\n\n```python\n%%pglite_magic -w pg\nCREATE TABLE IF NOT EXISTS test  (\n        id serial primary key,\n        title varchar not null\n      );\n\n#----\n%%pglite_magic\nINSERT INTO test (title) VALUES ('dummy');\n\n#----\n%%pglite_magic\nSELECT * FROM test;\n\n```\n\nTo run multiple SQL statements in the same cell:\n\n- use the `-m / --multiple-statements` flag (default: `False`) when calling the cell block magic [NOT RECOMMENDED]. This will naively split the query on each `;` character, and then run each split item as a separate command. The response will be set to the response from the final query;\n- use the `-M / --multiple-statement-block` flag to run all the tems using the `pglite` `.exec()` command.\n\nWe can also run queries (with the same arguments) using the `%pglite_query` line magic, with the query set via the `-q / --query` parameter:\n\n`%pglite_query -r -q 'SELECT * FROM test LIMIT 1;'`\n\nAs if we add the `-d` flag, this will return the query result as a dataframe.\n\nHaving made a query onto the database via a magic cell, we can retrieve the response:\n\n```python\npg.response\n```\n\nIf `pandas` is installed, we can get rows returned from a query response as a dataframe:\n\n`pg.df()`\n\nNote that the `pglite` query runs asynchronously, so how do we know on the Python side when the response is ready?\n\nUsing the [`jupyter_ui_poll`](https://github.com/kirill888/jupyter-ui-poll) package (*not* JupyterLite), we can run a blocking wait on a response from `pglite` *(not JupyterLite)*:\n\n`response = pg.blocking_reply()`\n\nOptionally provide a timeout period (seconds):\n\n`response = pg.blocking_reply(timeout=5)`\n\nWe can also use a blocking trick to return a response from the magic cell *(not JupyterLite)*. Set `-r / --response` flag when calling the magic. Optionally set the `-t / --timeout` to the timeout period in seconds (default 5s; if the timeout is explicitly set, `-r` is assumed): `%%pglite -r`, `%pglite -t 10`\n\n![Example showing use of pg.ready() and magic -r response flag ](images/blocking_functions.png)\n\n*Note: I think that IPython notebook cells should have cell run IDs cleared prior to running. I have seen errors if there are non-unique cell run IDs for the blocking cell.*\n\n## Add the contents of a dataframe to the database\n\nIf we have a table already defined on the database, and a dataframe that confoms to it, we can add the data in the dataframe to the table as follows:\n\n`%pglite_df_insert -d df -t my_table`\n\n## Exporting data to file / reloading from file\n\nSave and load data to / from a file.\n\n![example of creating a datadump , saving it to a file, and seeding a widget from it](images/datadump-handling.png)\n\nWe can get an export of the data using the `pglite` data exporter ([`.dumpdatadir()`](https://github.com/electric-sql/pglite/blob/main/docs/docs/api.md#dumpdatadir)) in the database by calling:\n\n`pg.create_data_dump()`\n\nFor a blocking wait until the datadump is read, use `pg.create_data_dump(True)` or `pg.create_data_dump(wait=True)` (not JupyterLite). You can also pass a `timeout` parameter in seconds (`wait=True` is assumed if the timeout parameter is explicitly set).\n\nAfter a moment or two, the data will appear in a dictionary on: `pg.file_package`\n\nIf we make a copy of that data, we can then create a new `pglite` widget with a new `pglite` instance that can load in the data using the `pglite` data load option ([`loadDataDir`](https://github.com/electric-sql/pglite/blob/main/docs/docs/api.md#options)).\n\nUse the `data=` argument when creating the widget to pass in the data:\n\n```python\ndatadump = pg.file_package.copy()\n# View info\n#datadump[\"file_info\"]\n# Actual data is in: datadump[\"file_content\"]\npg1 = pglite_inline(data=datadump)\n```\n\nWe can export the datadump to a file using:\n\n`pg.save_datadump_to_file()`\n\nOr pass a filename: `pg.save_datadump_to_file('myfile.tar.gz')`\n\nLoad data into a datadump object:\n\n```python\nfrom jupyter_anywidget_pglite import load_datadump_from_file\n\ndd = load_datadump_from_file(\"pgdata.tar.gz\")\ndd[\"file_info\"]\n```\n\nOr create a new widget with the `pglite` database seeded from the file:\n\n`pg2 = pglite_panel(data=\"pgdata.tar.gz\")`\n\n## Extensions\n\nAn increasing range of PostgreSQL extensions are available for `pglite` ([catalogue](https://pglite.dev/extensions/)), and several of these are currently supported by `jupyter_anywidget_pglite`:\n\n```python\nfrom jupyter_anywidget_pglite import AVAILABLE_EXTENSIONS\n\nAVAILABLE_EXTENSIONS\n\n>>> ['fuzzystrmatch', 'pg_trgm', 'vector']\n```\n\nWhen creating the widget, pass the list of required extensions via the `extensions=` parameter. For example:  `pglite_panel(extensions=[\"vector\", \"fuzzystrmatch\", \"pg_trgm\"])`\n\nThe extension package is downloaded and the extension automatically enabled via an automaticlaly run `CREATE EXTENSION IF NOT EXISTS extension_name` call.\n\nExamples:\n\n- `pg_trgm`: `%pglite_query -w pg_panel -r -q \"SELECT similarity('One sentence', 'Another sentence');\"`\n- `fuzzystrmatch`: `%pglite_query -r -q \"SELECT soundex('hello world!');\"`\n\n*TO DO: provide a way for users to dynamically add references to additional extension packages.*\n\n## Audible alerts\n\nTo provide an audible alert when a query or a data dump generation operation has completed, set: `pg.audio = True`,\n\n## TO DO\n\n- options to display outputs in the panel;\n- button to clear input history;\n- button to reset database;\n- explore possibility of a JuptyerLab extension to load `pglite` \"centrally\" and then connect to the same instance from any notebook.\n",
    "bugtrack_url": null,
    "license": "MIT License",
    "summary": null,
    "version": "0.1.10",
    "project_urls": {
        "Homepage": "https://github.com/innovationOUtside/jupyter_anywidget_pglite",
        "Repository": "https://github.com/innovationOUtside/jupyter_anywidget_pglite"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b07b56a25d878836b2f71d638cf643f38e8e552f1c1aa2c0f6c04e0a6fe87d2f",
                "md5": "84fc62cbb4238a05a7417991669e7de7",
                "sha256": "774cb4ac48f77b9f54b2dd34f833a0396751bc0907e161804f5ae6506e43e81a"
            },
            "downloads": -1,
            "filename": "jupyter_anywidget_pglite-0.1.10-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "84fc62cbb4238a05a7417991669e7de7",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 13305,
            "upload_time": "2024-12-07T11:54:52",
            "upload_time_iso_8601": "2024-12-07T11:54:52.782060Z",
            "url": "https://files.pythonhosted.org/packages/b0/7b/56a25d878836b2f71d638cf643f38e8e552f1c1aa2c0f6c04e0a6fe87d2f/jupyter_anywidget_pglite-0.1.10-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "33dd5f388ab373280913bef623c6a95db02a0aafa4e7742219e6eb260a362441",
                "md5": "3790921fdfe1230a26f3badc18239dec",
                "sha256": "71f4fedb7456f1a6e238d4094986c687683c5c755aaa103ee41b7eaff28bae6c"
            },
            "downloads": -1,
            "filename": "jupyter_anywidget_pglite-0.1.10.tar.gz",
            "has_sig": false,
            "md5_digest": "3790921fdfe1230a26f3badc18239dec",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 10906,
            "upload_time": "2024-12-07T11:54:53",
            "upload_time_iso_8601": "2024-12-07T11:54:53.848204Z",
            "url": "https://files.pythonhosted.org/packages/33/dd/5f388ab373280913bef623c6a95db02a0aafa4e7742219e6eb260a362441/jupyter_anywidget_pglite-0.1.10.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-12-07 11:54:53",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "innovationOUtside",
    "github_project": "jupyter_anywidget_pglite",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "jupyter-anywidget-pglite"
}
        
Elapsed time: 0.39990s