Skip to content

Commit 2b2c520

Browse files
Merge pull request #734 from Kanaries/refactor-0.5
[codex] Refactor 0.5 integration hardening and typed API cleanup
2 parents 0f14ef0 + ec0cba5 commit 2b2c520

153 files changed

Lines changed: 10545 additions & 2262 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/auto-ci.yml

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ jobs:
3535
run: |
3636
chmod u+x ./scripts/compile.sh
3737
./scripts/compile.sh
38+
- name: Try Frontend Smoke Test
39+
working-directory: ./app
40+
run: |
41+
yarn playwright install --with-deps chromium
42+
yarn test:front_end
3843
- name: Uploading dist
3944
uses: actions/upload-artifact@v4
4045
with:
@@ -48,7 +53,7 @@ jobs:
4853
strategy:
4954
fail-fast: false
5055
matrix:
51-
python-version: ['3.12', '3.13']
56+
python-version: ['3.10', '3.11', '3.12', '3.13']
5257
os-version: [ubuntu-latest, windows-latest, macos-latest]
5358

5459
runs-on: ${{ matrix.os-version }}
@@ -64,6 +69,15 @@ jobs:
6469
uses: actions/setup-python@v4
6570
with:
6671
python-version: ${{ matrix.python-version }}
72+
- name: Use Node.js 22.x
73+
uses: actions/setup-node@v4
74+
with:
75+
node-version: 22.x
76+
cache: 'yarn'
77+
cache-dependency-path: ./app/yarn.lock
78+
- name: Ensure Yarn
79+
run: |
80+
npm install -g yarn
6781
- name: Download test data
6882
working-directory: ./
6983
run: |
@@ -75,32 +89,30 @@ jobs:
7589
PIP_ONLY_BINARY: "duckdb"
7690
run: |
7791
pip install ".[export]"
92+
- name: Pin Pydantic v1 compatibility leg
93+
if: ${{ matrix.os-version == 'ubuntu-latest' && matrix.python-version == '3.10' }}
94+
run: |
95+
pip install "pydantic==1.10.15"
7896
- name: Try Install Modin In Linux Os
7997
if: ${{ matrix.os-version == 'ubuntu-latest' && matrix.python-version == '3.11' }}
8098
run: |
99+
pip install "numpy<2" "pandas<2.1"
81100
pip install aiohttp==3.8.6
82101
pip install "modin==0.23.1" "modin[ray]==0.23.1"
83102
pip install pydantic==1.10.9
84103
- name: Try Running
85104
working-directory: ./tests/
86105
run: |
87-
pip install ipykernel nbconvert pandas polars
106+
pip install ipykernel nbmake pandas polars pytest
88107
python -m ipykernel install --name python --user
89108
jupyter kernelspec list
90-
jupyter nbconvert --execute --ExecutePreprocessor.kernel_name=python --to html *.ipynb
109+
python -c "from pathlib import Path; import subprocess, sys; notebooks = sorted(str(path) for path in Path('.').glob('*.ipynb')); subprocess.run([sys.executable, '-m', 'pytest', '--nbmake', '--nbmake-kernel=python', *notebooks], check=True)"
91110
- name: Try Pytest
92111
timeout-minutes: 20
93112
working-directory: ./
94113
run: |
95114
pip install duckdb_engine
96-
pip install pytest
97-
python ./scripts/ci_run_pytest.py
98-
- name: Uploading notebooks
99-
uses: actions/upload-artifact@v4
100-
if: ${{ matrix.python-version == '3.12' && matrix.os-version == 'ubuntu-latest' }}
101-
with:
102-
name: notebook
103-
path: |
104-
./tests/main.html
105-
./tests/offline.html
106-
./tests/stress-test.html
115+
pip install pytest ruff starlette polars tornado
116+
ruff check pygwalker tests scripts bin pygwalker_tools
117+
ruff format --check pygwalker tests scripts bin pygwalker_tools
118+
python -X faulthandler -W error::DeprecationWarning:pygwalker -m pytest -o faulthandler_timeout=300 tests

.github/workflows/publish.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ jobs:
5656
uses: actions/setup-python@v4
5757
with:
5858
python-version: ${{ matrix.python-version }}
59+
- name: Use Node.js 22.x
60+
uses: actions/setup-node@v4
61+
with:
62+
node-version: 22.x
63+
cache: 'yarn'
64+
cache-dependency-path: ./app/yarn.lock
65+
- name: Ensure Yarn
66+
run: |
67+
npm install -g yarn
5968
- name: Try building
6069
working-directory: ./
6170
run: |

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ dmypy.json
130130

131131
__pycache__
132132
dist
133-
!/pygwalker/templates/dist/*
133+
pygwalker/templates/dist/
134134
.DS_Store
135135
venv
136136
.ipynb_checkpoints
@@ -147,4 +147,4 @@ __pycache__/
147147
*.db
148148
.web
149149
*.py[cod]
150-
assets/external/
150+
assets/external/

CONTRIBUTING.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Contributing to PyGWalker
2+
3+
The contributor workflow lives in [`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md).
4+
5+
Start there for the supported local setup, including:
6+
7+
- Python editable installs and test commands.
8+
- Frontend dependency installation, builds, type checks, and Playwright smoke tests.
9+
- Optional local Graphic Walker source builds through `app`'s `dev:preinstall` script.
10+
- Vite dev-server setup for JupyterLab hot reload.
11+
- CI and package-build expectations.
12+
13+
Keeping the detailed guide under `docs/` lets the development notes and
14+
troubleshooting page link to one maintained source of truth.

README.md

Lines changed: 67 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
[English](README.md) | [Español](./docs/README.es.md) | [Français](./docs/README.fr.md) | [Deutsch](./docs/README.de.md) | [中文](./docs/README.zh.md) | [Türkçe](./docs/README.tr.md) | [日本語](./docs/README.ja.md) | [한국어](./docs/README.ko.md) | [Русский](./docs/README.ru.md)
22

3+
> [!NOTE]
4+
> The English README is the source of truth for the API reference, installation, and development instructions. Translated READMEs are community-maintained and may lag behind this file.
5+
36

47
<p align="center"><a href="https://github.com/Kanaries/pygwalker"><img width=100% alt="" src="https://github.com/user-attachments/assets/f90db669-6e5a-45d3-942e-547c9d0471c9" /></a></p>
58

@@ -57,7 +60,7 @@ Visit [Google Colab](https://colab.research.google.com/drive/171QUQeq-uTLgSj1u-P
5760
5861

5962
# Features
60-
PyGWalker is a Python library that simplifies data analysis and visualization workflows by turning pandas DataFrames into interactive visual interfaces.
63+
PyGWalker is a Python library that simplifies data analysis and visualization workflows by turning pandas, polars, and pyarrow table data into interactive visual interfaces.
6164
It offers a variety of features that make it a powerful tool for data exploration:
6265
- ##### Interactive Data Exploration:
6366
- Drag-and-drop interface for easy visualization creation.  
@@ -151,21 +154,45 @@ Cool things you can do with PyGwalker:
151154

152155
### Better Practices
153156

154-
There are some important parameters you should know when using pygwalker:
157+
There are some important parameters you should know when using pygwalker:
155158

156-
+ `spec`: for save/load chart config (json string or file path)
157-
+ `kernel_computation`: for using duckdb as computing engine which allows you to handle larger dataset faster in your local machine.
158-
+ `use_kernel_calc`: Deprecated, use `kernel_computation` instead.
159+
+ `spec_path`: local file path for saving/loading chart config.
160+
+ `spec`: chart config object, JSON string, config ID, or remote URL.
161+
+ `computation`: choose where data queries run. Use `"browser"` for frontend-only computation, `"kernel"` for local DuckDB-backed Python computation, `"cloud"` for Kanaries cloud computation, or omit it for the default automatic behavior.
162+
+ `kernel_computation`: legacy boolean for using DuckDB as computing engine. Prefer `computation="kernel"`.
163+
+ `use_kernel_calc`: Deprecated, use `computation="kernel"` or `kernel_computation` instead.
159164

160165
```python
161166
df = pd.read_csv('./bike_sharing_dc.csv')
162167
walker = pyg.walk(
163168
df,
164-
spec="./chart_meta_0.json", # this json file will save your chart state, you need to click save button in ui mannual when you finish a chart, 'autosave' will be supported in the future.
165-
kernel_computation=True, # set `kernel_computation=True`, pygwalker will use duckdb as computing engine, it support you explore bigger dataset(<=100GB).
169+
spec_path="./chart_meta_0.json", # local file used to load and save chart state.
170+
computation="kernel", # use DuckDB in the Python kernel for larger datasets.
166171
)
167172
```
168173

174+
You can also create a reusable `Walker` object and choose where to render it:
175+
176+
```python
177+
walker = pyg.Walker(df, spec_path="./chart_meta_0.json", computation="browser")
178+
walker.show() # auto-detects notebook or script mode
179+
html = walker.to_html()
180+
html = pyg.to_html(walker)
181+
```
182+
183+
After exploring in the UI, export the current chart state as reproducible Python code:
184+
185+
```python
186+
code = walker.to_code(dataset_name="df")
187+
print(code)
188+
```
189+
190+
If you have an older saved spec, migrate it to the current schema before committing it:
191+
192+
```python
193+
migrated_spec = pyg.spec.migrate(open("./old_chart_meta.json").read())
194+
```
195+
169196
### Example in local notebook
170197

171198
* Notebook Code: [Click Here](https://github.com/Kanaries/pygwalker-offline-example)
@@ -181,7 +208,7 @@ walker = pyg.walk(
181208
After saving a chart from the UI, you can retrieve the image directly from Python.
182209

183210
```python
184-
walker = pyg.walk(df, spec="./chart_meta_0.json")
211+
walker = pyg.walk(df, spec_path="./chart_meta_0.json")
185212
# edit the chart in the UI and click the save button
186213
walker.save_chart_to_file("Chart 1", "chart1.svg", save_type="svg")
187214
png_bytes = walker.export_chart_png("Chart 1")
@@ -216,32 +243,48 @@ st.title("Use Pygwalker In Streamlit")
216243
def get_pyg_renderer() -> "StreamlitRenderer":
217244
df = pd.read_csv("./bike_sharing_dc.csv")
218245
# If you want to use feature of saving chart config, set `spec_io_mode="rw"`
219-
return StreamlitRenderer(df, spec="./gw_config.json", spec_io_mode="rw")
246+
return StreamlitRenderer(df, spec_path="./gw_config.json", spec_io_mode="rw")
220247

221248

222249
renderer = get_pyg_renderer()
223250

224251
renderer.explorer()
225252
```
226253

254+
If you already created a reusable `Walker`, Streamlit can render it directly:
255+
256+
```python
257+
import pygwalker as pyg
258+
from pygwalker.api.streamlit import StreamlitRenderer
259+
260+
walker = pyg.Walker(df, spec_path="./gw_config.json", computation="kernel")
261+
renderer = StreamlitRenderer(walker)
262+
renderer.explorer()
263+
```
264+
227265
## [API Reference](https://pygwalker-docs.vercel.app/api-reference/jupyter)
228266

229267
### [pygwalker.walk](https://pygwalker-docs.vercel.app/api-reference/jupyter#walk)
230268

231269

232-
| Parameter | Type | Default | Description |
233-
|------------------------|-----------------------------------------------------------|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
234-
| dataset | Union[DataFrame, Connector] | - | The dataframe or connector to be used. |
235-
| gid | Union[int, str] | None | ID for the GraphicWalker container div, formatted as 'gwalker-{gid}'. |
236-
| env | Literal['Jupyter', 'JupyterWidget'] | 'JupyterWidget' | Environment using pygwalker. |
237-
| field_specs | Optional[Dict[str, FieldSpec]] | None | Specifications of fields. Will be automatically inferred from `dataset` if not specified. |
238-
| hide_data_source_config | bool | True | If True, hides DataSource import and export button. |
239-
| theme_key | Literal['vega', 'g2'] | 'g2' | Theme type for the GraphicWalker. |
240-
| appearance | Literal['media', 'light', 'dark'] | 'media' | Theme setting. 'media' will auto-detect the OS theme. |
241-
| spec | str | "" | Chart configuration data. Can be a configuration ID, JSON, or remote file URL. |
242-
| use_preview | bool | True | If True, uses the preview function. |
243-
| kernel_computation | bool | False | If True, uses kernel computation for data. |
244-
| **kwargs | Any | - | Additional keyword arguments. |
270+
| Parameter | Type | Default | Description |
271+
|--------------------|-----------------------------------------------------------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------|
272+
| dataset | Union[DataFrame, pyarrow.Table, Connector, str, Walker] | - | DataFrame, pyarrow table, database connector, SQL/data source string, or reusable Walker object to explore. |
273+
| gid | Union[int, str] | None | ID for the GraphicWalker container div, formatted as `gwalker-{gid}`. |
274+
| env | Literal['JupyterAnywidget', 'Jupyter', 'JupyterWidget'] | 'JupyterAnywidget' | Notebook rendering environment. Use `JupyterAnywidget` or omit `env`; `Jupyter` and `JupyterWidget` are deprecated legacy transports kept for compatibility. |
275+
| field_specs | Optional[List[FieldSpec]] | None | Field specifications. They will be inferred from `dataset` if not specified. |
276+
| theme_key | Literal['vega', 'g2', 'streamlit'] | 'g2' | Theme type for Graphic Walker. |
277+
| appearance | Literal['media', 'light', 'dark'] | 'media' | Theme appearance. `media` follows the operating system preference. |
278+
| spec | str | "" | Chart configuration data. Can be a configuration ID, JSON string, local file path, or remote file URL. |
279+
| spec_path | Optional[str] | None | Local chart configuration file path. Prefer this over passing a local file path through `spec`. |
280+
| computation | Optional[Literal['auto', 'browser', 'kernel', 'cloud']] | None | Computation backend. Omit it for automatic behavior; use `browser`, `kernel`, or `cloud` to choose explicitly. |
281+
| use_kernel_calc | Optional[bool] | None | Deprecated. Use `computation="kernel"` or `kernel_computation` instead. |
282+
| kernel_computation | Optional[bool] | None | Legacy boolean for local DuckDB-backed kernel computation. Prefer `computation="kernel"` or `computation="browser"`. |
283+
| cloud_computation | bool | False | Legacy boolean for Kanaries cloud computation. Prefer `computation="cloud"`. |
284+
| show_cloud_tool | bool | True | Whether to show the Kanaries cloud tool when available. |
285+
| kanaries_api_key | str | "" | Kanaries API key used by cloud features. |
286+
| default_tab | Literal['data', 'vis'] | 'vis' | Default tab to show when the UI opens. |
287+
| **kwargs | Any | - | Additional keyword arguments. |
245288

246289
## Development
247290

@@ -257,7 +300,7 @@ Refer it: [local-development](https://docs.kanaries.net/pygwalker/installation#l
257300
- [x] Databricks Notebook (Since version `0.1.4a0`)
258301
- [x] Jupyter Extension for Visual Studio Code (Since version `0.1.4a0`)
259302
- [x] Most web applications compatiable with IPython kernels. (Since version `0.1.4a0`)
260-
- [x] **Streamlit (Since version `0.1.4.9`)**, enabled with `pyg.walk(df, env='Streamlit')`
303+
- [x] **Streamlit (Since version `0.1.4.9`)**, enabled with `pygwalker.api.streamlit.StreamlitRenderer`
261304
- [x] DataCamp Workspace (Since version `0.1.4a0`)
262305
- [x] Panel. See [panel-graphic-walker](https://github.com/panel-extensions/panel-graphic-walker).
263306
- [x] marimo (Since version `0.4.9.11`)
@@ -276,7 +319,7 @@ usage: pygwalker config [-h] [--set [key=value ...]] [--reset [key ...]] [--rese
276319
Modify configuration file. (default: ~/Library/Application Support/pygwalker/config.json)
277320
Available configurations:
278321

279-
- privacy ['offline', 'update-only', 'events'] (default: events).
322+
- privacy ['offline', 'update-only', 'events'] (default: update-only).
280323
"offline": fully offline, no data is send or api is requested
281324
"update-only": only check whether this is a new version of pygwalker to update
282325
"events": share which events about which feature is used in pygwalker, it only contains events data about which feature you arrive for product optimization. No DATA YOU ANALYSIS IS SEND. Events data will bind with a unique id, which is generated by pygwalker when it is installed based on timestamp. We will not collect any other information about you.

app/.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
node_modules/
2-
!lib
2+
test-results/
3+
playwright-report/
4+
!lib

0 commit comments

Comments
 (0)