From d265055cc49152374949b196752e8a0b760c98a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 13:57:19 +0200 Subject: [PATCH 001/130] Automatic extract of dependencies from setup.py --- pixi.toml | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 pixi.toml diff --git a/pixi.toml b/pixi.toml new file mode 100644 index 0000000000..f2186fd706 --- /dev/null +++ b/pixi.toml @@ -0,0 +1,270 @@ +[dependencies] +bokeh = ">=3.4.0,<3.5.0" +param = ">=2.0.0,<3.0" +pyviz_comms = ">=2.0.0" +xyzservices = ">=2021.09.1" +markdown = "*" +markdown-it-py = "*" +linkify-it-py = "*" +mdit-py-plugins = "*" +requests = "*" +tqdm = ">=4.48.0" +bleach = "*" +typing_extensions = "*" +pandas = ">=1.2" + +[feature.examples.dependencies] +holoviews = ">=1.16.0" +hvplot = "*" +plotly = ">=4.0" +altair = "*" +streamz = "*" +vega_datasets = "*" +vtk = "*" +scikit-learn = "*" +datashader = "*" +jupyter_bokeh = ">=3.0.7" +django = "<4" +channels = "*" +pyvista = "*" +ipywidgets = "*" +ipywidgets_bokeh = "*" +ipyvolume = "*" +ipyleaflet = "*" +ipympl = "*" +folium = "*" +xarray = "*" +pyinstrument = ">=4.0" +aiohttp = "*" +croniter = "*" +graphviz = "*" +networkx = ">=2.5" +pygraphviz = "*" +seaborn = "*" +pydeck = "*" +python-graphviz = "*" +xgboost = "*" +ipyvuetify = "*" +reacton = "*" +scikit-image = "*" +fastparquet = "*" +textual = "*" +dask-expr = "*" + +[feature.tests_core.dependencies] +flake8 = "*" +parameterized = "*" +pytest = "*" +nbval = "*" +pytest-rerunfailures = "*" +pytest-asyncio = "<0.22" +pytest-xdist = "*" +pytest-cov = "*" +pre-commit = "*" +psutil = "*" +altair = "*" +anywidget = "*" +folium = "*" +diskcache = "*" +holoviews = ">=1.16.0" +numpy = "*" +pandas = ">=1.3" +ipython = ">=7.0" +scipy = "*" +textual = "*" +watchfiles = "*" + +[feature.tests.dependencies] +flake8 = "*" +parameterized = "*" +pytest = "*" +nbval = "*" +pytest-rerunfailures = "*" +pytest-asyncio = "<0.22" +pytest-xdist = "*" +pytest-cov = "*" +pre-commit = "*" +psutil = "*" +altair = "*" +anywidget = "*" +folium = "*" +diskcache = "*" +holoviews = ">=1.16.0" +numpy = "*" +pandas = ">=1.3" +ipython = ">=7.0" +scipy = "*" +textual = "*" +watchfiles = "*" +ipympl = "*" +ipyvuetify = "*" +ipywidgets_bokeh = "*" +reacton = "*" +twine = "*" +numba = "<0.58" + +[feature.recommended.dependencies] +jupyterlab = "*" +holoviews = ">=1.16.0" +matplotlib = "*" +pillow = "*" +plotly = "*" + +[feature.doc.dependencies] +jupyterlab = "*" +holoviews = ">=1.16.0" +matplotlib = "*" +pillow = "*" +plotly = "*" +nbsite = ">=0.8.4" +lxml = "*" +pandas = "<2.1.0" + +[feature.ui.dependencies] +jupyter-server = "*" +playwright = "*" +pytest-playwright = "*" +tomli = "*" + +[feature.all.dependencies] +aiohttp = "*" +altair = "*" +anywidget = "*" +channels = "*" +croniter = "*" +dask-expr = "*" +datashader = "*" +diskcache = "*" +django = "<4" +fastparquet = "*" +flake8 = "*" +folium = "*" +graphviz = "*" +holoviews = ">=1.16.0" +hvplot = "*" +ipyleaflet = "*" +ipympl = "*" +ipython = ">=7.0" +ipyvolume = "*" +ipyvuetify = "*" +ipywidgets = "*" +ipywidgets_bokeh = "*" +jupyter-server = "*" +jupyter_bokeh = ">=3.0.7" +jupyterlab = "*" +lxml = "*" +matplotlib = "*" +nbsite = ">=0.8.4" +nbval = "*" +networkx = ">=2.5" +numba = "<0.58" +numpy = "*" +pandas = ">=1.3" +parameterized = "*" +pillow = "*" +playwright = "*" +plotly = ">=4.0" +pre-commit = "*" +psutil = "*" +pydeck = "*" +pygraphviz = "*" +pyinstrument = ">=4.0" +pytest = "*" +pytest-asyncio = "<0.22" +pytest-cov = "*" +pytest-playwright = "*" +pytest-rerunfailures = "*" +pytest-xdist = "*" +python-graphviz = "*" +pyvista = "*" +reacton = "*" +scikit-image = "*" +scikit-learn = "*" +scipy = "*" +seaborn = "*" +streamz = "*" +textual = "*" +tomli = "*" +twine = "*" +vega_datasets = "*" +vtk = "*" +watchfiles = "*" +xarray = "*" +xgboost = "*" + +[feature.all_pip.dependencies] +aiohttp = "*" +altair = "*" +anywidget = "*" +channels = "*" +croniter = "*" +dask-expr = "*" +datashader = "*" +diskcache = "*" +django = "<4" +fastparquet = "*" +flake8 = "*" +folium = "*" +graphviz = "*" +holoviews = ">=1.16.0" +hvplot = "*" +ipyleaflet = "*" +ipympl = "*" +ipython = ">=7.0" +ipyvolume = "*" +ipyvuetify = "*" +ipywidgets = "*" +ipywidgets_bokeh = "*" +jupyter-server = "*" +jupyter_bokeh = ">=3.0.7" +jupyterlab = "*" +lxml = "*" +matplotlib = "*" +nbsite = ">=0.8.4" +nbval = "*" +networkx = ">=2.5" +numba = "<0.58" +numpy = "*" +pandas = ">=1.3" +parameterized = "*" +pillow = "*" +playwright = "*" +plotly = ">=4.0" +pre-commit = "*" +psutil = "*" +pydeck = "*" +pyinstrument = ">=4.0" +pytest = "*" +pytest-asyncio = "<0.22" +pytest-cov = "*" +pytest-playwright = "*" +pytest-rerunfailures = "*" +pytest-xdist = "*" +pyvista = "*" +reacton = "*" +scikit-image = "*" +scikit-learn = "*" +scipy = "*" +seaborn = "*" +streamz = "*" +textual = "*" +tomli = "*" +twine = "*" +vega_datasets = "*" +vtk = "*" +watchfiles = "*" +xarray = "*" +xgboost = "*" + +[feature.build.dependencies] +param = ">=2.0.0" +setuptools = ">=42" +requests = "*" +packaging = "*" +bokeh = ">=3.4.0,<3.5.0" +pyviz_comms = ">=2.0.0" +bleach = "*" +markdown = "*" +tqdm = ">=4.48.0" +cryptography = "<39" +urllib3 = "<2.0" From 01e8786a7f8b67ff70bf56b21ce2206ba85b6668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 14:12:29 +0200 Subject: [PATCH 002/130] Clean up dependencies, align with HoloViews - Removed duplicated from features --- pixi.toml | 290 ++++++++++++++++++------------------------------------ 1 file changed, 97 insertions(+), 193 deletions(-) diff --git a/pixi.toml b/pixi.toml index f2186fd706..44d7603a8b 100644 --- a/pixi.toml +++ b/pixi.toml @@ -1,8 +1,28 @@ +[project] +name = "panel" +channels = ["conda-forge", "pyviz/label/dev", "bokeh"] +platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"] + +[tasks] +download-data = 'bokeh sampledata' +install = 'python -m pip install --no-deps --disable-pip-version-check -e .' + +[environments] +test-39 = ["py39", "test-core", "test", "example", "test-example", "test-unit-task"] +test-310 = ["py310", "test-core", "test", "example", "test-example", "test-unit-task"] +test-311 = ["py311", "test-core", "test", "example", "test-example", "test-unit-task"] +test-312 = ["py312", "test-core", "test", "example", "test-example", "test-unit-task"] +test-ui = ["py312", "test-core", "test", "test-ui"] +test-core = ["py312", "test-core", "test-unit-task"] +docs = ["py311", "example", "doc"] +build = ["py311", "build"] +lint = ["py311", "lint"] + [dependencies] bokeh = ">=3.4.0,<3.5.0" param = ">=2.0.0,<3.0" pyviz_comms = ">=2.0.0" -xyzservices = ">=2021.09.1" +xyzservices = ">=2021.09.1" # Bokeh dependency, but pyodide 23.0.0 does not always pick it up markdown = "*" markdown-it-py = "*" linkify-it-py = "*" @@ -12,11 +32,27 @@ tqdm = ">=4.48.0" bleach = "*" typing_extensions = "*" pandas = ">=1.2" +# Recommended +jupyterlab = "*" +panel = ">=1.16.0" +matplotlib = "*" +pillow = "*" +plotly = ">=4.0" + +[feature.py39.dependencies] +python = "3.9.*" + +[feature.py310.dependencies] +python = "3.10.*" + +[feature.py311.dependencies] +python = "3.11.*" + +[feature.py312.dependencies] +python = "3.12.*" -[feature.examples.dependencies] -holoviews = ">=1.16.0" +[feature.example.dependencies] hvplot = "*" -plotly = ">=4.0" altair = "*" streamz = "*" vega_datasets = "*" @@ -24,8 +60,6 @@ vtk = "*" scikit-learn = "*" datashader = "*" jupyter_bokeh = ">=3.0.7" -django = "<4" -channels = "*" pyvista = "*" ipywidgets = "*" ipywidgets_bokeh = "*" @@ -51,220 +85,90 @@ fastparquet = "*" textual = "*" dask-expr = "*" -[feature.tests_core.dependencies] -flake8 = "*" -parameterized = "*" +# ============================================= +# =================== TESTS =================== +# ============================================= +[feature.test_core.dependencies] pytest = "*" -nbval = "*" pytest-rerunfailures = "*" pytest-asyncio = "<0.22" pytest-xdist = "*" pytest-cov = "*" -pre-commit = "*" psutil = "*" altair = "*" anywidget = "*" -folium = "*" diskcache = "*" -holoviews = ">=1.16.0" -numpy = "*" -pandas = ">=1.3" -ipython = ">=7.0" -scipy = "*" -textual = "*" watchfiles = "*" -[feature.tests.dependencies] -flake8 = "*" -parameterized = "*" -pytest = "*" -nbval = "*" -pytest-rerunfailures = "*" -pytest-asyncio = "<0.22" -pytest-xdist = "*" -pytest-cov = "*" -pre-commit = "*" -psutil = "*" -altair = "*" -anywidget = "*" +[feature.test.dependencies] folium = "*" -diskcache = "*" -holoviews = ">=1.16.0" -numpy = "*" -pandas = ">=1.3" -ipython = ">=7.0" scipy = "*" textual = "*" -watchfiles = "*" ipympl = "*" ipyvuetify = "*" ipywidgets_bokeh = "*" reacton = "*" twine = "*" -numba = "<0.58" +numba = "<0.58" # Temporary pins -[feature.recommended.dependencies] -jupyterlab = "*" -holoviews = ">=1.16.0" -matplotlib = "*" -pillow = "*" -plotly = "*" +# [feature.test-unit-task.tasks] +# test-unit = 'pytest panel' # So it not showing up for UI tests -[feature.doc.dependencies] -jupyterlab = "*" -holoviews = ">=1.16.0" -matplotlib = "*" -pillow = "*" -plotly = "*" -nbsite = ">=0.8.4" -lxml = "*" -pandas = "<2.1.0" +# [feature.test-example.tasks] +# test-example = 'pytest -n auto --dist loadscope --nbval-lax example' -[feature.ui.dependencies] -jupyter-server = "*" -playwright = "*" -pytest-playwright = "*" -tomli = "*" - -[feature.all.dependencies] -aiohttp = "*" -altair = "*" -anywidget = "*" -channels = "*" -croniter = "*" -dask-expr = "*" -datashader = "*" -diskcache = "*" -django = "<4" -fastparquet = "*" -flake8 = "*" -folium = "*" -graphviz = "*" -holoviews = ">=1.16.0" -hvplot = "*" -ipyleaflet = "*" -ipympl = "*" -ipython = ">=7.0" -ipyvolume = "*" -ipyvuetify = "*" -ipywidgets = "*" -ipywidgets_bokeh = "*" -jupyter-server = "*" -jupyter_bokeh = ">=3.0.7" -jupyterlab = "*" -lxml = "*" -matplotlib = "*" -nbsite = ">=0.8.4" +[feature.test-example.dependencies] nbval = "*" -networkx = ">=2.5" -numba = "<0.58" -numpy = "*" -pandas = ">=1.3" -parameterized = "*" -pillow = "*" + +[feature.test-ui] +channels = ["conda-forge", "pyviz/label/dev", "microsoft"] + +[feature.test-ui.dependencies] playwright = "*" -plotly = ">=4.0" -pre-commit = "*" -psutil = "*" -pydeck = "*" -pygraphviz = "*" -pyinstrument = ">=4.0" -pytest = "*" -pytest-asyncio = "<0.22" -pytest-cov = "*" pytest-playwright = "*" -pytest-rerunfailures = "*" -pytest-xdist = "*" -python-graphviz = "*" -pyvista = "*" -reacton = "*" -scikit-image = "*" -scikit-learn = "*" -scipy = "*" -seaborn = "*" -streamz = "*" -textual = "*" +jupyter-server = "*" tomli = "*" -twine = "*" -vega_datasets = "*" -vtk = "*" -watchfiles = "*" -xarray = "*" -xgboost = "*" -[feature.all_pip.dependencies] -aiohttp = "*" -altair = "*" -anywidget = "*" -channels = "*" -croniter = "*" -dask-expr = "*" -datashader = "*" -diskcache = "*" -django = "<4" -fastparquet = "*" -flake8 = "*" -folium = "*" -graphviz = "*" -holoviews = ">=1.16.0" -hvplot = "*" -ipyleaflet = "*" -ipympl = "*" -ipython = ">=7.0" -ipyvolume = "*" -ipyvuetify = "*" -ipywidgets = "*" -ipywidgets_bokeh = "*" -jupyter-server = "*" -jupyter_bokeh = ">=3.0.7" -jupyterlab = "*" -lxml = "*" -matplotlib = "*" +[feature.test-ui.tasks] +install-ui = 'playwright install chromium' + +[feature.test-ui.tasks.test-ui] +cmd = 'pytest panel/tests/ui --ui --browser chromium' +depends_on = ["install-ui"] + +# ============================================= +# =================== DOCS ==================== +# ============================================= +[feature.doc.dependencies] nbsite = ">=0.8.4" -nbval = "*" -networkx = ">=2.5" -numba = "<0.58" -numpy = "*" -pandas = ">=1.3" -parameterized = "*" -pillow = "*" -playwright = "*" -plotly = ">=4.0" -pre-commit = "*" -psutil = "*" -pydeck = "*" -pyinstrument = ">=4.0" -pytest = "*" -pytest-asyncio = "<0.22" -pytest-cov = "*" -pytest-playwright = "*" -pytest-rerunfailures = "*" -pytest-xdist = "*" -pyvista = "*" -reacton = "*" -scikit-image = "*" -scikit-learn = "*" -scipy = "*" -seaborn = "*" -streamz = "*" -textual = "*" -tomli = "*" -twine = "*" -vega_datasets = "*" -vtk = "*" -watchfiles = "*" -xarray = "*" -xgboost = "*" +lxml = "*" +pandas = "<2.1.0" # Avoid deprecation warnings + +# [feature.doc.tasks] +# docs-generate-rst = 'nbsite generate-rst --org holoviz --project-name panel' +# docs-refmanual = 'python ./doc/generate_modules.py panel -d ./doc/reference_manual -n panel -e tests' +# docs-generate = 'nbsite build --what=html --output=builtdocs --org holoviz --project-name panel' + +# [feature.doc.tasks.docs-build] +# depends_on = ['docs-generate-rst', 'docs-refmanual', 'docs-generate'] +# ============================================= +# ================== BUILD ==================== +# ============================================= [feature.build.dependencies] -param = ">=2.0.0" -setuptools = ">=42" -requests = "*" -packaging = "*" -bokeh = ">=3.4.0,<3.5.0" -pyviz_comms = ">=2.0.0" -bleach = "*" -markdown = "*" -tqdm = ">=4.48.0" -cryptography = "<39" -urllib3 = "<2.0" +build = "*" +conda-build = "*" + +# [feature.build.tasks] +# build-conda = 'bash scripts/conda/build.sh' +# build-pip = 'python -m build .' + +# ============================================= +# =================== LINT ==================== +# ============================================= +[feature.lint.dependencies] +pre-commit = "*" + +# [feature.lint.tasks] +# lint = 'pre-commit run --all-files' +# lint-install = 'pre-commit install' From 0cfa04ce2871723e4ac3724790aea6aaa773659f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 14:32:20 +0200 Subject: [PATCH 003/130] Add tasks to tests --- pixi.toml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pixi.toml b/pixi.toml index 44d7603a8b..73b7f9db50 100644 --- a/pixi.toml +++ b/pixi.toml @@ -111,11 +111,13 @@ reacton = "*" twine = "*" numba = "<0.58" # Temporary pins -# [feature.test-unit-task.tasks] -# test-unit = 'pytest panel' # So it not showing up for UI tests +[feature.test-unit-task.tasks] # So it not showing up for UI tests +test-unit = 'pytest panel/tests -n logical --dist loadgroup' +test-subprocess = 'pytest panel/tests --subprocess' -# [feature.test-example.tasks] -# test-example = 'pytest -n auto --dist loadscope --nbval-lax example' +[feature.test-example.tasks] +test-docs = 'pytest panel/tests --docs' +test-example = 'pytest -n logical --dist loadscope --nbval-lax example' [feature.test-example.dependencies] nbval = "*" @@ -133,7 +135,7 @@ tomli = "*" install-ui = 'playwright install chromium' [feature.test-ui.tasks.test-ui] -cmd = 'pytest panel/tests/ui --ui --browser chromium' +cmd = 'pytest panel/tests/ui --ui --browser chromium -n logical --dist loadgroup--reruns 3 --reruns-delay 10' depends_on = ["install-ui"] # ============================================= From 31cc42c267fd49e81cffe6694039bdeac3fbd177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 14:42:54 +0200 Subject: [PATCH 004/130] Run pixi install and fixes to make it work --- .gitignore | 4 ++++ pixi.toml | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 28a2d536c4..71796172f8 100644 --- a/.gitignore +++ b/.gitignore @@ -155,3 +155,7 @@ doc/reference/* .jupyter/* app_panel.py app_streamlit.py + +# pixi +.pixi +pixi.lock diff --git a/pixi.toml b/pixi.toml index 73b7f9db50..c452ebd774 100644 --- a/pixi.toml +++ b/pixi.toml @@ -34,7 +34,7 @@ typing_extensions = "*" pandas = ">=1.2" # Recommended jupyterlab = "*" -panel = ">=1.16.0" +holoviews = ">=1.16.0" matplotlib = "*" pillow = "*" plotly = ">=4.0" @@ -88,7 +88,7 @@ dask-expr = "*" # ============================================= # =================== TESTS =================== # ============================================= -[feature.test_core.dependencies] +[feature.test-core.dependencies] pytest = "*" pytest-rerunfailures = "*" pytest-asyncio = "<0.22" @@ -109,7 +109,7 @@ ipyvuetify = "*" ipywidgets_bokeh = "*" reacton = "*" twine = "*" -numba = "<0.58" # Temporary pins +numba = "*" [feature.test-unit-task.tasks] # So it not showing up for UI tests test-unit = 'pytest panel/tests -n logical --dist loadgroup' @@ -128,7 +128,7 @@ channels = ["conda-forge", "pyviz/label/dev", "microsoft"] [feature.test-ui.dependencies] playwright = "*" pytest-playwright = "*" -jupyter-server = "*" +jupyter_server = "*" tomli = "*" [feature.test-ui.tasks] From b7d4b18be995ffb8d3bff846449971318d5834a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 15:01:19 +0200 Subject: [PATCH 005/130] Run test and lint tasks --- pixi.toml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pixi.toml b/pixi.toml index c452ebd774..1f23f644f4 100644 --- a/pixi.toml +++ b/pixi.toml @@ -85,6 +85,9 @@ fastparquet = "*" textual = "*" dask-expr = "*" +# [feature.example.pypi-dependencies] +# pyecharts = "*" + # ============================================= # =================== TESTS =================== # ============================================= @@ -117,7 +120,7 @@ test-subprocess = 'pytest panel/tests --subprocess' [feature.test-example.tasks] test-docs = 'pytest panel/tests --docs' -test-example = 'pytest -n logical --dist loadscope --nbval-lax example' +test-example = 'pytest -n logical --dist loadscope --nbval-lax examples' [feature.test-example.dependencies] nbval = "*" @@ -171,6 +174,6 @@ conda-build = "*" [feature.lint.dependencies] pre-commit = "*" -# [feature.lint.tasks] -# lint = 'pre-commit run --all-files' -# lint-install = 'pre-commit install' +[feature.lint.tasks] +lint = 'pre-commit run --all-files' +lint-install = 'pre-commit install' From f071b863234efa1ad888ef8b85900b67c8face3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 17:41:26 +0200 Subject: [PATCH 006/130] Update pixi.toml with docs steps --- pixi.toml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/pixi.toml b/pixi.toml index 1f23f644f4..7bbb70bb30 100644 --- a/pixi.toml +++ b/pixi.toml @@ -38,6 +38,8 @@ holoviews = ">=1.16.0" matplotlib = "*" pillow = "*" plotly = ">=4.0" +packaging = "*" +watchfiles = "*" [feature.py39.dependencies] python = "3.9.*" @@ -101,7 +103,6 @@ psutil = "*" altair = "*" anywidget = "*" diskcache = "*" -watchfiles = "*" [feature.test.dependencies] folium = "*" @@ -111,7 +112,6 @@ ipympl = "*" ipyvuetify = "*" ipywidgets_bokeh = "*" reacton = "*" -twine = "*" numba = "*" [feature.test-unit-task.tasks] # So it not showing up for UI tests @@ -132,7 +132,6 @@ channels = ["conda-forge", "pyviz/label/dev", "microsoft"] playwright = "*" pytest-playwright = "*" jupyter_server = "*" -tomli = "*" [feature.test-ui.tasks] install-ui = 'playwright install chromium' @@ -149,13 +148,15 @@ nbsite = ">=0.8.4" lxml = "*" pandas = "<2.1.0" # Avoid deprecation warnings -# [feature.doc.tasks] -# docs-generate-rst = 'nbsite generate-rst --org holoviz --project-name panel' -# docs-refmanual = 'python ./doc/generate_modules.py panel -d ./doc/reference_manual -n panel -e tests' -# docs-generate = 'nbsite build --what=html --output=builtdocs --org holoviz --project-name panel' +[feature.doc.tasks] +docs-refmanual = 'python ./doc/generate_modules.py panel -d ./doc/api -n panel -e tests' +docs-convert-gallery = 'python scripts/gallery/convert_gallery.py' +docs-generate = 'nbsite build --what=html --output=builtdocs --org holoviz --project-name panel' +docs-copy-panel-dist = 'cp -r ./panel/dist ./builtdocs/panel_dist' +docs-pyodide = 'panel convert examples/gallery/*.ipynb doc/how_to/*/examples/*.md --to pyodide-worker --out ./builtdocs/pyodide/ --pwa --index --requirements doc/pyodide_dependencies.json' -# [feature.doc.tasks.docs-build] -# depends_on = ['docs-generate-rst', 'docs-refmanual', 'docs-generate'] +[feature.doc.tasks.docs-build] +depends_on = ['docs-refmanual', 'docs-convert-gallery', 'docs-generate', 'docs-copy-panel-dist', 'docs-pyodide'] # ============================================= # ================== BUILD ==================== @@ -167,6 +168,7 @@ conda-build = "*" # [feature.build.tasks] # build-conda = 'bash scripts/conda/build.sh' # build-pip = 'python -m build .' +# build-pyodide = 'python scripts/build_pyodide_wheels.py' # ============================================= # =================== LINT ==================== From b216be9ffb6801cf7d841a125349c5cedd7371c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 19:37:04 +0200 Subject: [PATCH 007/130] Small updates to dependencies - Also marking a scipy dependent test as skipif --- panel/tests/pane/test_plotly.py | 3 +++ pixi.toml | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/panel/tests/pane/test_plotly.py b/panel/tests/pane/test_plotly.py index 117404ca0c..88690bc9e0 100644 --- a/panel/tests/pane/test_plotly.py +++ b/panel/tests/pane/test_plotly.py @@ -1,5 +1,7 @@ import datetime as dt +from importlib.util import find_spec + import pytest try: @@ -211,6 +213,7 @@ def test_clean_relayout_data(): } +@pytest.mark.skipif(not find_spec("scipy"), reason="requires scipy") @plotly_available def test_plotly_swap_traces(document, comm): data_bar = pd.DataFrame({'Count': [1, 2, 3, 4], 'Category': ["A", "B", "C", "D"]}) diff --git a/pixi.toml b/pixi.toml index 7bbb70bb30..e154186cec 100644 --- a/pixi.toml +++ b/pixi.toml @@ -22,7 +22,6 @@ lint = ["py311", "lint"] bokeh = ">=3.4.0,<3.5.0" param = ">=2.0.0,<3.0" pyviz_comms = ">=2.0.0" -xyzservices = ">=2021.09.1" # Bokeh dependency, but pyodide 23.0.0 does not always pick it up markdown = "*" markdown-it-py = "*" linkify-it-py = "*" @@ -96,9 +95,10 @@ dask-expr = "*" [feature.test-core.dependencies] pytest = "*" pytest-rerunfailures = "*" -pytest-asyncio = "<0.22" +pytest-asyncio = "*" pytest-xdist = "*" pytest-cov = "*" +pytest-github-actions-annotate-failures = "*" psutil = "*" altair = "*" anywidget = "*" @@ -114,7 +114,7 @@ ipywidgets_bokeh = "*" reacton = "*" numba = "*" -[feature.test-unit-task.tasks] # So it not showing up for UI tests +[feature.test-unit-task.tasks] # So it is not showing up in the test-ui environment test-unit = 'pytest panel/tests -n logical --dist loadgroup' test-subprocess = 'pytest panel/tests --subprocess' From 98558a5c89c9a9b9646f1fe89aafa7e4444f9b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 19:51:02 +0200 Subject: [PATCH 008/130] Move project stuff to pyproject.toml --- pyproject.toml | 75 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 489321485f..99f3e67b26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,85 @@ [build-system] requires = [ + "hatchling", + "hatch-vcs", "param >=2.0.0", - "pyct >=0.4.4", - "setuptools >=42", "bokeh >=3.4.0,<3.5.0", "pyviz_comms >=0.7.4", "requests", "packaging", "tqdm >=4.48.0", "markdown", - "wheel" ] +build-backend = "hatchling.build" + +[project] +name = "panel" +dynamic = ["version"] +description = 'The powerful data exploration & web app framework for Python.' +readme = "README.md" +license = { text = "BSD" } +requires-python = ">=3.9" +authors = [{ name = "HoloViz developers", email = "developers@holoviz.org" }] +maintainers = [ + { name = "HoloViz developers", email = "developers@holoviz.org" }, +] +classifiers = [ + "License :: OSI Approved :: BSD License", + "Development Status :: 5 - Production/Stable", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Operating System :: OS Independent", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Intended Audience :: Financial and Insurance Industry", + "Intended Audience :: Healthcare Industry", + "Intended Audience :: Information Technology", + "Intended Audience :: Legal Industry", + "Intended Audience :: Other Audience", + "Intended Audience :: Science/Research", + "Natural Language :: English", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Visualization", + "Topic :: Scientific/Engineering :: Information Analysis", + "Topic :: Office/Business", + "Topic :: Office/Business :: Financial", + "Topic :: Software Development :: Libraries", +] + +dependencies = [ + 'bokeh >=3.4.0,<3.5.0', + 'param >=2.0.0,<3.0', + 'pyviz_comms >=2.0.0', + 'xyzservices >=2021.09.1', # Bokeh dependency, but pyodide 23.0.0 does not always pick it up + 'markdown', + 'markdown-it-py', + 'linkify-it-py', + 'mdit-py-plugins', + 'requests', + 'tqdm >=4.48.0', + 'bleach', + 'typing_extensions', + 'pandas >=1.2', +] + +[project.urls] +Homepage = "https://panel.holoviz.org" +Source = "http://github.com/holoviz/panel" +HoloViz = "https://holoviz.org/" + +[project.optional-dependencies] +recommended = [ + 'jupyterlab', + 'holoviews >=1.16.0', + 'matplotlib', + 'pillow', + 'plotly', +] +[project.scripts] +panel = "panel.util.command:main" [tool.ruff] exclude = [ From db0183f7a0ea967d3f5d7f15bc624f2e6f6d6c2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 19:53:54 +0200 Subject: [PATCH 009/130] Add initial hatch setting to pyproject.toml --- .gitignore | 1 + pyproject.toml | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/.gitignore b/.gitignore index 71796172f8..e17944a61c 100644 --- a/.gitignore +++ b/.gitignore @@ -159,3 +159,4 @@ app_streamlit.py # pixi .pixi pixi.lock +panel/_version.py diff --git a/pyproject.toml b/pyproject.toml index 99f3e67b26..7e8f1119b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,9 +78,22 @@ recommended = [ 'pillow', 'plotly', ] + [project.scripts] panel = "panel.util.command:main" +[tool.hatch.version] +source = "vcs" + +[tool.hatch.build.targets.wheel] +include = ["panel"] + +[tool.hatch.build.targets.sdist] +include = ["panel"] + +[tool.hatch.build.hooks.vcs] +version-file = "panel/_version.py" + [tool.ruff] exclude = [ ".git", From 26af6a19547ee8beef4e0a8e18dd95fcff00685f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 20:01:13 +0200 Subject: [PATCH 010/130] Add nodejs and fix scripts path --- pixi.toml | 1 + pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index e154186cec..154381f079 100644 --- a/pixi.toml +++ b/pixi.toml @@ -19,6 +19,7 @@ build = ["py311", "build"] lint = ["py311", "lint"] [dependencies] +nodejs= ">=20" bokeh = ">=3.4.0,<3.5.0" param = ">=2.0.0,<3.0" pyviz_comms = ">=2.0.0" diff --git a/pyproject.toml b/pyproject.toml index 7e8f1119b2..4eaf8a9605 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,7 +80,7 @@ recommended = [ ] [project.scripts] -panel = "panel.util.command:main" +panel = "panel.command:main" [tool.hatch.version] source = "vcs" From 68c69649fb265f4c3e0b9c6e41e44a66f406a9e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 20:39:29 +0200 Subject: [PATCH 011/130] Add build hook script --- pyproject.toml | 4 ++ scripts/hatch_build.py | 84 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 scripts/hatch_build.py diff --git a/pyproject.toml b/pyproject.toml index 4eaf8a9605..54eef7fcd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,6 +94,9 @@ include = ["panel"] [tool.hatch.build.hooks.vcs] version-file = "panel/_version.py" +[tool.hatch.build.hooks.custom] +path = "scripts/hatch_build.py" + [tool.ruff] exclude = [ ".git", @@ -138,6 +141,7 @@ select = [ "panel/compiler.py" = ["T201"] "panel/io/convert.py" = ["T201"] "panel/pane/vtk/synchronizable_*.py" = ["T201"] +"scripts/hatch_build.py" = ["T201"] [tool.codespell] ignore-words-list = "nd,doubleclick,ser" diff --git a/scripts/hatch_build.py b/scripts/hatch_build.py new file mode 100644 index 0000000000..1a1a8d0836 --- /dev/null +++ b/scripts/hatch_build.py @@ -0,0 +1,84 @@ +from __future__ import annotations + +import json +import os +import shutil +import sys +import typing as t + +from pathlib import Path + +from hatchling.builders.hooks.plugin.interface import BuildHookInterface + +BASE_DIR = Path(__file__).parents[1] + + +def build_paneljs(): + from bokeh.ext import build + + print("Building custom models:") + panel_dir = BASE_DIR / "panel" + build(panel_dir) + print("Bundling custom model resources:") + if sys.platform != "win32": + # npm can cause non-blocking stdout; so reset it just in case + import fcntl + + flags = fcntl.fcntl(sys.stdout, fcntl.F_GETFL) + fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags & ~os.O_NONBLOCK) + + +def install_jupyter_server_extension(): + # data_files are not copied for editable installs returning + files = setup_args["data_files"] + for dst, (src,) in files: + dst = os.path.join(sys.prefix, dst) + os.makedirs(dst, exist_ok=True) + shutil.copy2(src, dst) + print(f"Copied {src} to {dst}") + + +def clean_js_version(version): + version = version.replace("-", "") + for dev in ("a", "b", "rc"): + version = version.replace(dev + ".", dev) + return version + + +def validate_js_version(version): + if "post" not in version: + with open("./panel/package.json") as f: + package_json = json.load(f) + js_version = package_json["version"] + version = version.split("+")[0] + if any(dev in version for dev in ("a", "b", "rc")) and "-" not in js_version: + raise ValueError(f"panel.js dev versions ({js_version}) must " "must separate dev suffix with a dash, e.g. " "v1.0.0rc1 should be v1.0.0-rc.1.") + if version != "None" and version != clean_js_version(js_version): + raise ValueError(f"panel.js version ({js_version}) does not match " f"panel version ({version}). Cannot build release.") + + +class BuildHook(BuildHookInterface): + """The hatch jupyter builder build hook.""" + + PLUGIN_NAME = "install" + + def initialize(self, version: str, build_data: dict[str, t.Any]) -> None: + """Initialize the plugin.""" + if self.target_name not in ["wheel", "sdist"]: + return + + validate_js_version(self.metadata.version) + + if version == "editable": + ... + # install_jupyter_server_extension() + + def finalize(self, version: str, build_data: dict[str, t.Any], artifact_path: str) -> None: + """Finalize the plugin.""" + if self.target_name not in ["wheel", "sdist"]: + return + + sys.path.insert(0, str(BASE_DIR)) + from panel.compiler import bundle_resources + + bundle_resources(verbose=True) From 6f2996ed2397ce297d0eadc217489cea7dacf49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 20:50:26 +0200 Subject: [PATCH 012/130] Update validate js version --- scripts/hatch_build.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/scripts/hatch_build.py b/scripts/hatch_build.py index 1a1a8d0836..9885b0185f 100644 --- a/scripts/hatch_build.py +++ b/scripts/hatch_build.py @@ -46,15 +46,16 @@ def clean_js_version(version): def validate_js_version(version): - if "post" not in version: - with open("./panel/package.json") as f: - package_json = json.load(f) - js_version = package_json["version"] - version = version.split("+")[0] - if any(dev in version for dev in ("a", "b", "rc")) and "-" not in js_version: - raise ValueError(f"panel.js dev versions ({js_version}) must " "must separate dev suffix with a dash, e.g. " "v1.0.0rc1 should be v1.0.0-rc.1.") - if version != "None" and version != clean_js_version(js_version): - raise ValueError(f"panel.js version ({js_version}) does not match " f"panel version ({version}). Cannot build release.") + # TODO: Double check the logic in this function + version = version.split(".dev")[0] + with open("./panel/package.json") as f: + package_json = json.load(f) + js_version = package_json["version"] + version = version.split("+")[0] + if any(dev in version for dev in ("a", "b", "rc")) and "-" not in js_version: + raise ValueError(f"panel.js dev versions ({js_version}) must separate dev suffix with a dash, e.g. v1.0.0rc1 should be v1.0.0-rc.1.") + if version != "None" and version != clean_js_version(js_version): + raise ValueError(f"panel.js version ({js_version}) does not match panel version ({version}). Cannot build release.") class BuildHook(BuildHookInterface): From 7a86621b80b46c74a6145b762438c7062ba4a79b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 20 Apr 2024 20:58:34 +0200 Subject: [PATCH 013/130] Add pip --- pixi.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pixi.toml b/pixi.toml index 154381f079..08fa7a7c24 100644 --- a/pixi.toml +++ b/pixi.toml @@ -20,6 +20,7 @@ lint = ["py311", "lint"] [dependencies] nodejs= ">=20" +pip = "*" bokeh = ">=3.4.0,<3.5.0" param = ">=2.0.0,<3.0" pyviz_comms = ">=2.0.0" From 8a8afd350296aa7a694c9251da075523cd535ddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 14:25:18 +0200 Subject: [PATCH 014/130] Sort dependencies in pyproject.toml and pixi.toml Also adding pyecharts to pixi.toml Adding packaging as required dependency in pyproject.toml --- pixi.toml | 86 ++++++++++++++++++++++++-------------------------- pyproject.toml | 1 + 2 files changed, 43 insertions(+), 44 deletions(-) diff --git a/pixi.toml b/pixi.toml index 08fa7a7c24..7b3399ec8f 100644 --- a/pixi.toml +++ b/pixi.toml @@ -19,27 +19,27 @@ build = ["py311", "build"] lint = ["py311", "lint"] [dependencies] -nodejs= ">=20" -pip = "*" +bleach = "*" bokeh = ">=3.4.0,<3.5.0" -param = ">=2.0.0,<3.0" -pyviz_comms = ">=2.0.0" +linkify-it-py = "*" markdown = "*" markdown-it-py = "*" -linkify-it-py = "*" mdit-py-plugins = "*" +nodejs= ">=20" +packaging = "*" +pandas = ">=1.2" +param = ">=2.0.0,<3.0" +pip = "*" +pyviz_comms = ">=2.0.0" requests = "*" tqdm = ">=4.48.0" -bleach = "*" typing_extensions = "*" -pandas = ">=1.2" # Recommended -jupyterlab = "*" holoviews = ">=1.16.0" +jupyterlab = "*" matplotlib = "*" pillow = "*" plotly = ">=4.0" -packaging = "*" watchfiles = "*" [feature.py39.dependencies] @@ -55,66 +55,64 @@ python = "3.11.*" python = "3.12.*" [feature.example.dependencies] -hvplot = "*" +aiohttp = "*" altair = "*" -streamz = "*" -vega_datasets = "*" -vtk = "*" -scikit-learn = "*" +croniter = "*" +dask-expr = "*" datashader = "*" -jupyter_bokeh = ">=3.0.7" -pyvista = "*" -ipywidgets = "*" -ipywidgets_bokeh = "*" -ipyvolume = "*" -ipyleaflet = "*" -ipympl = "*" +fastparquet = "*" folium = "*" -xarray = "*" -pyinstrument = ">=4.0" -aiohttp = "*" -croniter = "*" graphviz = "*" +hvplot = "*" +ipyleaflet = "*" +ipympl = "*" +ipyvolume = "*" +ipyvuetify = "*" +ipywidgets = "*" +ipywidgets_bokeh = "*" +jupyter_bokeh = ">=3.0.7" networkx = ">=2.5" -pygraphviz = "*" -seaborn = "*" pydeck = "*" +pyecharts = "*" +pygraphviz = "*" +pyinstrument = ">=4.0" python-graphviz = "*" -xgboost = "*" -ipyvuetify = "*" +pyvista = "*" reacton = "*" scikit-image = "*" -fastparquet = "*" +scikit-learn = "*" +seaborn = "*" +streamz = "*" textual = "*" -dask-expr = "*" - -# [feature.example.pypi-dependencies] -# pyecharts = "*" +vega_datasets = "*" +vtk = "*" +xarray = "*" +xgboost = "*" # ============================================= # =================== TESTS =================== # ============================================= [feature.test-core.dependencies] +altair = "*" +anywidget = "*" +diskcache = "*" +psutil = "*" pytest = "*" -pytest-rerunfailures = "*" pytest-asyncio = "*" -pytest-xdist = "*" pytest-cov = "*" pytest-github-actions-annotate-failures = "*" -psutil = "*" -altair = "*" -anywidget = "*" -diskcache = "*" +pytest-rerunfailures = "*" +pytest-xdist = "*" [feature.test.dependencies] folium = "*" -scipy = "*" -textual = "*" ipympl = "*" ipyvuetify = "*" ipywidgets_bokeh = "*" -reacton = "*" numba = "*" +reacton = "*" +scipy = "*" +textual = "*" [feature.test-unit-task.tasks] # So it is not showing up in the test-ui environment test-unit = 'pytest panel/tests -n logical --dist loadgroup' @@ -146,8 +144,8 @@ depends_on = ["install-ui"] # =================== DOCS ==================== # ============================================= [feature.doc.dependencies] -nbsite = ">=0.8.4" lxml = "*" +nbsite = ">=0.8.4" pandas = "<2.1.0" # Avoid deprecation warnings [feature.doc.tasks] diff --git a/pyproject.toml b/pyproject.toml index 54eef7fcd0..de6bce51d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,6 +63,7 @@ dependencies = [ 'bleach', 'typing_extensions', 'pandas >=1.2', + 'packaging', ] [project.urls] From 0643f994f56e80569baaa390654ccd1fb7cf1d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 14:51:06 +0200 Subject: [PATCH 015/130] Small updates to pyproject.toml --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index de6bce51d1..8632d03b20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,6 +78,7 @@ recommended = [ 'matplotlib', 'pillow', 'plotly', + 'watchfiles', ] [project.scripts] @@ -142,7 +143,7 @@ select = [ "panel/compiler.py" = ["T201"] "panel/io/convert.py" = ["T201"] "panel/pane/vtk/synchronizable_*.py" = ["T201"] -"scripts/hatch_build.py" = ["T201"] +"scripts/*.py" = ["T201"] [tool.codespell] ignore-words-list = "nd,doubleclick,ser" From 20bf27d72e90faa0ce3aafe2a3d62fa4b2606e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 15:10:46 +0200 Subject: [PATCH 016/130] Remove tqdm and markdown for build-system --- panel/io/mime_render.py | 3 +-- panel/widgets/indicators.py | 9 +++++++-- pixi.toml | 2 +- pyproject.toml | 3 --- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/panel/io/mime_render.py b/panel/io/mime_render.py index 734fc9f253..23deabf216 100644 --- a/panel/io/mime_render.py +++ b/panel/io/mime_render.py @@ -27,8 +27,6 @@ from textwrap import dedent from typing import Any, Dict, List -import markdown - #--------------------------------------------------------------------- # Import API #--------------------------------------------------------------------- @@ -228,6 +226,7 @@ def render_javascript(value, meta, mime): return f'', 'text/html' def render_markdown(value, meta, mime): + import markdown return (markdown.markdown( value, extensions=["extra", "smarty", "codehilite"], output_format='html5' ), 'text/html') diff --git a/panel/widgets/indicators.py b/panel/widgets/indicators.py index d7d88d0182..cca452f979 100644 --- a/panel/widgets/indicators.py +++ b/panel/widgets/indicators.py @@ -33,7 +33,6 @@ from bokeh.models import ColumnDataSource, FixedTicker, Tooltip from bokeh.plotting import figure -from tqdm.asyncio import tqdm as _tqdm from .._param import Align from ..io.resources import CDN_DIST @@ -54,6 +53,10 @@ from bokeh.document import Document from bokeh.model import Model from pyviz_comms import Comm +try: + from tqdm.asyncio import tqdm as _tqdm +except ImportError: + _tqdm = None RED = "#d9534f" GREEN = "#5cb85c" @@ -1205,9 +1208,11 @@ def _process_param_change(self, msg): -class ptqdm(_tqdm): +class ptqdm(_tqdm or object): def __init__(self, *args, **kwargs): + if _tqdm is None: + raise ImportError("tqdm is required for this indicator") self._indicator = kwargs.pop('indicator') super().__init__(*args, **kwargs) diff --git a/pixi.toml b/pixi.toml index 7b3399ec8f..bc764eb8b5 100644 --- a/pixi.toml +++ b/pixi.toml @@ -32,7 +32,6 @@ param = ">=2.0.0,<3.0" pip = "*" pyviz_comms = ">=2.0.0" requests = "*" -tqdm = ">=4.48.0" typing_extensions = "*" # Recommended holoviews = ">=1.16.0" @@ -84,6 +83,7 @@ scikit-learn = "*" seaborn = "*" streamz = "*" textual = "*" +tqdm = ">=4.48.0" vega_datasets = "*" vtk = "*" xarray = "*" diff --git a/pyproject.toml b/pyproject.toml index 8632d03b20..270fd93801 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,8 +7,6 @@ requires = [ "pyviz_comms >=0.7.4", "requests", "packaging", - "tqdm >=4.48.0", - "markdown", ] build-backend = "hatchling.build" @@ -59,7 +57,6 @@ dependencies = [ 'linkify-it-py', 'mdit-py-plugins', 'requests', - 'tqdm >=4.48.0', 'bleach', 'typing_extensions', 'pandas >=1.2', From f2535d8347ffdb2a3706d14391cabde279177d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 15:55:10 +0200 Subject: [PATCH 017/130] Add shared-data for jupyter-config --- pyproject.toml | 6 +++++- scripts/hatch_build.py | 15 --------------- .../jupyter-config/notebook.json | 0 .../jupyter-config/server.json | 0 4 files changed, 5 insertions(+), 16 deletions(-) rename jupyter-config/jupyter_notebook_config.d/panel-client-jupyter.json => scripts/jupyter-config/notebook.json (100%) rename jupyter-config/jupyter_server_config.d/panel-client-jupyter.json => scripts/jupyter-config/server.json (100%) diff --git a/pyproject.toml b/pyproject.toml index 270fd93801..3de09afae0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,8 +87,12 @@ source = "vcs" [tool.hatch.build.targets.wheel] include = ["panel"] +[tool.hatch.build.targets.wheel.shared-data] +"scripts/jupyter-config/notebook.json" = "etc/jupyter/jupyter_notebook_config.d/panel-client-jupyter.json" +"scripts/jupyter-config/server.json" = "etc/jupyter/jupyter_server_config.d/panel-client-jupyter.json" + [tool.hatch.build.targets.sdist] -include = ["panel"] +include = ["panel", "scripts"] [tool.hatch.build.hooks.vcs] version-file = "panel/_version.py" diff --git a/scripts/hatch_build.py b/scripts/hatch_build.py index 9885b0185f..5b40a31af8 100644 --- a/scripts/hatch_build.py +++ b/scripts/hatch_build.py @@ -2,7 +2,6 @@ import json import os -import shutil import sys import typing as t @@ -28,16 +27,6 @@ def build_paneljs(): fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags & ~os.O_NONBLOCK) -def install_jupyter_server_extension(): - # data_files are not copied for editable installs returning - files = setup_args["data_files"] - for dst, (src,) in files: - dst = os.path.join(sys.prefix, dst) - os.makedirs(dst, exist_ok=True) - shutil.copy2(src, dst) - print(f"Copied {src} to {dst}") - - def clean_js_version(version): version = version.replace("-", "") for dev in ("a", "b", "rc"): @@ -70,10 +59,6 @@ def initialize(self, version: str, build_data: dict[str, t.Any]) -> None: validate_js_version(self.metadata.version) - if version == "editable": - ... - # install_jupyter_server_extension() - def finalize(self, version: str, build_data: dict[str, t.Any], artifact_path: str) -> None: """Finalize the plugin.""" if self.target_name not in ["wheel", "sdist"]: diff --git a/jupyter-config/jupyter_notebook_config.d/panel-client-jupyter.json b/scripts/jupyter-config/notebook.json similarity index 100% rename from jupyter-config/jupyter_notebook_config.d/panel-client-jupyter.json rename to scripts/jupyter-config/notebook.json diff --git a/jupyter-config/jupyter_server_config.d/panel-client-jupyter.json b/scripts/jupyter-config/server.json similarity index 100% rename from jupyter-config/jupyter_server_config.d/panel-client-jupyter.json rename to scripts/jupyter-config/server.json From f9a25e69d6ab8e19df764d4699d70db9f522f986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 15:56:46 +0200 Subject: [PATCH 018/130] Add unfixable rules for ruff --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 3de09afae0..24fa4f919e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -138,6 +138,10 @@ select = [ "T20", "RUF006", ] +unfixable = [ + "F401", # Unused imports + "F841", # Unused variables +] [tool.ruff.lint.per-file-ignores] "panel/tests/ui/jupyter_server_test_config.py" = ["F821"] From df2937319b1f305d1676432b9c54d73527fac700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 15:57:14 +0200 Subject: [PATCH 019/130] Start enabling build --- pixi.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pixi.toml b/pixi.toml index bc764eb8b5..a2f30a67e5 100644 --- a/pixi.toml +++ b/pixi.toml @@ -165,9 +165,9 @@ depends_on = ['docs-refmanual', 'docs-convert-gallery', 'docs-generate', 'docs-c build = "*" conda-build = "*" -# [feature.build.tasks] +[feature.build.tasks] # build-conda = 'bash scripts/conda/build.sh' -# build-pip = 'python -m build .' +build-pip = 'python -m build .' # build-pyodide = 'python scripts/build_pyodide_wheels.py' # ============================================= From 2d86fd2cf4404437d80bc220ed5174833e5d78d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 16:01:01 +0200 Subject: [PATCH 020/130] Add boilerplate __version__ --- panel/__version.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ panel/config.py | 4 +--- 2 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 panel/__version.py diff --git a/panel/__version.py b/panel/__version.py new file mode 100644 index 0000000000..d593a9a5e3 --- /dev/null +++ b/panel/__version.py @@ -0,0 +1,44 @@ +"""Define the package version. + +Called __version.py as setuptools_scm will create a _version.py +""" + +import os.path + +PACKAGE = "panel" + +try: + # For performance reasons on imports, avoid importing setuptools_scm + # if not in a .git folder + if os.path.exists(os.path.join(os.path.dirname(__file__), "..", ".git")): + # If setuptools_scm is installed (e.g. in a development environment with + # an editable install), then use it to determine the version dynamically. + from setuptools_scm import get_version + + # This will fail with LookupError if the package is not installed in + # editable mode or if Git is not installed. + __version__ = get_version(root="..", relative_to=__file__) + else: + raise FileNotFoundError +except (ImportError, LookupError, FileNotFoundError): + # As a fallback, use the version that is hard-coded in the file. + try: + # __version__ was added in _version in setuptools-scm 7.0.0, we rely on + # the hopefully stable version variable. + from ._version import version as __version__ + except (ModuleNotFoundError, ImportError): + # Either _version doesn't exist (ModuleNotFoundError) or version isn't + # in _version (ImportError). ModuleNotFoundError is a subclass of + # ImportError, let's be explicit anyway. + + # Try something else: + from importlib.metadata import PackageNotFoundError, version + + try: + __version__ = version(PACKAGE) + except PackageNotFoundError: + # The user is probably trying to run this without having installed + # the package. + __version__ = "0.0.0+unknown" + +__all__ = ("__version__",) diff --git a/panel/config.py b/panel/config.py index 485aafdd9b..a0f5bcd2b5 100644 --- a/panel/config.py +++ b/panel/config.py @@ -25,13 +25,11 @@ JupyterCommManager as _JupyterCommManager, extension as _pyviz_extension, ) +from .__version import __version__ from .io.logging import panel_log_handler from .io.state import state from .util import param_watchers -__version__ = str(param.version.Version( - fpath=__file__, archive_commit="$Format:%h$", reponame="panel")) - _LOCAL_DEV_VERSION = ( any(v in __version__ for v in ('post', 'dirty')) and not state._is_pyodide From cc8de67684038cb241d3034dc72ae4cb3f7bb2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 16:09:23 +0200 Subject: [PATCH 021/130] Add isort setting to pyproject --- pyproject.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 24fa4f919e..abba7379d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -150,6 +150,13 @@ unfixable = [ "panel/pane/vtk/synchronizable_*.py" = ["T201"] "scripts/*.py" = ["T201"] +[tool.isort] +force_grid_wrap = 4 +multi_line_output = 5 +combine_as_imports = true +lines_between_types = 1 +include_trailing_comma = true + [tool.codespell] ignore-words-list = "nd,doubleclick,ser" skip = "doc/generate_modules.py,examples/reference/templates/FastGridTemplate.ipynb,panel/.eslintrc.js,panel/package-lock.json,panel/package.json" From 3bb2d8cc3348bba2522150c90378a6e08f0fbab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 16:10:17 +0200 Subject: [PATCH 022/130] Remove setup.cfg and setup.py --- setup.cfg | 22 ---- setup.py | 349 ------------------------------------------------------ 2 files changed, 371 deletions(-) delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index c6dee5db23..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,22 +0,0 @@ -[metadata] -license_files = LICENSE.txt - -[flake8] -# F - all pyflake errors -# E101 - indentation contains mixed spaces and tabs -# E111 - indentation is not a multiple of four -# E501 - line too long (see max-line-length) -# E722 - do not use bare except, specify exception instead -include = *.py -exclude = .git,__pycache__,.tox,.eggs,*.egg,doc,dist,build,_build,examples,.ipynb_checkpoints,node_modules,apps -ignore = E,W,F812 -select = F,E101,E111,E501,E722 -max-line-length = 165 -per-file-ignores = panel/tests/ui/jupyter_server_test_config.py:F821 - -[isort] -force_grid_wrap=4 -multi_line_output=5 -combine_as_imports=True -lines_between_types=1 -include_trailing_comma=True diff --git a/setup.py b/setup.py deleted file mode 100644 index 9e746516cd..0000000000 --- a/setup.py +++ /dev/null @@ -1,349 +0,0 @@ -#!/usr/bin/env python -import json -import os -import shutil -import sys - -from setuptools import find_packages, setup -from setuptools.command.develop import develop -from setuptools.command.install import install -from setuptools.command.sdist import sdist - -PANEL_LITE_BUILD = 'PANEL_LITE' in os.environ - - -def get_setup_version(reponame): - """ - Helper to get the current version from either git describe or the - .version file (if available). - """ - basepath = os.path.split(__file__)[0] - version_file_path = os.path.join(basepath, reponame, '.version') - try: - from param import version - except Exception: - version = None - if version is not None: - return version.Version.setup_version(basepath, reponame, archive_commit="$Format:%h$") - else: - print("WARNING: param>=1.6.0 unavailable. If you are installing a package, " - "this warning can safely be ignored. If you are creating a package or " - "otherwise operating in a git repository, you should install param>=1.6.0.") - return json.load(open(version_file_path, 'r'))['version_string'] - - -def _build_paneljs(): - from bokeh.ext import build - - from panel.compiler import bundle_resources - print("Building custom models:") - panel_dir = os.path.join(os.path.dirname(__file__), "panel") - build(panel_dir) - print("Bundling custom model resources:") - bundle_resources() - if sys.platform != "win32": - # npm can cause non-blocking stdout; so reset it just in case - import fcntl - flags = fcntl.fcntl(sys.stdout, fcntl.F_GETFL) - fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags&~os.O_NONBLOCK) - - -def _install_jupyter_server_extension(): - # data_files are not copied for editable installs returning - files = setup_args['data_files'] - for dst, (src,) in files: - dst = os.path.join(sys.prefix, dst) - os.makedirs(dst, exist_ok=True) - shutil.copy2(src, dst) - print(f"Copied {src} to {dst}") - - -class CustomDevelopCommand(develop): - """Custom installation for development mode.""" - - def run(self): - if not PANEL_LITE_BUILD: - _build_paneljs() - _install_jupyter_server_extension() - develop.run(self) - - -class CustomInstallCommand(install): - """Custom installation for install mode.""" - - def run(self): - if not PANEL_LITE_BUILD: - _build_paneljs() - install.run(self) - - -class CustomSdistCommand(sdist): - """Custom installation for sdist mode.""" - - def run(self): - if not PANEL_LITE_BUILD: - _build_paneljs() - sdist.run(self) - - -_COMMANDS = { - 'develop': CustomDevelopCommand, - 'install': CustomInstallCommand, - 'sdist': CustomSdistCommand, -} - -try: - from wheel.bdist_wheel import bdist_wheel - - class CustomBdistWheelCommand(bdist_wheel): - """Custom bdist_wheel command to force cancelling qiskit-terra wheel - creation.""" - - def run(self): - """Do nothing so the command intentionally fails.""" - if not PANEL_LITE_BUILD: - _build_paneljs() - bdist_wheel.run(self) - - _COMMANDS['bdist_wheel'] = CustomBdistWheelCommand -except Exception: - pass - -########## dependencies ########## - -install_requires = [ - 'bokeh >=3.4.0,<3.5.0', - 'param >=2.0.0,<3.0', - 'pyviz_comms >=2.0.0', - 'xyzservices >=2021.09.1', # Bokeh dependency, but pyodide 23.0.0 does not always pick it up - 'markdown', - 'markdown-it-py', - 'linkify-it-py', - 'mdit-py-plugins', - 'requests', - 'tqdm >=4.48.0', - 'bleach', - 'typing_extensions', - 'pandas >=1.2', -] - -_recommended = [ - 'jupyterlab', - 'holoviews >=1.16.0', - 'matplotlib', - 'pillow', - 'plotly' -] - -_tests_core = [ - # Test dependencies - 'flake8', - 'parameterized', - 'pytest', - 'nbval', - 'pytest-rerunfailures', - 'pytest-asyncio <0.22', - 'pytest-xdist', - 'pytest-cov', - 'pre-commit', - 'psutil', - # Libraries tested in unit tests - 'altair', - 'anywidget', - 'folium', - 'diskcache', - 'holoviews >=1.16.0', - 'numpy', - 'pandas >=1.3', - 'ipython >=7.0', - 'scipy', - 'textual', - 'watchfiles' -] - -_tests = _tests_core + [ - 'ipympl', - 'ipyvuetify', - 'ipywidgets_bokeh', - 'reacton', - 'twine', - # Temporary pins - 'numba <0.58' -] - -_ui = [ - 'jupyter-server', - 'playwright', - 'pytest-playwright', - 'tomli', -] - -_examples = [ - 'holoviews >=1.16.0', - 'hvplot', - 'plotly >=4.0', - 'altair', - 'streamz', - 'vega_datasets', - 'vtk', - 'scikit-learn', - 'datashader', - 'jupyter_bokeh >=3.0.7', - 'django <4', - 'channels', - 'pyvista', - 'ipywidgets', - 'ipywidgets_bokeh', - 'ipyvolume', - 'ipyleaflet', - 'ipympl', - 'folium', - 'xarray', - 'pyinstrument >=4.0', - 'aiohttp', - 'croniter', - 'graphviz', - 'networkx >=2.5', - 'pygraphviz', - 'seaborn', - 'pydeck', - 'graphviz', - 'python-graphviz', - 'xgboost', - 'ipyvuetify', - 'reacton', - 'scikit-image', - 'fastparquet', - 'textual', - 'dask-expr' -] - -# Anything only installable via conda -_conda_only = [ - 'pygraphviz', - 'python-graphviz', -] - -extras_require = { - 'examples': _examples, - 'tests_core': _tests_core, - 'tests': _tests, - 'recommended': _recommended, - 'doc': _recommended + [ - 'nbsite >=0.8.4', - 'lxml', - 'pandas <2.1.0' # Avoid deprecation warnings - ], - 'ui': _ui -} - -extras_require['all'] = sorted(set(sum(extras_require.values(), []))) -extras_require['all_pip'] = sorted(set(extras_require['all']) - set(_conda_only)) - -# Superset of what's in pyproject.toml (includes non-python -# dependencies). Also, pyproject.toml isn't supported by all tools -# anyway (e.g. older versions of pip, or conda - which also supports -# non-python dependencies). Note that setup_requires isn't used -# because it doesn't work well with pip. -extras_require['build'] = [ - 'param >=2.0.0', - 'setuptools >=42', - 'requests', - 'packaging', - 'bokeh >=3.4.0,<3.5.0', - 'pyviz_comms >=2.0.0', - 'bleach', - 'markdown', - 'tqdm >=4.48.0', - 'cryptography <39', # Avoid pyOpenSSL issue - 'urllib3 <2.0', # See: https://github.com/holoviz/panel/pull/4979 -] - -setup_args = dict( - name='panel', - version=get_setup_version("panel"), - description='The powerful data exploration & web app framework for Python.', - long_description=open('README.md', encoding="utf8").read() if os.path.isfile('README.md') else 'Consult README.md', - long_description_content_type="text/markdown", - author="HoloViz", - author_email="developers@holoviz.org", - maintainer="HoloViz", - maintainer_email="developers@holoviz.org", - platforms=['Windows', 'Mac OS X', 'Linux'], - license='BSD', - url='http://panel.holoviz.org', - project_urls={ - 'Source': 'https://github.com/holoviz/panel', - }, - cmdclass=_COMMANDS, - packages=find_packages(), - include_package_data=True, - data_files=[ - # like `jupyter serverextension enable --sys-prefix` - ( - "etc/jupyter/jupyter_notebook_config.d", - ["jupyter-config/jupyter_notebook_config.d/panel-client-jupyter.json"], - ), - # like `jupyter server extension enable --sys-prefix` - ( - "etc/jupyter/jupyter_server_config.d", - ["jupyter-config/jupyter_server_config.d/panel-client-jupyter.json"], - ), - ], - classifiers=[ - "License :: OSI Approved :: BSD License", - "Development Status :: 5 - Production/Stable", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Operating System :: OS Independent", - "Intended Audience :: Developers", - "Intended Audience :: Science/Research", - "Intended Audience :: Financial and Insurance Industry", - "Intended Audience :: Healthcare Industry", - "Intended Audience :: Information Technology", - "Intended Audience :: Legal Industry", - "Intended Audience :: Other Audience", - "Intended Audience :: Science/Research", - "Natural Language :: English", - "Topic :: Scientific/Engineering", - "Topic :: Scientific/Engineering :: Visualization", - "Topic :: Scientific/Engineering :: Information Analysis", - "Topic :: Office/Business", - "Topic :: Office/Business :: Financial", - "Topic :: Software Development :: Libraries"], - python_requires=">=3.9", - entry_points={ - 'console_scripts': [ - 'panel = panel.command:main' - ] - }, - install_requires=install_requires, - extras_require=extras_require, - tests_require=extras_require['tests'] -) - -def clean_js_version(version): - version = version.replace('-', '') - for dev in ('a', 'b', 'rc'): - version = version.replace(dev+'.', dev) - return version - -if __name__ == "__main__": - version = setup_args['version'] - if 'post' not in version: - with open('./panel/package.json') as f: - package_json = json.load(f) - js_version = package_json['version'] - version = version.split('+')[0] - if any(dev in version for dev in ('a', 'b', 'rc')) and not '-' in js_version: - raise ValueError(f"panel.js dev versions ({js_version}) must " - "must separate dev suffix with a dash, e.g. " - "v1.0.0rc1 should be v1.0.0-rc.1.") - if version != 'None' and version != clean_js_version(js_version): - raise ValueError(f"panel.js version ({js_version}) does not match " - f"panel version ({version}). Cannot build release.") - - setup(**setup_args) From 9332c68a50b070db667f4ea130ed3f3e275771e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 16:18:58 +0200 Subject: [PATCH 023/130] Move conda build to scripts folder --- scripts/build_conda.sh | 14 ------------- scripts/conda/build.sh | 21 +++++++++++++++++++ .../conda/recipe}/meta.yaml | 0 3 files changed, 21 insertions(+), 14 deletions(-) delete mode 100755 scripts/build_conda.sh create mode 100755 scripts/conda/build.sh rename {conda.recipe => scripts/conda/recipe}/meta.yaml (100%) diff --git a/scripts/build_conda.sh b/scripts/build_conda.sh deleted file mode 100755 index f2a5cc5dfa..0000000000 --- a/scripts/build_conda.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -euxo pipefail - -git status - -export SETUPTOOLS_ENABLE_FEATURES="legacy-editable" -python -m build -w . - -git diff --exit-code - -VERSION=$(find dist -name "*.whl" -exec basename {} \; | cut -d- -f2) -export VERSION -conda build conda.recipe/ --no-anaconda-upload --no-verify -c bokeh diff --git a/scripts/conda/build.sh b/scripts/conda/build.sh new file mode 100755 index 0000000000..79761fa4a0 --- /dev/null +++ b/scripts/conda/build.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +PACKAGE="panel" + +for file in dist/*.whl dist/*.tar.bz2; do + if [ -e "$file" ]; then + echo "dist folder already contains $(basename "$file"). Please delete it before running this script." + exit 1 + fi +done + +git diff --exit-code +python -m build . # Can add -w when this is solved: https://github.com/pypa/hatch/issues/1305 + +VERSION=$(find dist -name "*.whl" -exec basename {} \; | cut -d- -f2) +export VERSION +conda build scripts/conda/recipe --no-anaconda-upload --no-verify -c bokeh + +mv "$CONDA_PREFIX/conda-bld/noarch/$PACKAGE-$VERSION-py_0.tar.bz2" dist diff --git a/conda.recipe/meta.yaml b/scripts/conda/recipe/meta.yaml similarity index 100% rename from conda.recipe/meta.yaml rename to scripts/conda/recipe/meta.yaml From 362145d99ad1aee010e39da49cab89b77a6c1e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 16:23:47 +0200 Subject: [PATCH 024/130] Update conda meta --- pixi.toml | 2 +- scripts/conda/build.sh | 2 +- scripts/conda/recipe/meta.yaml | 30 ++++++++++++++++-------------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/pixi.toml b/pixi.toml index a2f30a67e5..34ee5696b7 100644 --- a/pixi.toml +++ b/pixi.toml @@ -166,7 +166,7 @@ build = "*" conda-build = "*" [feature.build.tasks] -# build-conda = 'bash scripts/conda/build.sh' +build-conda = 'bash scripts/conda/build.sh' build-pip = 'python -m build .' # build-pyodide = 'python scripts/build_pyodide_wheels.py' diff --git a/scripts/conda/build.sh b/scripts/conda/build.sh index 79761fa4a0..a4bc698b01 100755 --- a/scripts/conda/build.sh +++ b/scripts/conda/build.sh @@ -12,7 +12,7 @@ for file in dist/*.whl dist/*.tar.bz2; do done git diff --exit-code -python -m build . # Can add -w when this is solved: https://github.com/pypa/hatch/issues/1305 +python -m build -w . VERSION=$(find dist -name "*.whl" -exec basename {} \; | cut -d- -f2) export VERSION diff --git a/scripts/conda/recipe/meta.yaml b/scripts/conda/recipe/meta.yaml index daa05b49c2..909523d832 100644 --- a/scripts/conda/recipe/meta.yaml +++ b/scripts/conda/recipe/meta.yaml @@ -1,17 +1,18 @@ -{% set sdata = load_setup_py_data(setup_file="../setup.py", from_recipe_dir=True) %} +{% set pyproject = load_file_data('../../../pyproject.toml', from_recipe_dir=True) %} +{% set project = pyproject['project'] %} package: - name: {{ sdata['name'] }} + name: {{ project["name"] }} version: {{ VERSION }} source: - url: ../dist/{{ sdata['name'] }}-{{ VERSION }}-py3-none-any.whl + url: ../../../dist/{{ project["name"] }}-{{ VERSION }}-py3-none-any.whl build: noarch: python - script: {{ PYTHON }} -m pip install -vv {{ sdata['name'] }}-{{ VERSION }}-py3-none-any.whl + script: {{ PYTHON }} -m pip install -vv {{ project["name"] }}-{{ VERSION }}-py3-none-any.whl entry_points: - {% for group,epoints in sdata.get("entry_points",{}).items() %} + {% for group,epoints in project.get("entry_points",{}).items() %} {% for entry_point in epoints %} - {{ entry_point }} {% endfor %} @@ -19,17 +20,18 @@ build: requirements: build: - - python {{ sdata['python_requires'] }} - {% for dep in sdata['extras_require']['build'] %} + - python {{ project['requires-python'] }} + {% for dep in pyproject['build-system']['requires'] %} - {{ dep }} {% endfor %} run: - - python {{ sdata['python_requires'] }} - {% for dep in sdata.get('install_requires',{}) %} + - python {{ project['requires-python'] }} + {% for dep in project.get('dependencies', []) %} + - {{ dep }} + {% endfor %} + {% for dep in project['optional-dependencies']['recommended'] %} - {{ dep }} {% endfor %} - run_constrained: - - holoviews >=1.13.2 test: imports: @@ -45,6 +47,6 @@ test: - pytest --pyargs panel.tests -n logical --dist loadgroup about: - home: {{ sdata['url'] }} - summary: {{ sdata['description'] }} - license: {{ sdata['license'] }} + home: {{ project['urls']['Homepage'] }} + summary: {{ project['description'] }} + license: {{ project['license']['text'] }} From 1ff08d6804d15beb98d6f73db8841eea7afc764b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 17:08:43 +0200 Subject: [PATCH 025/130] Add dist to force-include --- pyproject.toml | 7 +++++++ scripts/conda/recipe/meta.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index abba7379d5..02265e056b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,6 +61,7 @@ dependencies = [ 'typing_extensions', 'pandas >=1.2', 'packaging', + 'tqdm', # TODO: Make this optional ] [project.urls] @@ -87,6 +88,9 @@ source = "vcs" [tool.hatch.build.targets.wheel] include = ["panel"] +[tool.hatch.build.targets.wheel.force-include] +"panel/dist" = "panel/dist" + [tool.hatch.build.targets.wheel.shared-data] "scripts/jupyter-config/notebook.json" = "etc/jupyter/jupyter_notebook_config.d/panel-client-jupyter.json" "scripts/jupyter-config/server.json" = "etc/jupyter/jupyter_server_config.d/panel-client-jupyter.json" @@ -94,6 +98,9 @@ include = ["panel"] [tool.hatch.build.targets.sdist] include = ["panel", "scripts"] +[tool.hatch.build.targets.sdist.force-include] +"panel/dist" = "panel/dist" + [tool.hatch.build.hooks.vcs] version-file = "panel/_version.py" diff --git a/scripts/conda/recipe/meta.yaml b/scripts/conda/recipe/meta.yaml index 909523d832..353328bfd0 100644 --- a/scripts/conda/recipe/meta.yaml +++ b/scripts/conda/recipe/meta.yaml @@ -49,4 +49,4 @@ test: about: home: {{ project['urls']['Homepage'] }} summary: {{ project['description'] }} - license: {{ project['license']['text'] }} + # license: {{ project['license']['text'] }} From 575580e47064a4424ad6d05e702d13ef9f91fde9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 17:33:11 +0200 Subject: [PATCH 026/130] add license back --- scripts/conda/recipe/meta.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/conda/recipe/meta.yaml b/scripts/conda/recipe/meta.yaml index 353328bfd0..909523d832 100644 --- a/scripts/conda/recipe/meta.yaml +++ b/scripts/conda/recipe/meta.yaml @@ -49,4 +49,4 @@ test: about: home: {{ project['urls']['Homepage'] }} summary: {{ project['description'] }} - # license: {{ project['license']['text'] }} + license: {{ project['license']['text'] }} From fcd30a3dec04ce652482f7058919b1a32c105473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 21 Apr 2024 17:40:26 +0200 Subject: [PATCH 027/130] Update hatch-build --- scripts/hatch_build.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/hatch_build.py b/scripts/hatch_build.py index 5b40a31af8..ddd6be2518 100644 --- a/scripts/hatch_build.py +++ b/scripts/hatch_build.py @@ -58,11 +58,7 @@ def initialize(self, version: str, build_data: dict[str, t.Any]) -> None: return validate_js_version(self.metadata.version) - - def finalize(self, version: str, build_data: dict[str, t.Any], artifact_path: str) -> None: - """Finalize the plugin.""" - if self.target_name not in ["wheel", "sdist"]: - return + build_paneljs() sys.path.insert(0, str(BASE_DIR)) from panel.compiler import bundle_resources From d623bf51c3e36fa411f93d89b9623704d6e89652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 08:27:54 +0200 Subject: [PATCH 028/130] Add PANEL_LITE back to install task --- scripts/hatch_build.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/scripts/hatch_build.py b/scripts/hatch_build.py index ddd6be2518..3eab4d8d09 100644 --- a/scripts/hatch_build.py +++ b/scripts/hatch_build.py @@ -18,7 +18,6 @@ def build_paneljs(): print("Building custom models:") panel_dir = BASE_DIR / "panel" build(panel_dir) - print("Bundling custom model resources:") if sys.platform != "win32": # npm can cause non-blocking stdout; so reset it just in case import fcntl @@ -27,6 +26,14 @@ def build_paneljs(): fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags & ~os.O_NONBLOCK) +def bundle_resources(): + sys.path.insert(0, str(BASE_DIR)) + from panel.compiler import bundle_resources + + print("Bundling custom model resources:") + bundle_resources(verbose=True) + + def clean_js_version(version): version = version.replace("-", "") for dev in ("a", "b", "rc"): @@ -48,7 +55,7 @@ def validate_js_version(version): class BuildHook(BuildHookInterface): - """The hatch jupyter builder build hook.""" + """The hatch build hook.""" PLUGIN_NAME = "install" @@ -58,9 +65,7 @@ def initialize(self, version: str, build_data: dict[str, t.Any]) -> None: return validate_js_version(self.metadata.version) - build_paneljs() - - sys.path.insert(0, str(BASE_DIR)) - from panel.compiler import bundle_resources - bundle_resources(verbose=True) + if "PANEL_LITE" not in os.environ: + build_paneljs() + bundle_resources() From e9d9705ca29b928899685c87719c0bc493eba0b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 09:05:33 +0200 Subject: [PATCH 029/130] Add some information + colors to build step --- scripts/hatch_build.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/scripts/hatch_build.py b/scripts/hatch_build.py index 3eab4d8d09..15a4407a44 100644 --- a/scripts/hatch_build.py +++ b/scripts/hatch_build.py @@ -10,14 +10,15 @@ from hatchling.builders.hooks.plugin.interface import BuildHookInterface BASE_DIR = Path(__file__).parents[1] +GREEN, RED, RESET = "\033[92m", "\033[91m", "\033[0m" -def build_paneljs(): +def build_models(): from bokeh.ext import build - print("Building custom models:") + print(f"{GREEN}[PANEL]{RESET} Starting building custom models", flush=True) panel_dir = BASE_DIR / "panel" - build(panel_dir) + success = build(panel_dir) if sys.platform != "win32": # npm can cause non-blocking stdout; so reset it just in case import fcntl @@ -25,14 +26,23 @@ def build_paneljs(): flags = fcntl.fcntl(sys.stdout, fcntl.F_GETFL) fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags & ~os.O_NONBLOCK) + if success: + print(f"{GREEN}[PANEL]{RESET} Finished building custom models", flush=True) + else: + print(f"{RED}[PANEL]{RESET} Failed building custom models", flush=True) + sys.exit(1) def bundle_resources(): sys.path.insert(0, str(BASE_DIR)) from panel.compiler import bundle_resources - print("Bundling custom model resources:") - bundle_resources(verbose=True) - + print(f"{GREEN}[PANEL]{RESET} Starting bundling custom model resources", flush=True) + try: + bundle_resources() + print(f"{GREEN}[PANEL]{RESET} Finished bundling custom model resources", flush=True) + except Exception as e: + print(f"{GREEN}[PANEL]{RESET} Failed bundling custom model resources", flush=True) + raise e def clean_js_version(version): version = version.replace("-", "") @@ -67,5 +77,5 @@ def initialize(self, version: str, build_data: dict[str, t.Any]) -> None: validate_js_version(self.metadata.version) if "PANEL_LITE" not in os.environ: - build_paneljs() + build_models() bundle_resources() From d7bdcbf3141a0b3ae27cfde38d427e32407636ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 09:17:49 +0200 Subject: [PATCH 030/130] Update to python-build --- pixi.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index 34ee5696b7..a4db40ecff 100644 --- a/pixi.toml +++ b/pixi.toml @@ -162,7 +162,7 @@ depends_on = ['docs-refmanual', 'docs-convert-gallery', 'docs-generate', 'docs-c # ================== BUILD ==================== # ============================================= [feature.build.dependencies] -build = "*" +python-build = "*" conda-build = "*" [feature.build.tasks] From c273521a177c86cb5d23b8217be01dda7cfc04af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 09:44:33 +0200 Subject: [PATCH 031/130] enable build-pyodide --- pixi.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index a4db40ecff..20756c4c98 100644 --- a/pixi.toml +++ b/pixi.toml @@ -168,7 +168,7 @@ conda-build = "*" [feature.build.tasks] build-conda = 'bash scripts/conda/build.sh' build-pip = 'python -m build .' -# build-pyodide = 'python scripts/build_pyodide_wheels.py' +build-pyodide = 'python scripts/build_pyodide_wheels.py' # ============================================= # =================== LINT ==================== From f1cec0c4a0e000f60d677c046ebcb37bffd7b664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 09:51:22 +0200 Subject: [PATCH 032/130] Small changes to test.yaml --- .github/workflows/test.yaml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 5f9cc7ca32..5f05c97c9b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -3,10 +3,9 @@ on: push: branches: - main - - branch-1.0 pull_request: branches: - - '*' + - "*" workflow_dispatch: inputs: target: @@ -22,7 +21,7 @@ on: type: boolean default: true schedule: - - cron: '0 19 * * SUN' + - cron: "0 19 * * SUN" concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -31,7 +30,7 @@ concurrency: jobs: pre_commit: name: Run pre-commit - runs-on: 'ubuntu-latest' + runs-on: "ubuntu-latest" steps: - uses: holoviz-dev/holoviz_tasks/pre-commit@v0 - uses: pre-commit/action@v3.0.1 @@ -41,6 +40,7 @@ jobs: with: commit_message: "Optimize PNG images (lossless)" file_pattern: "*.png" + setup: name: Setup workflow runs-on: ubuntu-latest @@ -179,6 +179,7 @@ jobs: files: ./coverage.xml flags: unitexamples-tests fail_ci_if_error: false # optional (default = false) + ui_test_suite: name: UI tests on ${{ matrix.os }} with Python 3.9 needs: [pre_commit, setup] @@ -187,7 +188,7 @@ jobs: strategy: fail-fast: false matrix: - os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] + os: ["ubuntu-latest", "macos-latest", "windows-latest"] timeout-minutes: 120 defaults: run: @@ -265,6 +266,7 @@ jobs: files: ./coverage.xml flags: ui-tests fail_ci_if_error: false # optional (default = false) + core_test_suite: name: Core tests on Python ${{ matrix.python-version }}, ${{ matrix.os }} needs: [pre_commit, setup] @@ -273,8 +275,8 @@ jobs: strategy: fail-fast: false matrix: - os: ['ubuntu-latest'] - python-version: ['3.12'] + os: ["ubuntu-latest"] + python-version: ["3.12"] timeout-minutes: 120 defaults: run: @@ -284,7 +286,7 @@ jobs: PYTHON_VERSION: ${{ matrix.python-version }} SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" steps: - # - uses: holoviz-dev/holoviz_tasks/install@v0.1a19 + # - uses: holoviz-dev/holoviz_tasks/install@v0.1a19 # with: # name: core_test_suite # python-version: ${{ matrix.python-version }} From 4989ddb0fcdc0ded9b4f3bc2c04d651a3ce1c17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 10:02:19 +0200 Subject: [PATCH 033/130] Update global settings for test.yaml workflow --- .github/workflows/test.yaml | 80 ++++++++++++++----------------------- 1 file changed, 31 insertions(+), 49 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 5f05c97c9b..9c614a4fc1 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -27,6 +27,16 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true +defaults: + run: + shell: bash -el {0} + +env: + DISPLAY: ":99.0" + PYTHONIOENCODING: "utf-8" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PYTHONIOENCODING: "utf-8" + jobs: pre_commit: name: Run pre-commit @@ -61,9 +71,8 @@ jobs: code: - 'panel/**' - 'examples/**' - - 'setup.py' + - 'pixi.toml' - 'pyproject.toml' - - 'tox.ini' - '.github/workflows/test.yaml' doc: - 'doc/getting_started/**' @@ -86,19 +95,16 @@ jobs: if: env.MATRIX_OPTION == 'default' run: | MATRIX=$(jq -nsc '{ - "os": ["ubuntu-latest", "macos-latest", "windows-latest"], - "python-version": ["3.9", "3.11"], - "include": [ - {"os": "ubuntu-latest", "python-version": "3.10"} - ] + "os": ["ubuntu-latest", "macos-14", "windows-latest"], + "environment": ["test-39", "test-312"] }') echo "MATRIX=$MATRIX" >> $GITHUB_ENV - name: Set test matrix with 'full' option if: env.MATRIX_OPTION == 'full' run: | MATRIX=$(jq -nsc '{ - "os": ["ubuntu-latest", "macos-latest", "windows-latest"], - "python-version": ["3.9", "3.10", "3.11"] + "os": ["ubuntu-latest", "macos-14", "windows-latest"], + "environment": ["test-39", "test-310", "test-311", "test-312"] }') echo "MATRIX=$MATRIX" >> $GITHUB_ENV - name: Set test matrix with 'downstream' option @@ -106,34 +112,27 @@ jobs: run: | MATRIX=$(jq -nsc '{ "os": ["ubuntu-latest"], - "python-version": ["3.11"] + "environment": ["test-312"] }') echo "MATRIX=$MATRIX" >> $GITHUB_ENV + pixi_lock: + name: Pixi lock + runs-on: ubuntu-latest + steps: + - uses: holoviz-dev/holoviz_tasks/pixi_lock@pixi + with: + cache: ${{ github.event.inputs.cache == 'true' || github.event.inputs.cache == '' }} + unit_test_suite: - name: Unit tests on ${{ matrix.os }} with Python ${{ matrix.python-version }} - needs: [pre_commit, setup] + name: unit:${{ matrix.environment }}:${{ matrix.os }} + needs: [pre_commit, setup, pixi_lock] runs-on: ${{ matrix.os }} if: needs.setup.outputs.code_change == 'true' strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.matrix) }} timeout-minutes: 90 - defaults: - run: - shell: bash -l {0} - env: - DESC: "Python ${{ matrix.python-version }} tests" - PYTHON_VERSION: ${{ matrix.python-version }} - SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" - DISPLAY: ":99.0" - PYTHONIOENCODING: "utf-8" - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Without this env var `doit env_create ...` uses by default - # the `pyviz` channel, except that we don't want to configure - # it as one of the sources. - PYCTDEV_SELF_CHANNEL: "pyviz/label/dev" - OMP_NUM_THREADS: 1 steps: - uses: holoviz-dev/holoviz_tasks/install@v0 with: @@ -181,8 +180,8 @@ jobs: fail_ci_if_error: false # optional (default = false) ui_test_suite: - name: UI tests on ${{ matrix.os }} with Python 3.9 - needs: [pre_commit, setup] + name: ui:${{ matrix.environment }}:${{ matrix.os }} + needs: [pre_commit, setup, pixi_lock] runs-on: ${{ matrix.os }} if: needs.setup.outputs.code_change == 'true' || needs.setup.outputs.doc_change == 'true' strategy: @@ -190,14 +189,8 @@ jobs: matrix: os: ["ubuntu-latest", "macos-latest", "windows-latest"] timeout-minutes: 120 - defaults: - run: - shell: bash -el {0} env: - DESC: "Python ${{ matrix.python-version }} tests" - PYTHONIOENCODING: "utf-8" PANEL_LOG_LEVEL: info - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" OAUTH_COOKIE_SECRET: ${{ secrets.OAUTH_COOKIE_SECRET }} OAUTH_ENCRYPTION_KEY: ${{ secrets.OAUTH_ENCRYPTION_KEY }} @@ -218,10 +211,6 @@ jobs: OKTA_OAUTH_EXTRA_PARAMS: ${{ secrets.OKTA_OAUTH_EXTRA_PARAMS }} OKTA_OAUTH_USER: ${{ secrets.OKTA_OAUTH_USER }} OKTA_OAUTH_PASSWORD: ${{ secrets.OKTA_OAUTH_PASSWORD }} - # Without this env var `doit env_create ...` uses by default - # the `pyviz` channel, except that we don't want to configure - # it as one of the sources. - PYCTDEV_SELF_CHANNEL: "pyviz/label/dev" steps: - uses: holoviz-dev/holoviz_tasks/install@v0 with: @@ -268,8 +257,8 @@ jobs: fail_ci_if_error: false # optional (default = false) core_test_suite: - name: Core tests on Python ${{ matrix.python-version }}, ${{ matrix.os }} - needs: [pre_commit, setup] + name: core:${{ matrix.environment }}:${{ matrix.os }} + needs: [pre_commit, setup, pixi_lock] runs-on: ${{ matrix.os }} if: needs.setup.outputs.code_change == 'true' strategy: @@ -278,18 +267,11 @@ jobs: os: ["ubuntu-latest"] python-version: ["3.12"] timeout-minutes: 120 - defaults: - run: - shell: bash -el {0} - env: - DESC: "Python ${{ matrix.python-version }}, ${{ matrix.os }} core tests" - PYTHON_VERSION: ${{ matrix.python-version }} - SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" steps: # - uses: holoviz-dev/holoviz_tasks/install@v0.1a19 # with: # name: core_test_suite - # python-version: ${{ matrix.python-version }} + # environment: ${{ matrix.environment }} # # channel-priority: strict # channels: pyviz/label/dev,conda-forge,nodefaults # envs: "-o tests_core -o tests_ci" From 4e33fdfb487a2310f2a17c168c299fa67f531056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 10:08:35 +0200 Subject: [PATCH 034/130] Initial update to unit test --- .github/workflows/test.yaml | 55 ++++++++++++------------------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9c614a4fc1..11dc71fefe 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -134,50 +134,29 @@ jobs: matrix: ${{ fromJson(needs.setup.outputs.matrix) }} timeout-minutes: 90 steps: - - uses: holoviz-dev/holoviz_tasks/install@v0 + - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi + if: needs.setup.outputs.code_change == 'true' with: - name: unit_test_suite - python-version: ${{ matrix.python-version }} - channels: pyviz/label/dev,numba,bokeh/label/dev,conda-forge,nodefaults - conda-update: true - nodejs: true - envs: -o examples -o recommended -o tests -o build - cache: ${{ github.event.inputs.cache || github.event.inputs.cache == '' }} - opengl: true - id: install - - name: doit develop_install - run: | - conda activate test-environment - pip install pyecharts - panel build panel - - name: override-vtk-osmesa - if: contains(matrix.os, 'ubuntu') - run: | - conda activate test-environment - conda install -c conda-forge vtk=9.2.6=osmesa* vtk-base=9.2.6=osmesa* vtk-io-ffmpeg=9.2.6=osmesa* --no-deps - - name: bokeh_sampledata - run: | - conda activate test-environment - bokeh sampledata - - name: doit test_unit + environments: ${{ matrix.environment }} + # opengl: true + # - name: override-vtk-osmesa + # if: contains(matrix.os, 'ubuntu') + # run: | + # conda activate test-environment + # conda install -c conda-forge vtk=9.2.6=osmesa* vtk-base=9.2.6=osmesa* vtk-io-ffmpeg=9.2.6=osmesa* --no-deps + - name: Test unit run: | - conda activate test-environment - doit test_unit - - name: doit test_unit-subprocess + pixi run -e ${{ matrix.environment }} test-unit --cov=./panel --cov-report=xml + - name: Test subprocess if: contains(matrix.os, 'ubuntu') run: | - conda activate test-environment - doit test_subprocess - - name: test examples + pixi run -e ${{ matrix.environment }} test-subprocess --cov=./panel --cov-report=xml + - name: Test Examples run: | - conda activate test-environment - doit test_examples - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + pixi run -e ${{ matrix.environment }} test-example + - uses: codecov/codecov-action@v4 with: - files: ./coverage.xml - flags: unitexamples-tests - fail_ci_if_error: false # optional (default = false) + token: ${{ secrets.CODECOV_TOKEN }} ui_test_suite: name: ui:${{ matrix.environment }}:${{ matrix.os }} From 750eb087efa6eba3dd414f6054d8d681b5b1d39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 10:19:37 +0200 Subject: [PATCH 035/130] Initial update to UI test --- .github/workflows/test.yaml | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 11dc71fefe..c295e996d2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -167,10 +167,10 @@ jobs: fail-fast: false matrix: os: ["ubuntu-latest", "macos-latest", "windows-latest"] + environment: ["test-ui"] timeout-minutes: 120 env: PANEL_LOG_LEVEL: info - SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" OAUTH_COOKIE_SECRET: ${{ secrets.OAUTH_COOKIE_SECRET }} OAUTH_ENCRYPTION_KEY: ${{ secrets.OAUTH_ENCRYPTION_KEY }} AUTH0_PORT: "5701" @@ -191,24 +191,18 @@ jobs: OKTA_OAUTH_USER: ${{ secrets.OKTA_OAUTH_USER }} OKTA_OAUTH_PASSWORD: ${{ secrets.OKTA_OAUTH_PASSWORD }} steps: - - uses: holoviz-dev/holoviz_tasks/install@v0 + - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: - name: ui_test_suite - python-version: 3.9 - channels: pyviz/label/dev,bokeh/label/dev,conda-forge,nodefaults - envs: "-o recommended -o tests -o build" - cache: ${{ github.event.inputs.cache || github.event.inputs.cache == '' }} - nodejs: true - playwright: true + environments: ${{ matrix.environment }} id: install - name: launch jupyter run: | - conda activate test-environment - jupyter server extension enable panel.io.jupyter_server_extension --sys-prefix + # jupyter server extension enable panel.io.jupyter_server_extension --sys-prefix + pixi shell -e ${{ matrix.environment }} (jupyter lab --config panel/tests/ui/jupyter_server_test_config.py --port 8887 > /tmp/jupyterlab_server.log 2>&1) & - name: build jupyterlite run: | - conda activate test-environment + pixi shell -e ${{ matrix.environment }} python -m pip install -r ./lite/requirements.txt python ./scripts/build_pyodide_wheels.py lite/pypi python ./scripts/panelite/generate_panelite_content.py @@ -218,22 +212,20 @@ jobs: with: resource: http-get://localhost:8887/lab timeout: 180000 - - name: doit test_ui + - name: Test UI run: | - conda activate test-environment - doit test_ui + COV="--cov=./panel --cov-report=xml --cov-config=.uicoveragerc" + FAIL="--screenshot only-on-failure --full-page-screenshot --output ui_screenshots" + pixi run -e ${{ matrix.environment }} test-ui --jupyter $COV $FAIL - uses: actions/upload-artifact@v3 if: always() with: name: ui_screenshots path: ./ui_screenshots if-no-files-found: ignore - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v4 with: - files: ./coverage.xml - flags: ui-tests - fail_ci_if_error: false # optional (default = false) + token: ${{ secrets.CODECOV_TOKEN }} core_test_suite: name: core:${{ matrix.environment }}:${{ matrix.os }} From 97462cfa34ecc34393115ae98d314af1d1eb039a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 10:22:40 +0200 Subject: [PATCH 036/130] Initial update to core test --- .github/workflows/test.yaml | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c295e996d2..0bcb060c37 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -236,37 +236,12 @@ jobs: fail-fast: false matrix: os: ["ubuntu-latest"] - python-version: ["3.12"] + environment: ["test-core"] timeout-minutes: 120 steps: - # - uses: holoviz-dev/holoviz_tasks/install@v0.1a19 - # with: - # name: core_test_suite - # environment: ${{ matrix.environment }} - # # channel-priority: strict - # channels: pyviz/label/dev,conda-forge,nodefaults - # envs: "-o tests_core -o tests_ci" - # cache: ${{ github.event.inputs.cache || github.event.inputs.cache == '' }} - # conda-update: true - # id: install - - uses: actions/checkout@v3 - with: - fetch-depth: "100" - - name: Fetch unshallow - run: git fetch --prune --tags --unshallow -f - - uses: actions/setup-node@v3 - with: - node-version: 18.x - - uses: actions/setup-python@v4 + - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: - python-version: "3.12" - - run: | - python -m pip install -ve '.[tests_core, recommended]' - - name: bokeh sampledata - run: | - # conda activate test-environment - bokeh sampledata - - name: doit test_unit + environments: ${{ matrix.environment }} + - name: Test Unit run: | - # conda activate test-environment - pytest panel -n logical --dist loadgroup + pixi run -e ${{ matrix.environment }} test-unit From 7c9d5d2dff53e6102f4b7ed0a734e14b7455df6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 10:29:28 +0200 Subject: [PATCH 037/130] Small updates to test workflow --- .github/workflows/test.yaml | 4 +++- pixi.toml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 0bcb060c37..dfabb1cc5f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -35,7 +35,6 @@ env: DISPLAY: ":99.0" PYTHONIOENCODING: "utf-8" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PYTHONIOENCODING: "utf-8" jobs: pre_commit: @@ -212,6 +211,9 @@ jobs: with: resource: http-get://localhost:8887/lab timeout: 180000 + - name: Test docs + run: | + pixi run -e ${{ matrix.environment }} test-docs --cov=./panel --cov-report=xml - name: Test UI run: | COV="--cov=./panel --cov-report=xml --cov-config=.uicoveragerc" diff --git a/pixi.toml b/pixi.toml index 20756c4c98..db7557d0b4 100644 --- a/pixi.toml +++ b/pixi.toml @@ -137,7 +137,7 @@ jupyter_server = "*" install-ui = 'playwright install chromium' [feature.test-ui.tasks.test-ui] -cmd = 'pytest panel/tests/ui --ui --browser chromium -n logical --dist loadgroup--reruns 3 --reruns-delay 10' +cmd = 'pytest panel/tests/ui --ui --browser chromium -n logical --dist loadgroup --reruns 3 --reruns-delay 10' depends_on = ["install-ui"] # ============================================= From 124bb107b449fed9cdc30241e9bd2ad23660161c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 10:44:07 +0200 Subject: [PATCH 038/130] Add coverage environment variable --- .github/workflows/test.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index dfabb1cc5f..bdf910acdd 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -35,6 +35,7 @@ env: DISPLAY: ":99.0" PYTHONIOENCODING: "utf-8" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COV: "--cov=./panel --cov-report=xml" jobs: pre_commit: @@ -145,11 +146,11 @@ jobs: # conda install -c conda-forge vtk=9.2.6=osmesa* vtk-base=9.2.6=osmesa* vtk-io-ffmpeg=9.2.6=osmesa* --no-deps - name: Test unit run: | - pixi run -e ${{ matrix.environment }} test-unit --cov=./panel --cov-report=xml + pixi run -e ${{ matrix.environment }} test-unit $COV - name: Test subprocess if: contains(matrix.os, 'ubuntu') run: | - pixi run -e ${{ matrix.environment }} test-subprocess --cov=./panel --cov-report=xml + pixi run -e ${{ matrix.environment }} test-subprocess $COV - name: Test Examples run: | pixi run -e ${{ matrix.environment }} test-example @@ -213,12 +214,11 @@ jobs: timeout: 180000 - name: Test docs run: | - pixi run -e ${{ matrix.environment }} test-docs --cov=./panel --cov-report=xml + pixi run -e ${{ matrix.environment }} test-docs $COV - name: Test UI run: | - COV="--cov=./panel --cov-report=xml --cov-config=.uicoveragerc" FAIL="--screenshot only-on-failure --full-page-screenshot --output ui_screenshots" - pixi run -e ${{ matrix.environment }} test-ui --jupyter $COV $FAIL + pixi run -e ${{ matrix.environment }} test-ui --jupyter $COV --cov-config=.uicoveragerc $FAIL - uses: actions/upload-artifact@v3 if: always() with: From 05ee167d6ac59a0699dfb2df842315bf2b4a61b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 10:46:30 +0200 Subject: [PATCH 039/130] Remove tox.ini --- .github/workflows/test.yaml | 3 ++ tox.ini | 74 ------------------------------------- 2 files changed, 3 insertions(+), 74 deletions(-) delete mode 100644 tox.ini diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index bdf910acdd..250c9c8005 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -217,6 +217,9 @@ jobs: pixi run -e ${{ matrix.environment }} test-docs $COV - name: Test UI run: | + # Read the .uicoveragerc file to set the concurrency library to greenlet + # when the test suite relies on playwright, see + # https://github.com/microsoft/playwright-python/issues/313 FAIL="--screenshot only-on-failure --full-page-screenshot --output ui_screenshots" pixi run -e ${{ matrix.environment }} test-ui --jupyter $COV --cov-config=.uicoveragerc $FAIL - uses: actions/upload-artifact@v3 diff --git a/tox.ini b/tox.ini deleted file mode 100644 index d6e0ea03cc..0000000000 --- a/tox.ini +++ /dev/null @@ -1,74 +0,0 @@ -# For use with pyct (https://github.com/pyviz/pyct), but just standard -# tox config (works with tox alone). - -[tox] -# python version test group extra envs extra commands -envlist = {py39,py310,py311,py312}-{flakes,unit,ui,subprocess,unit_deploy,examples,all_recommended,deprecations}-{default}-{dev,pkg} -build = wheel - -[_flakes] -description = Flake check python and notebooks -deps = .[tests] -commands = flake8 - -[_unit] -description = Run unit tests -deps = .[tests] -commands = pytest panel --cov=./panel --cov-report=xml -n logical --dist loadgroup - -[_unit_deploy] -description = Run unit tests without coverage -deps = .[tests] -commands = pytest panel - -[_ui] -description = Run UI tests -deps = .[tests, ui] -; Read the .uicoveragerc file to set the concurrency library to greenlet -; when the test suite relies on playwright, see -; https://github.com/microsoft/playwright-python/issues/313 -commands = pytest panel --cov=./panel --cov-report=xml --cov-config=.uicoveragerc --ui --jupyter --browser chromium -n logical --dist loadgroup --screenshot only-on-failure --full-page-screenshot --output ui_screenshots --tracing retain-on-failure --reruns 3 --reruns-delay 10 - -[_subprocess] -description = Run unit tests that fork the process -deps = .[tests] -commands = pytest panel --cov=./panel --cov-report=xml --subprocess - -[_examples] -description = Test that default examples run -deps = .[recommended, tests] -commands = pytest panel --docs - pytest -n logical --dist loadscope --nbval-lax examples - -[_all_recommended] -description = Run all recommended tests -deps = .[recommended, tests] -commands = {[_flakes]commands} - {[_unit]commands} - {[_examples]commands} - -[_deprecations] -description = Unit tests, but DeprecationWarnings and FutureWarnings are errors -deps = .[tests] -# Not yet sure how people use these in reality vs what's in the docs (there's also PendingDeprecationWarning) -commands = pytest panel -W error::DeprecationWarning -W error::FutureWarning - -[testenv] -changedir = {envtmpdir} - -commands = unit: {[_unit]commands} - unit_deploy: {[_unit_deploy]commands} - subprocess: {[_subprocess]commands} - ui: {[_ui]commands} - flakes: {[_flakes]commands} - examples: {[_examples]commands} - all_recommended: {[_all_recommended]commands} - deprecations: {[_deprecations]commands} - -deps = unit: {[_unit]deps} - unit_deploy: {[_unit_deploy]deps} - ui: {[_ui]commands} - flakes: {[_flakes]deps} - examples: {[_examples]deps} - all_recommended: {[_all_recommended]deps} - deprecations: {[_deprecations]commands} From d2bf8cf938c5259d447df67a62938f84c378cc87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 10:47:33 +0200 Subject: [PATCH 040/130] Remove dodo.py --- dodo.py | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 dodo.py diff --git a/dodo.py b/dodo.py deleted file mode 100644 index 9dc6229de2..0000000000 --- a/dodo.py +++ /dev/null @@ -1,21 +0,0 @@ -import os - -if "PYCTDEV_ECOSYSTEM" not in os.environ: - os.environ["PYCTDEV_ECOSYSTEM"] = "conda" - -from pyctdev import * # noqa: api - - -def task_pip_on_conda(): - """Experimental: provide pip build env via conda""" - return {'actions':[ - # some ecosystem=pip build tools must be installed with conda when using conda... - 'conda install -y pip twine wheel "rfc3986>=1.4.0"', - # ..and some are only available via conda-forge - 'conda install -y -c conda-forge tox "virtualenv<=20.4.7"', - ]} - - -def _build_dev(channel): - channels = " ".join(['-c %s' % c for c in channel]) - return "conda build %s conda.recipe/ --build-only" % channels From b50d2cf0476b4c8d506bd004e429e2a15663e22c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 10:50:47 +0200 Subject: [PATCH 041/130] Create the .uicoverage file in CI --- .github/workflows/test.yaml | 4 ++-- .gitignore | 1 + .uicoveragerc | 2 -- 3 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 .uicoveragerc diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 250c9c8005..d1efd05204 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -217,9 +217,9 @@ jobs: pixi run -e ${{ matrix.environment }} test-docs $COV - name: Test UI run: | - # Read the .uicoveragerc file to set the concurrency library to greenlet - # when the test suite relies on playwright, see + # Create a .uicoveragerc file to set the concurrency library to greenlet # https://github.com/microsoft/playwright-python/issues/313 + echo "[run]\nconcurrency = greenlet" > .uicoveragerc FAIL="--screenshot only-on-failure --full-page-screenshot --output ui_screenshots" pixi run -e ${{ matrix.environment }} test-ui --jupyter $COV --cov-config=.uicoveragerc $FAIL - uses: actions/upload-artifact@v3 diff --git a/.gitignore b/.gitignore index e17944a61c..0f29f786c0 100644 --- a/.gitignore +++ b/.gitignore @@ -160,3 +160,4 @@ app_streamlit.py .pixi pixi.lock panel/_version.py +.uicoveragerc diff --git a/.uicoveragerc b/.uicoveragerc deleted file mode 100644 index 0099493102..0000000000 --- a/.uicoveragerc +++ /dev/null @@ -1,2 +0,0 @@ -[run] -concurrency = greenlet From d05c1a97b79d0a68bee8c297eab0ca2c0aec877b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 11:46:10 +0200 Subject: [PATCH 042/130] First round of fixes --- .github/workflows/test.yaml | 13 ++++++------- panel/package-lock.json | 4 ++-- panel/package.json | 2 +- pyproject.toml | 3 ++- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d1efd05204..c59b5198e0 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -198,15 +198,14 @@ jobs: - name: launch jupyter run: | # jupyter server extension enable panel.io.jupyter_server_extension --sys-prefix - pixi shell -e ${{ matrix.environment }} - (jupyter lab --config panel/tests/ui/jupyter_server_test_config.py --port 8887 > /tmp/jupyterlab_server.log 2>&1) & + (pixi run -e ${{ matrix.environment }} jupyter lab --config panel/tests/ui/jupyter_server_test_config.py --port 8887 > /tmp/jupyterlab_server.log 2>&1) & - name: build jupyterlite run: | - pixi shell -e ${{ matrix.environment }} - python -m pip install -r ./lite/requirements.txt - python ./scripts/build_pyodide_wheels.py lite/pypi - python ./scripts/panelite/generate_panelite_content.py - jupyter lite build --lite-dir lite --output-dir lite/dist + # TODO: Make this a pixi feature/environment + pixi run -e ${{ matrix.environment }} python -m pip install -r ./lite/requirements.txt + pixi run -e ${{ matrix.environment }} python ./scripts/build_pyodide_wheels.py lite/pypi + pixi run -e ${{ matrix.environment }} python ./scripts/panelite/generate_panelite_content.py + pixi run -e ${{ matrix.environment }} jupyter lite build --lite-dir lite --output-dir lite/dist - name: Wait for JupyterLab uses: ifaxity/wait-on-action@v1.1.0 with: diff --git a/panel/package-lock.json b/panel/package-lock.json index 7fba539fe9..28abb112e9 100644 --- a/panel/package-lock.json +++ b/panel/package-lock.json @@ -1,12 +1,12 @@ { "name": "@holoviz/panel", - "version": "1.4.2-rc.1", + "version": "1.4.2-rc.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@holoviz/panel", - "version": "1.4.2-rc.1", + "version": "1.4.2-rc.2", "license": "BSD-3-Clause", "dependencies": { "@bokeh/bokehjs": "~3.4.1", diff --git a/panel/package.json b/panel/package.json index 5243160276..71e984499f 100644 --- a/panel/package.json +++ b/panel/package.json @@ -1,6 +1,6 @@ { "name": "@holoviz/panel", - "version": "1.4.2-rc.1", + "version": "1.4.2-rc.2", "description": "The powerful data exploration & web app framework for Python.", "license": "BSD-3-Clause", "repository": { diff --git a/pyproject.toml b/pyproject.toml index 02265e056b..87e54fda47 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -170,7 +170,8 @@ skip = "doc/generate_modules.py,examples/reference/templates/FastGridTemplate.ip write-changes = true [tool.pytest.ini_options] -addopts = "-v --pyargs --doctest-ignore-import-errors --color=yes" +# addopts = "-v --pyargs --doctest-ignore-import-errors --color=yes" +addopts = "--pyargs --doctest-ignore-import-errors --color=yes" norecursedirs = "doc .git dist build _build .ipynb_checkpoints panel/examples" asyncio_mode = "auto" xfail_strict = true From 1551fb72fd53b8c6ad9ad69cde94d8b2274c117d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 11:57:46 +0200 Subject: [PATCH 043/130] Move test docs up --- .github/workflows/test.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c59b5198e0..08f12fc24f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -151,6 +151,9 @@ jobs: if: contains(matrix.os, 'ubuntu') run: | pixi run -e ${{ matrix.environment }} test-subprocess $COV + - name: Test docs + run: | + pixi run -e ${{ matrix.environment }} test-docs $COV - name: Test Examples run: | pixi run -e ${{ matrix.environment }} test-example @@ -211,9 +214,6 @@ jobs: with: resource: http-get://localhost:8887/lab timeout: 180000 - - name: Test docs - run: | - pixi run -e ${{ matrix.environment }} test-docs $COV - name: Test UI run: | # Create a .uicoveragerc file to set the concurrency library to greenlet From 1a51d767dd1034163e59d4f88f43cd6cae2f9248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 12:07:25 +0200 Subject: [PATCH 044/130] Fix docs error --- .github/workflows/test.yaml | 7 ++++++- panel/tests/test_docs.py | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 08f12fc24f..15386959c4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -134,6 +134,11 @@ jobs: matrix: ${{ fromJson(needs.setup.outputs.matrix) }} timeout-minutes: 90 steps: + - if: contains(matrix.os, 'ubuntu') + run: | + sudo apt-get install libglu1-mesa + /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x24 + sleep 3 - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi if: needs.setup.outputs.code_change == 'true' with: @@ -200,7 +205,7 @@ jobs: id: install - name: launch jupyter run: | - # jupyter server extension enable panel.io.jupyter_server_extension --sys-prefix + pixi run -e ${{ matrix.environment }} jupyter server extension enable panel.io.jupyter_server_extension --sys-prefix (pixi run -e ${{ matrix.environment }} jupyter lab --config panel/tests/ui/jupyter_server_test_config.py --port 8887 > /tmp/jupyterlab_server.log 2>&1) & - name: build jupyterlite run: | diff --git a/panel/tests/test_docs.py b/panel/tests/test_docs.py index bdfb3fd07e..0242fcf119 100644 --- a/panel/tests/test_docs.py +++ b/panel/tests/test_docs.py @@ -138,4 +138,4 @@ def test_markdown_codeblocks(file, tmp_path): with open(mod, 'w', encoding='utf-8') as f: f.writelines(lines) - runpy.run_path(mod) + runpy.run_path(str(mod)) From a4c01c29cb0f98c37184f07e078f9c7260736fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 13:30:01 +0200 Subject: [PATCH 045/130] Add opengl to install task --- .github/workflows/test.yaml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 15386959c4..041a61af4c 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -134,21 +134,11 @@ jobs: matrix: ${{ fromJson(needs.setup.outputs.matrix) }} timeout-minutes: 90 steps: - - if: contains(matrix.os, 'ubuntu') - run: | - sudo apt-get install libglu1-mesa - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x24 - sleep 3 - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi if: needs.setup.outputs.code_change == 'true' with: environments: ${{ matrix.environment }} - # opengl: true - # - name: override-vtk-osmesa - # if: contains(matrix.os, 'ubuntu') - # run: | - # conda activate test-environment - # conda install -c conda-forge vtk=9.2.6=osmesa* vtk-base=9.2.6=osmesa* vtk-io-ffmpeg=9.2.6=osmesa* --no-deps + opengl: true - name: Test unit run: | pixi run -e ${{ matrix.environment }} test-unit $COV From d2ed29ed174186e012d3bb34be0990c9341f020e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 13:45:34 +0200 Subject: [PATCH 046/130] Comment out validation check for now. --- panel/package-lock.json | 4 ++-- panel/package.json | 2 +- scripts/hatch_build.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/panel/package-lock.json b/panel/package-lock.json index 28abb112e9..7fba539fe9 100644 --- a/panel/package-lock.json +++ b/panel/package-lock.json @@ -1,12 +1,12 @@ { "name": "@holoviz/panel", - "version": "1.4.2-rc.2", + "version": "1.4.2-rc.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@holoviz/panel", - "version": "1.4.2-rc.2", + "version": "1.4.2-rc.1", "license": "BSD-3-Clause", "dependencies": { "@bokeh/bokehjs": "~3.4.1", diff --git a/panel/package.json b/panel/package.json index 71e984499f..5243160276 100644 --- a/panel/package.json +++ b/panel/package.json @@ -1,6 +1,6 @@ { "name": "@holoviz/panel", - "version": "1.4.2-rc.2", + "version": "1.4.2-rc.1", "description": "The powerful data exploration & web app framework for Python.", "license": "BSD-3-Clause", "repository": { diff --git a/scripts/hatch_build.py b/scripts/hatch_build.py index 15a4407a44..88981a50ea 100644 --- a/scripts/hatch_build.py +++ b/scripts/hatch_build.py @@ -74,7 +74,7 @@ def initialize(self, version: str, build_data: dict[str, t.Any]) -> None: if self.target_name not in ["wheel", "sdist"]: return - validate_js_version(self.metadata.version) + # validate_js_version(self.metadata.version) if "PANEL_LITE" not in os.environ: build_models() From af6d642cb93d4a05814538738dd4081c06461c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 14:11:40 +0200 Subject: [PATCH 047/130] Add validate js version back --- pyproject.toml | 3 +++ scripts/hatch_build.py | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 87e54fda47..f398c5bee3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,6 +104,9 @@ include = ["panel", "scripts"] [tool.hatch.build.hooks.vcs] version-file = "panel/_version.py" +[tool.hatch.version.raw-options] +version_scheme = "no-guess-dev" + [tool.hatch.build.hooks.custom] path = "scripts/hatch_build.py" diff --git a/scripts/hatch_build.py b/scripts/hatch_build.py index 88981a50ea..380db12923 100644 --- a/scripts/hatch_build.py +++ b/scripts/hatch_build.py @@ -53,7 +53,7 @@ def clean_js_version(version): def validate_js_version(version): # TODO: Double check the logic in this function - version = version.split(".dev")[0] + version = version.split(".post")[0] with open("./panel/package.json") as f: package_json = json.load(f) js_version = package_json["version"] @@ -74,7 +74,7 @@ def initialize(self, version: str, build_data: dict[str, t.Any]) -> None: if self.target_name not in ["wheel", "sdist"]: return - # validate_js_version(self.metadata.version) + validate_js_version(self.metadata.version) if "PANEL_LITE" not in os.environ: build_models() From e153669005aee1d4fff506bd5b0a3f24654a90fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 14:19:27 +0200 Subject: [PATCH 048/130] Add wait for failing ui test --- panel/tests/ui/layout/test_feed.py | 1 + 1 file changed, 1 insertion(+) diff --git a/panel/tests/ui/layout/test_feed.py b/panel/tests/ui/layout/test_feed.py index 50742a4966..f5b3b7a870 100644 --- a/panel/tests/ui/layout/test_feed.py +++ b/panel/tests/ui/layout/test_feed.py @@ -72,6 +72,7 @@ def test_feed_dynamic_objects(page): serve_component(page, feed) feed.objects = list(range(1000)) + wait_until(lambda: page.locator('pre').count() > 0, page) expect(page.locator('pre').nth(0)).to_have_text('0') wait_until(lambda: page.locator('pre').count() > 10, page) From 9c629149c979dd0aca32657b78967c062246236f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 15:32:59 +0200 Subject: [PATCH 049/130] Only mark jupyter test --- panel/tests/ui/io/test_jupyter_server_extension.py | 2 +- panel/tests/ui/io/test_jupyterlite.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/panel/tests/ui/io/test_jupyter_server_extension.py b/panel/tests/ui/io/test_jupyter_server_extension.py index 63fdc34aab..36494154a5 100644 --- a/panel/tests/ui/io/test_jupyter_server_extension.py +++ b/panel/tests/ui/io/test_jupyter_server_extension.py @@ -10,7 +10,7 @@ from panel.tests.util import wait_until -pytestmark = [pytest.mark.jupyter, pytest.mark.ui] +pytestmark = pytest.mark.jupyter diff --git a/panel/tests/ui/io/test_jupyterlite.py b/panel/tests/ui/io/test_jupyterlite.py index 9568ce0ae5..cbfd030171 100644 --- a/panel/tests/ui/io/test_jupyterlite.py +++ b/panel/tests/ui/io/test_jupyterlite.py @@ -9,7 +9,7 @@ from playwright.sync_api import expect -pytestmark = [pytest.mark.jupyter, pytest.mark.ui] +pytestmark = pytest.mark.jupyter @pytest.fixture() From 6bccb828bd8f8617fd50c50aca74ae72d29acde8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 15:41:29 +0200 Subject: [PATCH 050/130] Stabalize test_icon.py flaky test --- panel/tests/ui/widgets/test_icon.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/panel/tests/ui/widgets/test_icon.py b/panel/tests/ui/widgets/test_icon.py index 941acd44a5..afb6109412 100644 --- a/panel/tests/ui/widgets/test_icon.py +++ b/panel/tests/ui/widgets/test_icon.py @@ -344,7 +344,7 @@ def test_button_icon_name(page): serve_component(page, button) assert button.name == "Like" - assert page.locator(".bk-IconLabel").text_content() == "Like" + wait_until(page.locator(".bk-IconLabel").text_content() == "Like", page) def test_button_icon_name_dynamically(page): @@ -356,13 +356,13 @@ def test_button_icon_name_dynamically(page): button.name = "Dislike" assert button.name == "Dislike" - assert page.locator(".bk-IconLabel").text_content() == "Dislike" + wait_until(lambda: page.locator(".bk-IconLabel").text_content() == "Dislike", page) assert page.locator(".bk-IconLabel").bounding_box()["width"] < 40 button.size = "2em" # check size - assert page.locator(".bk-IconLabel").bounding_box()["width"] >= 40 + wait_until(lambda: page.locator(".bk-IconLabel").bounding_box()["width"] >= 40, page) def test_button_icon_description_dynamically(page): @@ -370,9 +370,10 @@ def test_button_icon_description_dynamically(page): serve_component(page, button) assert button.description == "Like" + wait_until(lambda: page.locator(".bk-TablerIcon"), page) page.locator(".bk-TablerIcon").click() assert page.locator(".bk-tooltip-content").text_content() == "Like" button.description = "Dislike" page.locator(".bk-TablerIcon").click() - assert page.locator(".bk-tooltip-content").text_content() == "Dislike" + wait_until(lambda: page.locator(".bk-tooltip-content").text_content() == "Dislike", page) From 28912bcd3301a434ef1f4889159cea1b2de46cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 15:50:36 +0200 Subject: [PATCH 051/130] Try something with dynamic feed --- panel/tests/ui/layout/test_feed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panel/tests/ui/layout/test_feed.py b/panel/tests/ui/layout/test_feed.py index f5b3b7a870..8c3762fdf3 100644 --- a/panel/tests/ui/layout/test_feed.py +++ b/panel/tests/ui/layout/test_feed.py @@ -72,7 +72,7 @@ def test_feed_dynamic_objects(page): serve_component(page, feed) feed.objects = list(range(1000)) - wait_until(lambda: page.locator('pre').count() > 0, page) + wait_until(lambda: page.locator('pre'), page) expect(page.locator('pre').nth(0)).to_have_text('0') wait_until(lambda: page.locator('pre').count() > 10, page) From a3f450ab78c19ff26875d94a03381e46eba74173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 18:24:13 +0200 Subject: [PATCH 052/130] Update ui tests --- panel/tests/ui/layout/test_feed.py | 2 +- panel/tests/ui/widgets/test_icon.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/panel/tests/ui/layout/test_feed.py b/panel/tests/ui/layout/test_feed.py index 8c3762fdf3..df3134ff5d 100644 --- a/panel/tests/ui/layout/test_feed.py +++ b/panel/tests/ui/layout/test_feed.py @@ -72,7 +72,7 @@ def test_feed_dynamic_objects(page): serve_component(page, feed) feed.objects = list(range(1000)) - wait_until(lambda: page.locator('pre'), page) + wait_until(lambda: page.locator('pre') is not None, page) expect(page.locator('pre').nth(0)).to_have_text('0') wait_until(lambda: page.locator('pre').count() > 10, page) diff --git a/panel/tests/ui/widgets/test_icon.py b/panel/tests/ui/widgets/test_icon.py index afb6109412..e284f839ab 100644 --- a/panel/tests/ui/widgets/test_icon.py +++ b/panel/tests/ui/widgets/test_icon.py @@ -344,7 +344,7 @@ def test_button_icon_name(page): serve_component(page, button) assert button.name == "Like" - wait_until(page.locator(".bk-IconLabel").text_content() == "Like", page) + wait_until(lambda: page.locator(".bk-IconLabel").text_content() == "Like", page) def test_button_icon_name_dynamically(page): @@ -370,7 +370,7 @@ def test_button_icon_description_dynamically(page): serve_component(page, button) assert button.description == "Like" - wait_until(lambda: page.locator(".bk-TablerIcon"), page) + wait_until(lambda: page.locator(".bk-TablerIcon") is not None, page) page.locator(".bk-TablerIcon").click() assert page.locator(".bk-tooltip-content").text_content() == "Like" From 2f80d5c0b6d25ae3b1a2564593ef17911689edce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 18:35:52 +0200 Subject: [PATCH 053/130] Update build --- .github/workflows/build.yaml | 51 ++++++++++++++---------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index bd2c44738b..da19bcd931 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -20,7 +20,6 @@ env: PYTHON_VERSION: "3.11" NODE_VERSION: "20" MPLBACKEND: "Agg" - SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" jobs: waiting_room: @@ -33,33 +32,28 @@ jobs: steps: - run: echo "All builds have finished, have been approved, and ready to publish" + pixi_lock: + name: Pixi lock + runs-on: ubuntu-latest + steps: + - uses: holoviz-dev/holoviz_tasks/pixi_lock@pixi + conda_build: name: Build Conda + needs: [pixi_lock] runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@v4 - with: - fetch-depth: "100" - - name: Fetch unshallow - run: git fetch --prune --tags --unshallow -f - - uses: conda-incubator/setup-miniconda@v3 + - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: - miniconda-version: "latest" - - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - name: conda setup - run: | - conda install -y conda-build build + environments: "build" + download-data: false - name: conda build - run: | - source ./scripts/build_conda.sh - echo "CONDA_FILE="$CONDA_PREFIX/conda-bld/noarch/$PACKAGE-$VERSION-py_0.tar.bz2"" >> $GITHUB_ENV + run: pixi run -e build build-conda - uses: actions/upload-artifact@v4 if: always() with: name: conda - path: ${{ env.CONDA_FILE }} + path: dist/*tar.bz2 if-no-files-found: error conda_publish: @@ -93,24 +87,15 @@ jobs: pip_build: name: Build PyPI + needs: [pixi_lock] runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@v4 + - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: - fetch-depth: "100" - - name: Fetch unshallow - run: git fetch --prune --tags --unshallow -f - - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PYTHON_VERSION }} - - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - name: Install build - run: | - python -m pip install build + environments: "build" + download-data: false - name: Build package - run: python -m build . + run: pixi run -e build build-pip - uses: actions/upload-artifact@v4 if: always() with: @@ -154,6 +139,7 @@ jobs: npm_build: name: Build NPM + needs: [pixi_lock] runs-on: "ubuntu-latest" steps: - uses: actions/checkout@v4 @@ -216,6 +202,7 @@ jobs: cdn_build: name: Build CDN + needs: [pixi_lock] runs-on: "ubuntu-latest" steps: - uses: actions/checkout@v4 From e671561f569828b3da05015325ff098e1b7a7a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 18:52:49 +0200 Subject: [PATCH 054/130] Only install if needed, try npm and cdn --- .github/workflows/build.yaml | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index da19bcd931..f01ed190df 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -46,6 +46,7 @@ jobs: - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: environments: "build" + install: false download-data: false - name: conda build run: pixi run -e build build-conda @@ -93,6 +94,7 @@ jobs: - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: environments: "build" + install: false download-data: false - name: Build package run: pixi run -e build build-pip @@ -142,20 +144,10 @@ jobs: needs: [pixi_lock] runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@v4 - with: - fetch-depth: "100" - - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PYTHON_VERSION }} - - uses: actions/setup-node@v4 + - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: - node-version: ${{ env.NODE_VERSION }} - - name: Fetch unshallow - run: git fetch --prune --tags --unshallow -f - - name: package install - run: | - python -m pip install -ve . + environments: "build" + download-data: false - name: npm build run: | cd ${{ env.PACKAGE }} @@ -205,17 +197,11 @@ jobs: needs: [pixi_lock] runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@v4 - with: - fetch-depth: "100" - - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PYTHON_VERSION }} - - uses: actions/setup-node@v4 + - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: - node-version: ${{ env.NODE_VERSION }} - - name: Fetch unshallow - run: git fetch --prune --tags --unshallow -f + environments: "build" + install: false + download-data: false - name: build pyodide wheels run: | python -m pip install packaging From c8ddf6cc7708be340c01c81704549c4bd9baccbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 18:54:49 +0200 Subject: [PATCH 055/130] wait until for flaky tabulator test --- panel/tests/ui/widgets/test_tabulator.py | 1 + 1 file changed, 1 insertion(+) diff --git a/panel/tests/ui/widgets/test_tabulator.py b/panel/tests/ui/widgets/test_tabulator.py index 211baf7ff6..ea6ff15be2 100644 --- a/panel/tests/ui/widgets/test_tabulator.py +++ b/panel/tests/ui/widgets/test_tabulator.py @@ -2286,6 +2286,7 @@ def test_tabulator_patching_and_styling(page, df_mixed): widget.patch({'int': [(0, 100)]}, as_index=False) max_int = df_mixed['int'].max() + wait_until(lambda: page.locator('.tabulator-cell', has=page.locator(f'text="{max_int}"')) is not None, page) max_cell = page.locator('.tabulator-cell', has=page.locator(f'text="{max_int}"')) expect(max_cell).to_have_count(1) expect(max_cell).to_have_css('background-color', _color_mapping['yellow']) From 73b426ce8b3db29b2fa42dffbea66ef722075d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 22 Apr 2024 20:46:46 +0200 Subject: [PATCH 056/130] More wait_until in test_feed --- panel/tests/ui/layout/test_feed.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/panel/tests/ui/layout/test_feed.py b/panel/tests/ui/layout/test_feed.py index df3134ff5d..a76e8f1c78 100644 --- a/panel/tests/ui/layout/test_feed.py +++ b/panel/tests/ui/layout/test_feed.py @@ -73,6 +73,7 @@ def test_feed_dynamic_objects(page): feed.objects = list(range(1000)) wait_until(lambda: page.locator('pre') is not None, page) + wait_until(lambda: page.locator('pre').first is not None, page) - expect(page.locator('pre').nth(0)).to_have_text('0') + expect(page.locator('pre').first).to_have_text('0') wait_until(lambda: page.locator('pre').count() > 10, page) From 7d7b9588d1b61e59cbde603da926477d553126a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 07:30:23 +0200 Subject: [PATCH 057/130] Small misc changes --- .github/workflows/test.yaml | 3 +-- pyproject.toml | 6 ++---- scripts/conda/recipe/meta.yaml | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 041a61af4c..1cad06d8a4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -135,7 +135,6 @@ jobs: timeout-minutes: 90 steps: - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi - if: needs.setup.outputs.code_change == 'true' with: environments: ${{ matrix.environment }} opengl: true @@ -164,7 +163,7 @@ jobs: strategy: fail-fast: false matrix: - os: ["ubuntu-latest", "macos-latest", "windows-latest"] + os: ["ubuntu-latest", "macos-14", "windows-latest"] environment: ["test-ui"] timeout-minutes: 120 env: diff --git a/pyproject.toml b/pyproject.toml index f398c5bee3..2e7496dae4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,7 +66,7 @@ dependencies = [ [project.urls] Homepage = "https://panel.holoviz.org" -Source = "http://github.com/holoviz/panel" +Source = "https://github.com/holoviz/panel" HoloViz = "https://holoviz.org/" [project.optional-dependencies] @@ -84,6 +84,7 @@ panel = "panel.command:main" [tool.hatch.version] source = "vcs" +raw-options = { version_scheme = "no-guess-dev" } [tool.hatch.build.targets.wheel] include = ["panel"] @@ -104,9 +105,6 @@ include = ["panel", "scripts"] [tool.hatch.build.hooks.vcs] version-file = "panel/_version.py" -[tool.hatch.version.raw-options] -version_scheme = "no-guess-dev" - [tool.hatch.build.hooks.custom] path = "scripts/hatch_build.py" diff --git a/scripts/conda/recipe/meta.yaml b/scripts/conda/recipe/meta.yaml index 909523d832..97bab6272a 100644 --- a/scripts/conda/recipe/meta.yaml +++ b/scripts/conda/recipe/meta.yaml @@ -10,7 +10,7 @@ source: build: noarch: python - script: {{ PYTHON }} -m pip install -vv {{ project["name"] }}-{{ VERSION }}-py3-none-any.whl + script: {{ PYTHON }} -m pip install --no-deps -vv {{ project["name"] }}-{{ VERSION }}-py3-none-any.whl entry_points: {% for group,epoints in project.get("entry_points",{}).items() %} {% for entry_point in epoints %} From 0eea092e4eae85a6f883fed91a9ce53dede9e14b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 08:48:17 +0200 Subject: [PATCH 058/130] Move some packages from test-core to test --- pixi.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pixi.toml b/pixi.toml index db7557d0b4..c737e5afd2 100644 --- a/pixi.toml +++ b/pixi.toml @@ -93,9 +93,6 @@ xgboost = "*" # =================== TESTS =================== # ============================================= [feature.test-core.dependencies] -altair = "*" -anywidget = "*" -diskcache = "*" psutil = "*" pytest = "*" pytest-asyncio = "*" @@ -105,6 +102,9 @@ pytest-rerunfailures = "*" pytest-xdist = "*" [feature.test.dependencies] +altair = "*" +anywidget = "*" +diskcache = "*" folium = "*" ipympl = "*" ipyvuetify = "*" From 75fbc8a58213837dbf288772f641e24649021b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 08:51:38 +0200 Subject: [PATCH 059/130] Use shell instead pixi run for every command --- .github/workflows/build.yaml | 3 ++- .github/workflows/test.yaml | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f01ed190df..ad2a2cde7e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -149,6 +149,7 @@ jobs: environments: "build" download-data: false - name: npm build + shell: pixi run -e build bash -el {0} run: | cd ${{ env.PACKAGE }} TARBALL=$(npm pack .) @@ -203,8 +204,8 @@ jobs: install: false download-data: false - name: build pyodide wheels + shell: pixi run -e build bash -el {0} run: | - python -m pip install packaging python ./scripts/build_pyodide_wheels.py --verify-clean - name: build CDN run: | diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 1cad06d8a4..7f1caae780 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -193,16 +193,18 @@ jobs: environments: ${{ matrix.environment }} id: install - name: launch jupyter + shell: pixi run -e test-ui bash -el {0} run: | - pixi run -e ${{ matrix.environment }} jupyter server extension enable panel.io.jupyter_server_extension --sys-prefix - (pixi run -e ${{ matrix.environment }} jupyter lab --config panel/tests/ui/jupyter_server_test_config.py --port 8887 > /tmp/jupyterlab_server.log 2>&1) & + jupyter server extension enable panel.io.jupyter_server_extension --sys-prefix + (jupyter lab --config panel/tests/ui/jupyter_server_test_config.py --port 8887 > /tmp/jupyterlab_server.log 2>&1) & - name: build jupyterlite + shell: pixi run -e test-ui bash -el {0} run: | # TODO: Make this a pixi feature/environment - pixi run -e ${{ matrix.environment }} python -m pip install -r ./lite/requirements.txt - pixi run -e ${{ matrix.environment }} python ./scripts/build_pyodide_wheels.py lite/pypi - pixi run -e ${{ matrix.environment }} python ./scripts/panelite/generate_panelite_content.py - pixi run -e ${{ matrix.environment }} jupyter lite build --lite-dir lite --output-dir lite/dist + python -m pip install -r ./lite/requirements.txt + python ./scripts/build_pyodide_wheels.py lite/pypi + python ./scripts/panelite/generate_panelite_content.py + jupyter lite build --lite-dir lite --output-dir lite/dist - name: Wait for JupyterLab uses: ifaxity/wait-on-action@v1.1.0 with: From 2c4873fc3c5e30fa512d3cd2e76c8f24167169c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 09:18:58 +0200 Subject: [PATCH 060/130] Update build cdn --- .github/workflows/build.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ad2a2cde7e..257b3e7a99 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -204,12 +204,11 @@ jobs: install: false download-data: false - name: build pyodide wheels - shell: pixi run -e build bash -el {0} run: | - python ./scripts/build_pyodide_wheels.py --verify-clean + pixi run build-pyodide --verify-clean - name: build CDN run: | - python -m pip install -ve . + pixi run build-pip - uses: actions/upload-artifact@v4 if: always() with: From e2a4c3310dde86de5c77808cb5abfa8ace08c0f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 18:00:23 +0200 Subject: [PATCH 061/130] Add tracing back to ui test workflow --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 0ccff5feb7..49d10d3be1 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -221,7 +221,7 @@ jobs: # Create a .uicoveragerc file to set the concurrency library to greenlet # https://github.com/microsoft/playwright-python/issues/313 echo "[run]\nconcurrency = greenlet" > .uicoveragerc - FAIL="--screenshot only-on-failure --full-page-screenshot --output ui_screenshots" + FAIL="--screenshot only-on-failure --full-page-screenshot --output ui_screenshots --tracing retain-on-failure" pixi run -e ${{ matrix.environment }} test-ui --jupyter $COV --cov-config=.uicoveragerc $FAIL - uses: actions/upload-artifact@v3 if: always() From db9153f62ec7775de2adab923af52d5ce94dc30e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 18:29:16 +0200 Subject: [PATCH 062/130] Kill jupyter lab for Windows --- .github/workflows/test.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 49d10d3be1..87f5ddd2ea 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -229,6 +229,11 @@ jobs: name: ui_screenshots path: ./ui_screenshots if-no-files-found: ignore + - name: Kill Jupyter Lab + if: always() + run: | + kill $(lsof -ti :8887) || true + sleep 5 - uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} From 26a7ff91ec9bc653e2728b0bdfdd6fb90a746689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 18:39:20 +0200 Subject: [PATCH 063/130] Format docs --- .github/workflows/docs.yaml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index f2c5fdac86..446dec37ec 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -3,32 +3,32 @@ name: docs on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+a[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+b[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+rc[0-9]+' + - "v[0-9]+.[0-9]+.[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+a[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+b[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+rc[0-9]+" workflow_dispatch: inputs: target: - description: 'Site to build and deploy' + description: "Site to build and deploy" type: choice options: - - dev - - main - - dryrun + - dev + - main + - dryrun required: true default: dryrun schedule: - - cron: '0 19 * * SUN' + - cron: "0 19 * * SUN" jobs: build_docs: name: Documentation - runs-on: 'macos-14' + runs-on: "macos-14" timeout-minutes: 180 defaults: run: - shell: bash -l {0} + shell: bash -el {0} env: DESC: "Documentation build" MPLBACKEND: "Agg" @@ -37,12 +37,12 @@ jobs: DISPLAY: ":99.0" PANEL_IPYWIDGET: 1 steps: - - uses: holoviz-dev/holoviz_tasks/install@v0 + - uses: holoviz-dev/holoviz_tasks/install@v0.1a19 with: name: doc_build python-version: "3.11" channels: pyviz/label/dev,conda-forge,bokeh,nodefaults - conda-update: 'true' + conda-update: "true" nodejs: true nodejs-version: 20 # Remove when all examples tools can be installed on 3.10 From 8c739b0e8a685b00b27dd542ba063e5c269f8319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 18:45:42 +0200 Subject: [PATCH 064/130] Update docs --- .github/workflows/docs.yaml | 49 +++++-------------------------------- 1 file changed, 6 insertions(+), 43 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 446dec37ec..2719b23aed 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -30,57 +30,20 @@ jobs: run: shell: bash -el {0} env: - DESC: "Documentation build" MPLBACKEND: "Agg" - SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" MOZ_HEADLESS: 1 DISPLAY: ":99.0" PANEL_IPYWIDGET: 1 steps: - - uses: holoviz-dev/holoviz_tasks/install@v0.1a19 + - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: - name: doc_build - python-version: "3.11" - channels: pyviz/label/dev,conda-forge,bokeh,nodefaults - conda-update: "true" - nodejs: true - nodejs-version: 20 - # Remove when all examples tools can be installed on 3.10 - envs: -o examples -o doc -o build - cache: true + environments: docs opengl: true - - name: doit develop_install - if: steps.install.outputs.cache-hit != 'true' - run: | - conda activate test-environment - pip install --use-deprecated=legacy-resolver pyecharts ipywidgets_bokeh==1.5.0 - - name: bokeh sampledata - run: | - conda activate test-environment - bokeh sampledata - - name: refmanual - run: | - conda activate test-environment - python ./doc/generate_modules.py panel -d ./doc/api -n panel -e tests - - name: build docs - run: | - conda activate test-environment - python scripts/gallery/convert_gallery.py - nbsite build --what=html --output=builtdocs --org holoviz --project-name panel - cp -r ./panel/dist ./builtdocs/panel_dist - - name: convert gallery - run: | - conda activate test-environment - panel convert examples/gallery/*.ipynb doc/how_to/*/examples/*.md --to pyodide-worker --out ./builtdocs/pyodide/ --pwa --index --requirements doc/pyodide_dependencies.json - - name: git status and git diff - run: | - git status - git diff - - name: Set and echo git ref + - name: Build documentation + run: pixi run -e docs docs-build + - name: Set output id: vars - run: | - echo "Deploying from ref ${GITHUB_REF#refs/*/}" - echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT + run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT - name: Deploy dev uses: peaceiris/actions-gh-pages@v3 if: | From c6662f23bd8478418278e8c838295db72b4d13a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 18:53:51 +0200 Subject: [PATCH 065/130] Switch to build and publish for docs --- .github/workflows/docs.yaml | 87 +++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 2719b23aed..d00d65957a 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -21,19 +21,23 @@ on: schedule: - cron: "0 19 * * SUN" +defaults: + run: + shell: bash -el {0} + +env: + MPLBACKEND: "Agg" + MOZ_HEADLESS: 1 + DISPLAY: ":99.0" + PANEL_IPYWIDGET: 1 + jobs: - build_docs: + docs_build: name: Documentation runs-on: "macos-14" timeout-minutes: 180 - defaults: - run: - shell: bash -el {0} - env: - MPLBACKEND: "Agg" - MOZ_HEADLESS: 1 - DISPLAY: ":99.0" - PANEL_IPYWIDGET: 1 + outputs: + tag: ${{ steps.vars.outputs.tag }} steps: - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: @@ -41,26 +45,53 @@ jobs: opengl: true - name: Build documentation run: pixi run -e docs docs-build + - uses: actions/upload-artifact@v4 + if: always() + with: + name: docs + if-no-files-found: error + path: builddocs - name: Set output id: vars run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT - - name: Deploy dev - uses: peaceiris/actions-gh-pages@v3 - if: | - (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'dev') || - (github.event_name == 'push' && (contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) - with: - personal_token: ${{ secrets.ACCESS_TOKEN }} - external_repository: holoviz-dev/panel - publish_dir: ./builtdocs - force_orphan: true - - name: Deploy main - if: | - (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'main') || - (github.event_name == 'push' && !(contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) - uses: peaceiris/actions-gh-pages@v3 + - name: TEST + run: | + echo ${{ steps.vars.outputs.tag }} + ls -la builddocs + + docs_publish: + name: Publish CDN + runs-on: "ubuntu-latest" + needs: [docs_build] + steps: + - uses: actions/download-artifact@v4 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./builtdocs - cname: panel.holoviz.org - force_orphan: true + name: docs + path: builddocs/ + - name: Set output + id: vars + run: echo "tag=${{ needs.docs_build.outputs.tag }}" >> $GITHUB_OUTPUT + - name: TEST + run: | + echo ${{ steps.vars.outputs.tag }} + ls -la builddocs + # - name: Deploy dev + # uses: peaceiris/actions-gh-pages@v3 + # if: | + # (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'dev') || + # (github.event_name == 'push' && (contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) + # with: + # personal_token: ${{ secrets.ACCESS_TOKEN }} + # external_repository: holoviz-dev/panel + # publish_dir: ./builtdocs + # force_orphan: true + # - name: Deploy main + # if: | + # (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'main') || + # (github.event_name == 'push' && !(contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) + # uses: peaceiris/actions-gh-pages@v3 + # with: + # github_token: ${{ secrets.GITHUB_TOKEN }} + # publish_dir: ./builtdocs + # cname: panel.holoviz.org + # force_orphan: true From 66e2d8859c9f01023fd1ee1cbe21740acc431640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 19:20:17 +0200 Subject: [PATCH 066/130] Update Stop Jupyter Lab step --- .github/workflows/test.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 87f5ddd2ea..b60e41e143 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -198,12 +198,12 @@ jobs: with: environments: ${{ matrix.environment }} id: install - - name: launch jupyter + - name: Launch JupyterLab shell: pixi run -e test-ui bash -el {0} run: | jupyter server extension enable panel.io.jupyter_server_extension --sys-prefix (jupyter lab --config panel/tests/ui/jupyter_server_test_config.py --port 8887 > /tmp/jupyterlab_server.log 2>&1) & - - name: build jupyterlite + - name: Build JupyterLite shell: pixi run -e test-ui bash -el {0} run: | # TODO: Make this a pixi feature/environment @@ -229,11 +229,11 @@ jobs: name: ui_screenshots path: ./ui_screenshots if-no-files-found: ignore - - name: Kill Jupyter Lab + - name: Stop JupyterLab if: always() + shell: pixi run -e test-ui bash -el {0} run: | - kill $(lsof -ti :8887) || true - sleep 5 + jupyter lab stop 8887 || true - uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} From d29423e558d72e88e0cfdaa2a156f0059282b4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 19:54:00 +0200 Subject: [PATCH 067/130] Fix spelling mistake... --- .github/workflows/docs.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index d00d65957a..6d890c0dbe 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -50,14 +50,14 @@ jobs: with: name: docs if-no-files-found: error - path: builddocs + path: builtdocs - name: Set output id: vars run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT - name: TEST run: | echo ${{ steps.vars.outputs.tag }} - ls -la builddocs + ls -la builtdocs docs_publish: name: Publish CDN @@ -67,14 +67,14 @@ jobs: - uses: actions/download-artifact@v4 with: name: docs - path: builddocs/ + path: builtdocs/ - name: Set output id: vars run: echo "tag=${{ needs.docs_build.outputs.tag }}" >> $GITHUB_OUTPUT - name: TEST run: | echo ${{ steps.vars.outputs.tag }} - ls -la builddocs + ls -la builtdocs # - name: Deploy dev # uses: peaceiris/actions-gh-pages@v3 # if: | From 082d5ddc0429893c7940a21f4206bab5dd1b322f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 23 Apr 2024 19:58:06 +0200 Subject: [PATCH 068/130] Add pixi-lock to docs build --- .github/workflows/docs.yaml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 6d890c0dbe..253e925bf6 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -32,8 +32,15 @@ env: PANEL_IPYWIDGET: 1 jobs: + pixi_lock: + name: Pixi lock + runs-on: ubuntu-latest + steps: + - uses: holoviz-dev/holoviz_tasks/pixi_lock@pixi + docs_build: - name: Documentation + name: Build Documentation + needs: [pixi_lock] runs-on: "macos-14" timeout-minutes: 180 outputs: @@ -60,7 +67,7 @@ jobs: ls -la builtdocs docs_publish: - name: Publish CDN + name: Publish Documentation runs-on: "ubuntu-latest" needs: [docs_build] steps: From 766211f14ba1001e7b788bf85f65848ae5ac0bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 06:45:36 +0200 Subject: [PATCH 069/130] Remove test and uncomment upload parts for docs --- .github/workflows/docs.yaml | 48 ++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 253e925bf6..082ebd3506 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -61,10 +61,6 @@ jobs: - name: Set output id: vars run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT - - name: TEST - run: | - echo ${{ steps.vars.outputs.tag }} - ls -la builtdocs docs_publish: name: Publish Documentation @@ -78,27 +74,23 @@ jobs: - name: Set output id: vars run: echo "tag=${{ needs.docs_build.outputs.tag }}" >> $GITHUB_OUTPUT - - name: TEST - run: | - echo ${{ steps.vars.outputs.tag }} - ls -la builtdocs - # - name: Deploy dev - # uses: peaceiris/actions-gh-pages@v3 - # if: | - # (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'dev') || - # (github.event_name == 'push' && (contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) - # with: - # personal_token: ${{ secrets.ACCESS_TOKEN }} - # external_repository: holoviz-dev/panel - # publish_dir: ./builtdocs - # force_orphan: true - # - name: Deploy main - # if: | - # (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'main') || - # (github.event_name == 'push' && !(contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) - # uses: peaceiris/actions-gh-pages@v3 - # with: - # github_token: ${{ secrets.GITHUB_TOKEN }} - # publish_dir: ./builtdocs - # cname: panel.holoviz.org - # force_orphan: true + - name: Deploy dev + uses: peaceiris/actions-gh-pages@v3 + if: | + (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'dev') || + (github.event_name == 'push' && (contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) + with: + personal_token: ${{ secrets.ACCESS_TOKEN }} + external_repository: holoviz-dev/panel + publish_dir: ./builtdocs + force_orphan: true + - name: Deploy main + if: | + (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'main') || + (github.event_name == 'push' && !(contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./builtdocs + cname: panel.holoviz.org + force_orphan: true From 5f7161f517c544b24c349bd9bb6cd1ed67633c5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 06:48:11 +0200 Subject: [PATCH 070/130] Bump peaceiris/action --- .github/workflows/docs.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 082ebd3506..0977be98b7 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -75,7 +75,7 @@ jobs: id: vars run: echo "tag=${{ needs.docs_build.outputs.tag }}" >> $GITHUB_OUTPUT - name: Deploy dev - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 if: | (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'dev') || (github.event_name == 'push' && (contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) @@ -88,7 +88,7 @@ jobs: if: | (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'main') || (github.event_name == 'push' && !(contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./builtdocs From 73c3664e9c654936326ffd33bd5fa599301abda0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 06:51:47 +0200 Subject: [PATCH 071/130] Bump action version in test.yaml --- .github/workflows/test.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b60e41e143..ea88f9e291 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -212,7 +212,7 @@ jobs: python ./scripts/panelite/generate_panelite_content.py jupyter lite build --lite-dir lite --output-dir lite/dist - name: Wait for JupyterLab - uses: ifaxity/wait-on-action@v1.1.0 + uses: ifaxity/wait-on-action@v1.2.0 with: resource: http-get://localhost:8887/lab timeout: 180000 @@ -221,13 +221,13 @@ jobs: # Create a .uicoveragerc file to set the concurrency library to greenlet # https://github.com/microsoft/playwright-python/issues/313 echo "[run]\nconcurrency = greenlet" > .uicoveragerc - FAIL="--screenshot only-on-failure --full-page-screenshot --output ui_screenshots --tracing retain-on-failure" + FAIL="--screenshot only-on-failure --full-page-screenshot --output ui_screenshots_${{ matrix.os }} --tracing retain-on-failure" pixi run -e ${{ matrix.environment }} test-ui --jupyter $COV --cov-config=.uicoveragerc $FAIL - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: always() with: name: ui_screenshots - path: ./ui_screenshots + path: ./ui_screenshots_${{ matrix.os }} if-no-files-found: ignore - name: Stop JupyterLab if: always() From 2ccccd064c3fb217821161d283e06cb11efba695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 06:52:59 +0200 Subject: [PATCH 072/130] Add tqdm to dependencies --- pixi.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pixi.toml b/pixi.toml index c737e5afd2..f835f31a22 100644 --- a/pixi.toml +++ b/pixi.toml @@ -32,6 +32,7 @@ param = ">=2.0.0,<3.0" pip = "*" pyviz_comms = ">=2.0.0" requests = "*" +tqdm = ">=4.48.0" typing_extensions = "*" # Recommended holoviews = ">=1.16.0" From c0e71ac9ed7c0b47465042a83d17988e36eb9b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 07:02:06 +0200 Subject: [PATCH 073/130] Downgrade for wait-on-action --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ea88f9e291..ab1f4ed89f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -212,7 +212,7 @@ jobs: python ./scripts/panelite/generate_panelite_content.py jupyter lite build --lite-dir lite --output-dir lite/dist - name: Wait for JupyterLab - uses: ifaxity/wait-on-action@v1.2.0 + uses: ifaxity/wait-on-action@v1.1.0 with: resource: http-get://localhost:8887/lab timeout: 180000 From 78d9432b490676409834a4f14452fd599d2898b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 07:21:17 +0200 Subject: [PATCH 074/130] Only change the name of upload artifact --- .github/workflows/test.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ab1f4ed89f..82e62459b7 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -221,13 +221,13 @@ jobs: # Create a .uicoveragerc file to set the concurrency library to greenlet # https://github.com/microsoft/playwright-python/issues/313 echo "[run]\nconcurrency = greenlet" > .uicoveragerc - FAIL="--screenshot only-on-failure --full-page-screenshot --output ui_screenshots_${{ matrix.os }} --tracing retain-on-failure" + FAIL="--screenshot only-on-failure --full-page-screenshot --output ui_screenshots --tracing retain-on-failure" pixi run -e ${{ matrix.environment }} test-ui --jupyter $COV --cov-config=.uicoveragerc $FAIL - uses: actions/upload-artifact@v4 if: always() with: - name: ui_screenshots - path: ./ui_screenshots_${{ matrix.os }} + name: ui_screenshots_${{ matrix.os }} + path: ./ui_screenshots if-no-files-found: ignore - name: Stop JupyterLab if: always() From 9aff7f54d2577fe63c7d1cce338a0f08e54198d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 10:09:44 +0200 Subject: [PATCH 075/130] Add page to wait_for_server --- panel/tests/util.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/panel/tests/util.py b/panel/tests/util.py index eeaefae783..9503d0988d 100644 --- a/panel/tests/util.py +++ b/panel/tests/util.py @@ -275,7 +275,7 @@ def serve_and_wait(app, page=None, prefix=None, port=None, **kwargs): wait_until(lambda: server_id in state._servers, page) server = state._servers[server_id][0] port = server.port - wait_for_server(port, prefix=prefix) + wait_for_server(port, prefix=prefix, page=page) return port @@ -297,7 +297,7 @@ def serve_and_request(app, suffix="", n=1, port=None, **kwargs): return reqs[0] if len(reqs) == 1 else reqs -def wait_for_server(port, prefix=None, timeout=3): +def wait_for_server(port, prefix=None, timeout=3, page=None): start = time.time() prefix = prefix or "" url = f"http://localhost:{port}{prefix}/liveness" @@ -307,7 +307,10 @@ def wait_for_server(port, prefix=None, timeout=3): return except Exception: pass - time.sleep(0.05) + if page: + page.wait_for_timeout(50) + else: + time.sleep(0.05) if (time.time()-start) > timeout: raise RuntimeError(f'{url} did not respond before timeout.') From ea844889a34c9d5710686bd7c5e82597410496c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 10:10:13 +0200 Subject: [PATCH 076/130] Add task docs-server --- pixi.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pixi.toml b/pixi.toml index f835f31a22..029c3c4468 100644 --- a/pixi.toml +++ b/pixi.toml @@ -155,6 +155,7 @@ docs-convert-gallery = 'python scripts/gallery/convert_gallery.py' docs-generate = 'nbsite build --what=html --output=builtdocs --org holoviz --project-name panel' docs-copy-panel-dist = 'cp -r ./panel/dist ./builtdocs/panel_dist' docs-pyodide = 'panel convert examples/gallery/*.ipynb doc/how_to/*/examples/*.md --to pyodide-worker --out ./builtdocs/pyodide/ --pwa --index --requirements doc/pyodide_dependencies.json' +docs-server = 'python -m http.server 5500 --directory ./builtdocs' [feature.doc.tasks.docs-build] depends_on = ['docs-refmanual', 'docs-convert-gallery', 'docs-generate', 'docs-copy-panel-dist', 'docs-pyodide'] From 4e9c98708d44ba0508ef69e7a23442a010a0e625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 10:24:33 +0200 Subject: [PATCH 077/130] Make private tasks start with x --- pixi.toml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pixi.toml b/pixi.toml index 029c3c4468..8febfb34a8 100644 --- a/pixi.toml +++ b/pixi.toml @@ -135,11 +135,11 @@ pytest-playwright = "*" jupyter_server = "*" [feature.test-ui.tasks] -install-ui = 'playwright install chromium' +x-install-ui = 'playwright install chromium' [feature.test-ui.tasks.test-ui] cmd = 'pytest panel/tests/ui --ui --browser chromium -n logical --dist loadgroup --reruns 3 --reruns-delay 10' -depends_on = ["install-ui"] +depends_on = ["x-install-ui"] # ============================================= # =================== DOCS ==================== @@ -150,15 +150,15 @@ nbsite = ">=0.8.4" pandas = "<2.1.0" # Avoid deprecation warnings [feature.doc.tasks] -docs-refmanual = 'python ./doc/generate_modules.py panel -d ./doc/api -n panel -e tests' -docs-convert-gallery = 'python scripts/gallery/convert_gallery.py' -docs-generate = 'nbsite build --what=html --output=builtdocs --org holoviz --project-name panel' -docs-copy-panel-dist = 'cp -r ./panel/dist ./builtdocs/panel_dist' -docs-pyodide = 'panel convert examples/gallery/*.ipynb doc/how_to/*/examples/*.md --to pyodide-worker --out ./builtdocs/pyodide/ --pwa --index --requirements doc/pyodide_dependencies.json' +x-docs-refmanual = 'python ./doc/generate_modules.py panel -d ./doc/api -n panel -e tests' +x-docs-convert-gallery = 'python scripts/gallery/convert_gallery.py' +x-docs-generate = 'nbsite build --what=html --output=builtdocs --org holoviz --project-name panel' +x-docs-copy-panel-dist = 'cp -r ./panel/dist ./builtdocs/panel_dist' +x-docs-pyodide = 'panel convert examples/gallery/*.ipynb doc/how_to/*/examples/*.md --to pyodide-worker --out ./builtdocs/pyodide/ --pwa --index --requirements doc/pyodide_dependencies.json' docs-server = 'python -m http.server 5500 --directory ./builtdocs' [feature.doc.tasks.docs-build] -depends_on = ['docs-refmanual', 'docs-convert-gallery', 'docs-generate', 'docs-copy-panel-dist', 'docs-pyodide'] +depends_on = ['x-docs-refmanual', 'x-docs-convert-gallery', 'x-docs-generate', 'x-docs-copy-panel-dist', 'x-docs-pyodide'] # ============================================= # ================== BUILD ==================== From 82de22cddad90cbcb95498861a919e3fc9bed7c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 10:34:43 +0200 Subject: [PATCH 078/130] More wait_until --- panel/tests/ui/layout/test_feed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panel/tests/ui/layout/test_feed.py b/panel/tests/ui/layout/test_feed.py index a76e8f1c78..e056dc01a2 100644 --- a/panel/tests/ui/layout/test_feed.py +++ b/panel/tests/ui/layout/test_feed.py @@ -75,5 +75,5 @@ def test_feed_dynamic_objects(page): wait_until(lambda: page.locator('pre') is not None, page) wait_until(lambda: page.locator('pre').first is not None, page) - expect(page.locator('pre').first).to_have_text('0') + wait_until(lambda: expect(page.locator('pre').first).to_have_text('0')) wait_until(lambda: page.locator('pre').count() > 10, page) From 4e104c121d28e3647559378a2cced273428c00a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 10:41:18 +0200 Subject: [PATCH 079/130] Remove empty fixtures file --- panel/_testing/fixtures.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 panel/_testing/fixtures.py diff --git a/panel/_testing/fixtures.py b/panel/_testing/fixtures.py deleted file mode 100644 index e69de29bb2..0000000000 From 93bc5e71115ed7034359af349c77bca474cda7d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 11:40:15 +0200 Subject: [PATCH 080/130] Remove MANIFEST.in --- MANIFEST.in | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index ba99bad0b6..0000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,33 +0,0 @@ -include README.md -include LICENSE.txt -include panel/.version -include panel/py.typed -include panel/*.json -include panel/assets/*.gif -include panel/assets/*.svg -include panel/index.ts -include panel/layout/*.html -include panel/models/*.ts -include panel/models/vtk/*.ts -include panel/_templates/*.css -include panel/_templates/*.js -include panel/_templates/*.html -include panel/_templates/*.webmanifest -include panel/tests/assets/*.css -include panel/tests/assets/*.js -include panel/tests/test_data/*.png -include panel/tests/pane/assets/*.mp3 -include panel/tests/pane/assets/*.mp4 -recursive-include panel/template *.html -recursive-include panel/template *.css -recursive-include panel/template *.js -recursive-include panel/theme *.css -recursive-include panel/theme *.js -global-exclude *.py[co] -global-exclude *~ -global-exclude *.ipynb_checkpoints/* -global-exclude *.whl -graft panel/examples -graft examples -graft doc/ -graft panel/dist From 22aaadbf1abf75b7ac40e2c28f06f1a6111bfe53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 11:47:18 +0200 Subject: [PATCH 081/130] Add nightly lock workflow --- .github/workflows/nightly_lock.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/nightly_lock.yaml diff --git a/.github/workflows/nightly_lock.yaml b/.github/workflows/nightly_lock.yaml new file mode 100644 index 0000000000..9d3379af2b --- /dev/null +++ b/.github/workflows/nightly_lock.yaml @@ -0,0 +1,14 @@ +name: nightly_lock +on: + workflow_dispatch: + schedule: + - cron: "0 0 * * *" + +jobs: + pixi_lock: + name: Pixi lock + runs-on: ubuntu-latest + steps: + - uses: holoviz-dev/holoviz_tasks/pixi_lock@pixi + + # TODO: Upload the lock-file From c1840c7ac179d6acfa565a8bf24e951b1a8583c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 12:16:06 +0200 Subject: [PATCH 082/130] Add wait_untils --- panel/tests/ui/io/test_reload.py | 4 ++-- panel/tests/ui/layout/test_gridstack.py | 3 ++- panel/tests/ui/pane/test_image.py | 6 +++--- panel/tests/ui/widgets/test_button.py | 5 ++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/panel/tests/ui/io/test_reload.py b/panel/tests/ui/io/test_reload.py index ca31fdbddb..4725e05a04 100644 --- a/panel/tests/ui/io/test_reload.py +++ b/panel/tests/ui/io/test_reload.py @@ -12,7 +12,7 @@ pytestmark = pytest.mark.skip("playwright not available") from panel.io.state import state -from panel.tests.util import serve_component +from panel.tests.util import serve_component, wait_until CURPATH = pathlib.Path(__file__).parent @@ -77,4 +77,4 @@ def test_reload_app_on_local_module_change(page, autoreload, py_files): pathlib.Path(module.name).touch() time.sleep(0.1) - expect(page.locator('.markdown')).to_have_text('bar') + wait_until(lambda: expect(page.locator('.markdown')).to_have_text('bar'), page) diff --git a/panel/tests/ui/layout/test_gridstack.py b/panel/tests/ui/layout/test_gridstack.py index 737d572518..05bf92c9ce 100644 --- a/panel/tests/ui/layout/test_gridstack.py +++ b/panel/tests/ui/layout/test_gridstack.py @@ -6,7 +6,7 @@ from panel import Column, Spacer from panel.layout.gridstack import GridStack -from panel.tests.util import serve_component +from panel.tests.util import serve_component, wait_until pytestmark = pytest.mark.ui @@ -26,6 +26,7 @@ def test_gridstack(page): expect(children).to_have_count(5) + wait_until(lambda: page.locator(".grid-stack").bounding_box() is not None, page) bbox = page.locator(".grid-stack").bounding_box() assert bbox['width'] == 800 diff --git a/panel/tests/ui/pane/test_image.py b/panel/tests/ui/pane/test_image.py index 30d0f49cdf..887e11ea22 100644 --- a/panel/tests/ui/pane/test_image.py +++ b/panel/tests/ui/pane/test_image.py @@ -6,7 +6,7 @@ from panel.layout import Row from panel.pane import PDF, PNG, SVG -from panel.tests.util import serve_component, wait_for_server +from panel.tests.util import serve_component, wait_for_server, wait_until PDF_FILE = 'https://assets.holoviz.org/panel/samples/pdf_sample.pdf' PNG_FILE = 'https://assets.holoviz.org/panel/samples/png_sample.png' @@ -21,11 +21,11 @@ def get_bbox(page, obj): if obj.embed: page.goto(f"http://localhost:{port}") - return page.locator("img").bounding_box() else: with page.expect_response(obj.object): page.goto(f"http://localhost:{port}") - return page.locator("img").bounding_box() + wait_until(lambda: page.locator("img") is not None, page) + return page.locator("img").bounding_box() @pytest.mark.parametrize('embed', [False, True]) def test_png_native_size(embed, page): diff --git a/panel/tests/ui/widgets/test_button.py b/panel/tests/ui/widgets/test_button.py index 4af149aac0..7d2c7a2621 100644 --- a/panel/tests/ui/widgets/test_button.py +++ b/panel/tests/ui/widgets/test_button.py @@ -92,13 +92,12 @@ def test_button_tooltip_with_delay(page, button_fn, button_locator): exp(tooltip).to_have_count(0) # After 100 ms the tooltip should be visible - page.wait_for_timeout(200) - exp(tooltip).to_have_count(1) + wait_until(lambda: exp(tooltip).to_have_count(1), page) # Removing hover should hide the tooltip page.hover("body") tooltip = page.locator(".bk-tooltip-content") - exp(tooltip).to_have_count(0) + wait_until(lambda: exp(tooltip).to_have_count(0), page) # Hovering over the button for a short time should not show the tooltip page.hover(button_locator) From 161fbb50e5fd77f658ded9f17f7f16f054840c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 12:20:15 +0200 Subject: [PATCH 083/130] Bump param version --- pixi.toml | 2 +- pyproject.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pixi.toml b/pixi.toml index 8febfb34a8..820ee15d2c 100644 --- a/pixi.toml +++ b/pixi.toml @@ -28,7 +28,7 @@ mdit-py-plugins = "*" nodejs= ">=20" packaging = "*" pandas = ">=1.2" -param = ">=2.0.0,<3.0" +param = ">=2.1.0,<3.0" pip = "*" pyviz_comms = ">=2.0.0" requests = "*" diff --git a/pyproject.toml b/pyproject.toml index 2e7496dae4..b785c47a69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ requires = [ "hatchling", "hatch-vcs", - "param >=2.0.0", + "param >=2.1.0", "bokeh >=3.4.0,<3.5.0", "pyviz_comms >=0.7.4", "requests", @@ -49,7 +49,7 @@ classifiers = [ dependencies = [ 'bokeh >=3.4.0,<3.5.0', - 'param >=2.0.0,<3.0', + 'param >=2.1.0,<3.0', 'pyviz_comms >=2.0.0', 'xyzservices >=2021.09.1', # Bokeh dependency, but pyodide 23.0.0 does not always pick it up 'markdown', From fea464460e0ca8cbdfb7fc4441b36a679ce4a905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 12:42:31 +0200 Subject: [PATCH 084/130] Pin ipyleaflet for now --- pixi.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index 820ee15d2c..af32a778b1 100644 --- a/pixi.toml +++ b/pixi.toml @@ -64,7 +64,7 @@ fastparquet = "*" folium = "*" graphviz = "*" hvplot = "*" -ipyleaflet = "*" +ipyleaflet = "<0.19" # tmp: https://github.com/conda-forge/ipyleaflet-feedstock/issues/116 ipympl = "*" ipyvolume = "*" ipyvuetify = "*" From cca01558ef31ff7231508635667d8c865b89b60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 14:25:35 +0200 Subject: [PATCH 085/130] Remove pin again --- pixi.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index af32a778b1..820ee15d2c 100644 --- a/pixi.toml +++ b/pixi.toml @@ -64,7 +64,7 @@ fastparquet = "*" folium = "*" graphviz = "*" hvplot = "*" -ipyleaflet = "<0.19" # tmp: https://github.com/conda-forge/ipyleaflet-feedstock/issues/116 +ipyleaflet = "*" ipympl = "*" ipyvolume = "*" ipyvuetify = "*" From de3213676f391b31cfa02e76c66a293682a87a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 14:36:49 +0200 Subject: [PATCH 086/130] Fix warning of class_ in param.List --- doc/tutorials/intermediate/build_todo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorials/intermediate/build_todo.md b/doc/tutorials/intermediate/build_todo.md index 20f71cbe1f..47fed2a554 100644 --- a/doc/tutorials/intermediate/build_todo.md +++ b/doc/tutorials/intermediate/build_todo.md @@ -255,7 +255,7 @@ This class defines the model of a task. It has two attributes: `value` (descript class TaskList(param.Parameterized): """Provides methods to add and remove tasks as well as calculate summary statistics""" - value: List[Task] = param.List(class_=Task, doc="A list of Tasks") + value: List[Task] = param.List(item_type=Task, doc="A list of Tasks") total_tasks = param.Integer(doc="The number of Tasks") has_tasks = param.Boolean(doc="Whether or not the TaskList contains Tasks") From 596d4e071f4ed40e4fad2b5fe75c8bb18ca447c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 24 Apr 2024 16:14:58 +0200 Subject: [PATCH 087/130] Try to reduce the number of items in dynamic_objects --- panel/tests/ui/layout/test_feed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panel/tests/ui/layout/test_feed.py b/panel/tests/ui/layout/test_feed.py index e056dc01a2..9b43594db4 100644 --- a/panel/tests/ui/layout/test_feed.py +++ b/panel/tests/ui/layout/test_feed.py @@ -71,7 +71,7 @@ def test_feed_dynamic_objects(page): feed = Feed(height=250, load_buffer=10) serve_component(page, feed) - feed.objects = list(range(1000)) + feed.objects = list(range(100)) wait_until(lambda: page.locator('pre') is not None, page) wait_until(lambda: page.locator('pre').first is not None, page) From 7b919e480c9efdde7d37b394bf5c369edbf6cc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 25 Apr 2024 09:30:16 +0200 Subject: [PATCH 088/130] Reduce number of items --- panel/tests/ui/layout/test_feed.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/panel/tests/ui/layout/test_feed.py b/panel/tests/ui/layout/test_feed.py index 9b43594db4..39c7829d76 100644 --- a/panel/tests/ui/layout/test_feed.py +++ b/panel/tests/ui/layout/test_feed.py @@ -9,9 +9,10 @@ pytestmark = pytest.mark.ui +ITEMS = 100 # 1000 items make the CI flaky def test_feed_load_entries(page): - feed = Feed(*list(range(1000)), height=250) + feed = Feed(*list(range(ITEMS)), height=250) serve_component(page, feed) feed_el = page.locator(".bk-panel-models-feed-Feed") @@ -34,7 +35,7 @@ def test_feed_load_entries(page): wait_until(lambda: feed_el.locator('.bk-panel-models-markup-HTML').count() >= 50, page) def test_feed_view_latest(page): - feed = Feed(*list(range(1000)), height=250, view_latest=True) + feed = Feed(*list(range(ITEMS)), height=250, view_latest=True) serve_component(page, feed) feed_el = page.locator(".bk-panel-models-feed-Feed") @@ -50,7 +51,7 @@ def test_feed_view_latest(page): wait_until(lambda: int(page.locator('pre').last.inner_text()) > 950, page) def test_feed_view_scroll_button(page): - feed = Feed(*list(range(1000)), height=250, scroll_button_threshold=50) + feed = Feed(*list(range(ITEMS)), height=250, scroll_button_threshold=50) serve_component(page, feed) feed_el = page.locator(".bk-panel-models-feed-Feed") @@ -71,9 +72,7 @@ def test_feed_dynamic_objects(page): feed = Feed(height=250, load_buffer=10) serve_component(page, feed) - feed.objects = list(range(100)) - wait_until(lambda: page.locator('pre') is not None, page) - wait_until(lambda: page.locator('pre').first is not None, page) + feed.objects = list(range(ITEMS)) wait_until(lambda: expect(page.locator('pre').first).to_have_text('0')) wait_until(lambda: page.locator('pre').count() > 10, page) From c3e21d41dafceab21be88447a936f91c6dc97aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 25 Apr 2024 09:41:43 +0200 Subject: [PATCH 089/130] Wait for flaky tests --- panel/tests/ui/chat/test_chat_interface_ui.py | 8 ++++---- panel/tests/ui/widgets/test_icon.py | 2 +- panel/tests/ui/widgets/test_tabulator.py | 1 + pyproject.toml | 2 ++ 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/panel/tests/ui/chat/test_chat_interface_ui.py b/panel/tests/ui/chat/test_chat_interface_ui.py index b156f5d9af..6f26698c97 100644 --- a/panel/tests/ui/chat/test_chat_interface_ui.py +++ b/panel/tests/ui/chat/test_chat_interface_ui.py @@ -3,7 +3,7 @@ pytest.importorskip("playwright") from panel.chat import ChatInterface -from panel.tests.util import serve_component +from panel.tests.util import serve_component, wait_until pytestmark = pytest.mark.ui @@ -15,7 +15,7 @@ def test_chat_interface_help(page): serve_component(page, chat_interface) message = page.locator("p") message_text = message.inner_text() - assert message_text == "This is a test help text" + wait_until(lambda: message_text == "This is a test help text", page) def test_chat_interface_custom_js(page): @@ -38,7 +38,7 @@ def test_chat_interface_custom_js(page): page.locator("button", has_text="help").click() msg = msg_info.value - assert msg.args[0].json_value() == "Typed: 'Hello'" + wait_until(lambda: msg.args[0].json_value() == "Typed: 'Hello'", page) def test_chat_interface_custom_js_string(page): @@ -58,4 +58,4 @@ def test_chat_interface_custom_js_string(page): page.locator("button", has_text="help").click() msg = msg_info.value - assert msg.args[0].json_value() == "Clicked" + wait_until(lambda: msg.args[0].json_value() == "Clicked", page) diff --git a/panel/tests/ui/widgets/test_icon.py b/panel/tests/ui/widgets/test_icon.py index e284f839ab..8ef0bfe8a1 100644 --- a/panel/tests/ui/widgets/test_icon.py +++ b/panel/tests/ui/widgets/test_icon.py @@ -128,7 +128,7 @@ def cb(event): icon.size = "8em" assert page.locator(".icon-tabler-ad-filled").bounding_box()["width"] >= 96 icon.size = "1em" - assert page.locator(".icon-tabler-ad-filled").bounding_box()["width"] <= 24 + wait_until(lambda: page.locator(".icon-tabler-ad-filled").bounding_box()["width"] <= 24, page) def test_toggle_icon_svg(page): diff --git a/panel/tests/ui/widgets/test_tabulator.py b/panel/tests/ui/widgets/test_tabulator.py index ea6ff15be2..823595e146 100644 --- a/panel/tests/ui/widgets/test_tabulator.py +++ b/panel/tests/ui/widgets/test_tabulator.py @@ -181,6 +181,7 @@ def test_tabulator_value_changed(page, df_mixed): # Need to trigger the value as the dataframe was modified # in place which is not detected. widget.param.trigger('value') + wait_until(lambda: page.locator('text="AA"') is not None, page) changed_cell = page.locator('text="AA"') expect(changed_cell).to_have_count(1) diff --git a/pyproject.toml b/pyproject.toml index b785c47a69..46eff2aec7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -176,6 +176,8 @@ addopts = "--pyargs --doctest-ignore-import-errors --color=yes" norecursedirs = "doc .git dist build _build .ipynb_checkpoints panel/examples" asyncio_mode = "auto" xfail_strict = true +minversion = "7" +log_cli_level = "INFO" filterwarnings = [ # 2023-11: `pkg_resources` is deprecated "ignore:Deprecated call to `pkg_resources.+?'zope:DeprecationWarning", # https://github.com/zopefoundation/meta/issues/194 From f2cc4ed8d559d26cdb553ec2b19a275266d9a621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 25 Apr 2024 09:47:01 +0200 Subject: [PATCH 090/130] Remove doc pins (to test out) --- pixi.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pixi.toml b/pixi.toml index 820ee15d2c..76ee3e10e7 100644 --- a/pixi.toml +++ b/pixi.toml @@ -145,9 +145,7 @@ depends_on = ["x-install-ui"] # =================== DOCS ==================== # ============================================= [feature.doc.dependencies] -lxml = "*" nbsite = ">=0.8.4" -pandas = "<2.1.0" # Avoid deprecation warnings [feature.doc.tasks] x-docs-refmanual = 'python ./doc/generate_modules.py panel -d ./doc/api -n panel -e tests' From d8c888d4161e98068c2ed748e7619f7e64a35b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 25 Apr 2024 10:31:12 +0200 Subject: [PATCH 091/130] Fix test and add wait_locator --- panel/tests/ui/layout/test_feed.py | 2 +- panel/tests/ui/widgets/test_tabulator.py | 6 ++++-- panel/tests/util.py | 5 +++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/panel/tests/ui/layout/test_feed.py b/panel/tests/ui/layout/test_feed.py index 39c7829d76..dcc0dae444 100644 --- a/panel/tests/ui/layout/test_feed.py +++ b/panel/tests/ui/layout/test_feed.py @@ -48,7 +48,7 @@ def test_feed_view_latest(page): # Assert scroll is not at 0 (view_latest) assert feed_el.evaluate('(el) => el.scrollTop') > 0 - wait_until(lambda: int(page.locator('pre').last.inner_text()) > 950, page) + wait_until(lambda: int(page.locator('pre').last.inner_text()) > ITEMS * 0.95, page) def test_feed_view_scroll_button(page): feed = Feed(*list(range(ITEMS)), height=250, scroll_button_threshold=50) diff --git a/panel/tests/ui/widgets/test_tabulator.py b/panel/tests/ui/widgets/test_tabulator.py index 823595e146..3c9915a7fc 100644 --- a/panel/tests/ui/widgets/test_tabulator.py +++ b/panel/tests/ui/widgets/test_tabulator.py @@ -23,7 +23,9 @@ from panel.io.state import state from panel.layout.base import Column from panel.models.tabulator import _TABULATOR_THEMES_MAPPING -from panel.tests.util import get_ctrl_modifier, serve_component, wait_until +from panel.tests.util import ( + get_ctrl_modifier, serve_component, wait_locator, wait_until, +) from panel.widgets import Select, Tabulator pytestmark = pytest.mark.ui @@ -2401,7 +2403,7 @@ def test_tabulator_sorters_set_after_init(page, df_mixed): widget.sorters = [{'field': 'int', 'dir': 'desc'}] - sheader = page.locator('[aria-sort="descending"]:visible') + sheader = wait_locator('[aria-sort="descending"]:visible', page) expect(sheader).to_have_count(1) assert sheader.get_attribute('tabulator-field') == 'int' diff --git a/panel/tests/util.py b/panel/tests/util.py index 9503d0988d..0b7ffc4770 100644 --- a/panel/tests/util.py +++ b/panel/tests/util.py @@ -257,6 +257,11 @@ def timed_out(): await asyncio.sleep(interval / 1000) +def wait_locator(selector, page, timeout=None, interval=None): + wait_until(lambda: page.locator(selector) is not None, page, timeout, interval) + return page.locator(selector) + + def get_ctrl_modifier(): """ Get the CTRL modifier on the current platform. From ae8ec001d9a10d83a1fe4f3ee69ce6432e0a2b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 25 Apr 2024 10:42:16 +0200 Subject: [PATCH 092/130] Revert changes in this PR --- panel/tests/util.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/panel/tests/util.py b/panel/tests/util.py index 0b7ffc4770..dcfe6e7b3b 100644 --- a/panel/tests/util.py +++ b/panel/tests/util.py @@ -280,7 +280,7 @@ def serve_and_wait(app, page=None, prefix=None, port=None, **kwargs): wait_until(lambda: server_id in state._servers, page) server = state._servers[server_id][0] port = server.port - wait_for_server(port, prefix=prefix, page=page) + wait_for_server(port, prefix=prefix) return port @@ -302,7 +302,7 @@ def serve_and_request(app, suffix="", n=1, port=None, **kwargs): return reqs[0] if len(reqs) == 1 else reqs -def wait_for_server(port, prefix=None, timeout=3, page=None): +def wait_for_server(port, prefix=None, timeout=3): start = time.time() prefix = prefix or "" url = f"http://localhost:{port}{prefix}/liveness" @@ -312,10 +312,7 @@ def wait_for_server(port, prefix=None, timeout=3, page=None): return except Exception: pass - if page: - page.wait_for_timeout(50) - else: - time.sleep(0.05) + time.sleep(0.05) if (time.time()-start) > timeout: raise RuntimeError(f'{url} did not respond before timeout.') From 03420f747132800c1da9e8bcb0f1a6bf463070ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 25 Apr 2024 10:45:47 +0200 Subject: [PATCH 093/130] add kwargs --- panel/tests/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panel/tests/util.py b/panel/tests/util.py index dcfe6e7b3b..f9009435b0 100644 --- a/panel/tests/util.py +++ b/panel/tests/util.py @@ -257,8 +257,8 @@ def timed_out(): await asyncio.sleep(interval / 1000) -def wait_locator(selector, page, timeout=None, interval=None): - wait_until(lambda: page.locator(selector) is not None, page, timeout, interval) +def wait_locator(selector, page, *, timeout=None, interval=None, **kwargs): + wait_until(lambda: page.locator(selector, **kwargs) is not None, page, timeout, interval) return page.locator(selector) From b162f046edc3124da11bd5686508218ab3d45b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 25 Apr 2024 10:48:44 +0200 Subject: [PATCH 094/130] Add some atol to test_gridstack --- panel/tests/ui/layout/test_gridstack.py | 51 +++++++++++++------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/panel/tests/ui/layout/test_gridstack.py b/panel/tests/ui/layout/test_gridstack.py index 05bf92c9ce..d20bd5f04f 100644 --- a/panel/tests/ui/layout/test_gridstack.py +++ b/panel/tests/ui/layout/test_gridstack.py @@ -1,3 +1,4 @@ +import numpy as np import pytest pytest.importorskip("playwright") @@ -29,40 +30,40 @@ def test_gridstack(page): wait_until(lambda: page.locator(".grid-stack").bounding_box() is not None, page) bbox = page.locator(".grid-stack").bounding_box() - assert bbox['width'] == 800 - assert bbox['height'] == 600 + assert np.isclose(bbox['width'], 800, atol=0.3) + assert np.isclose(bbox['height'], 600, atol=0.3) bbox1 = children.nth(0).bounding_box() - assert bbox1['x'] == 0 - assert bbox1['width'] == 200 - assert bbox1['height'] == 600 + assert np.isclose(bbox1['x'], 0, atol=0.3) + assert np.isclose(bbox1['width'], 200, atol=0.3) + assert np.isclose(bbox1['height'], 600, atol=0.3) assert children.nth(0).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(255, 0, 0)' bbox2 = children.nth(1).bounding_box() - assert bbox2['x'] == 200 - assert bbox2['y'] == 0 - assert bbox2['width'] == 400 - assert bbox2['height'] == 200 + assert np.isclose(bbox2['x'], 200, atol=0.3) + assert np.isclose(bbox2['y'], 0, atol=0.3) + assert np.isclose(bbox2['width'], 400, atol=0.3) + assert np.isclose(bbox2['height'], 200, atol=0.3) assert children.nth(1).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(0, 128, 0)' bbox3 = children.nth(2).bounding_box() - assert bbox3['x'] == 400 - assert bbox3['y'] == 200 - assert bbox3['width'] == 400 - assert bbox3['height'] == 200 + assert np.isclose(bbox3['x'], 400, atol=0.3) + assert np.isclose(bbox3['y'], 200, atol=0.3) + assert np.isclose(bbox3['width'], 400, atol=0.3) + assert np.isclose(bbox3['height'], 200, atol=0.3) assert children.nth(2).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(255, 165, 0)' bbox4 = children.nth(3).bounding_box() - assert bbox4['x'] == 200 - assert bbox4['y'] == 400 - assert bbox4['width'] == 600 - assert bbox4['height'] == 200 + assert np.isclose(bbox4['x'], 200, atol=0.3) + assert np.isclose(bbox4['y'], 400, atol=0.3) + assert np.isclose(bbox4['width'], 600, atol=0.3) + assert np.isclose(bbox4['height'], 200, atol=0.3) assert children.nth(3).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(0, 0, 255)' bbox5 = children.nth(4).bounding_box() - assert bbox5['x'] == 600 - assert bbox5['y'] == 0 - assert bbox5['width'] == 200 - assert bbox5['height'] == 200 + assert np.isclose(bbox5['x'], 600, atol=0.3) + assert np.isclose(bbox5['y'], 0, atol=0.3) + assert np.isclose(bbox5['width'], 200, atol=0.3) + assert np.isclose(bbox5['height'], 200, atol=0.3) assert children.nth(4).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(128, 0, 128)' @@ -76,10 +77,10 @@ def test_gridstack(page): assert children.nth(5).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(0, 0, 0)' bbox6 = children.nth(5).bounding_box() - assert bbox6['x'] == 200 - assert bbox6['y'] == 200 - assert bbox6['width'] == 200 - assert bbox6['height'] == 200 + assert np.isclose(bbox6['x'], 200, atol=0.3) + assert np.isclose(bbox6['y'], 200, atol=0.3) + assert np.isclose(bbox6['width'], 200, atol=0.3) + assert np.isclose(bbox6['height'], 200, atol=0.3) def test_gridstack_stretch(page): From 7976bc45083e0c0a3d426e2cb44aede320e46ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 25 Apr 2024 10:58:17 +0200 Subject: [PATCH 095/130] Add atol to other gridstack function --- panel/tests/ui/layout/test_gridstack.py | 50 ++++++++++++------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/panel/tests/ui/layout/test_gridstack.py b/panel/tests/ui/layout/test_gridstack.py index d20bd5f04f..3e8b62bc11 100644 --- a/panel/tests/ui/layout/test_gridstack.py +++ b/panel/tests/ui/layout/test_gridstack.py @@ -101,40 +101,40 @@ def test_gridstack_stretch(page): bbox = page.locator(".grid-stack").bounding_box() - assert bbox['width'] == 800 - assert bbox['height'] == 600 + assert np.isclose(bbox['width'], 800, atol=0.3) + assert np.isclose(bbox['height'], 600, atol=0.3) bbox1 = children.nth(0).bounding_box() - assert bbox1['x'] == 0 - assert bbox1['width'] == 200 - assert bbox1['height'] == 600 + assert np.isclose(bbox1['x'], 0, atol=0.3) + assert np.isclose(bbox1['width'], 200, atol=0.3) + assert np.isclose(bbox1['height'], 600, atol=0.3) assert children.nth(0).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(255, 0, 0)' bbox2 = children.nth(1).bounding_box() - assert bbox2['x'] == 200 - assert bbox2['y'] == 0 - assert bbox2['width'] == 400 - assert bbox2['height'] == 200 + assert np.isclose(bbox2['x'], 200, atol=0.3) + assert np.isclose(bbox2['y'], 0, atol=0.3) + assert np.isclose(bbox2['width'], 400, atol=0.3) + assert np.isclose(bbox2['height'], 200, atol=0.3) assert children.nth(1).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(0, 128, 0)' bbox3 = children.nth(2).bounding_box() - assert bbox3['x'] == 400 - assert bbox3['y'] == 200 - assert bbox3['width'] == 400 - assert bbox3['height'] == 200 + assert np.isclose(bbox3['x'], 400, atol=0.3) + assert np.isclose(bbox3['y'], 200, atol=0.3) + assert np.isclose(bbox3['width'], 400, atol=0.3) + assert np.isclose(bbox3['height'], 200, atol=0.3) assert children.nth(2).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(255, 165, 0)' bbox4 = children.nth(3).bounding_box() - assert bbox4['x'] == 200 - assert bbox4['y'] == 400 - assert bbox4['width'] == 600 - assert bbox4['height'] == 200 + assert np.isclose(bbox4['x'], 200, atol=0.3) + assert np.isclose(bbox4['y'], 400, atol=0.3) + assert np.isclose(bbox4['width'], 600, atol=0.3) + assert np.isclose(bbox4['height'], 200, atol=0.3) assert children.nth(3).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(0, 0, 255)' bbox5 = children.nth(4).bounding_box() - assert bbox5['x'] == 600 - assert bbox5['y'] == 0 - assert bbox5['width'] == 200 - assert bbox5['height'] == 200 + assert np.isclose(bbox5['x'], 600, atol=0.3) + assert np.isclose(bbox5['y'], 0, atol=0.3) + assert np.isclose(bbox5['width'], 200, atol=0.3) + assert np.isclose(bbox5['height'], 200, atol=0.3) assert children.nth(4).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(128, 0, 128)' @@ -149,7 +149,7 @@ def test_gridstack_stretch(page): assert children.nth(5).evaluate("""(element) => window.getComputedStyle(element).getPropertyValue('background-color')""") == 'rgb(0, 0, 0)' bbox6 = children.nth(5).bounding_box() - assert bbox6['x'] == 200 - assert bbox6['y'] == 200 - assert bbox6['width'] == 200 - assert bbox6['height'] == 200 + assert np.isclose(bbox6['x'], 200, atol=0.3) + assert np.isclose(bbox6['y'], 200, atol=0.3) + assert np.isclose(bbox6['width'], 200, atol=0.3) + assert np.isclose(bbox6['height'], 200, atol=0.3) From 01affe70a292f1a8362d5850e658cc8df79335ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 25 Apr 2024 14:18:32 +0200 Subject: [PATCH 096/130] Use macos-latest as they use mac-14 for it --- .github/workflows/docs.yaml | 2 +- .github/workflows/test.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 0977be98b7..9b5b793ed7 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -41,7 +41,7 @@ jobs: docs_build: name: Build Documentation needs: [pixi_lock] - runs-on: "macos-14" + runs-on: "macos-latest" timeout-minutes: 180 outputs: tag: ${{ steps.vars.outputs.tag }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 82e62459b7..975055dc06 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -101,7 +101,7 @@ jobs: if: env.MATRIX_OPTION == 'default' run: | MATRIX=$(jq -nsc '{ - "os": ["ubuntu-latest", "macos-14", "windows-latest"], + "os": ["ubuntu-latest", "macos-latest", "windows-latest"], "environment": ["test-39", "test-312"] }') echo "MATRIX=$MATRIX" >> $GITHUB_ENV @@ -109,7 +109,7 @@ jobs: if: env.MATRIX_OPTION == 'full' run: | MATRIX=$(jq -nsc '{ - "os": ["ubuntu-latest", "macos-14", "windows-latest"], + "os": ["ubuntu-latest", "macos-latest", "windows-latest"], "environment": ["test-39", "test-310", "test-311", "test-312"] }') echo "MATRIX=$MATRIX" >> $GITHUB_ENV @@ -169,7 +169,7 @@ jobs: strategy: fail-fast: false matrix: - os: ["ubuntu-latest", "macos-14", "windows-latest"] + os: ["ubuntu-latest", "macos-latest", "windows-latest"] environment: ["test-ui"] timeout-minutes: 120 env: From c3aa91f25f749377446e6aac250e7c071c228722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 25 Apr 2024 14:26:14 +0200 Subject: [PATCH 097/130] Use runner.os for ui upload --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 975055dc06..ec023c8524 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -226,7 +226,7 @@ jobs: - uses: actions/upload-artifact@v4 if: always() with: - name: ui_screenshots_${{ matrix.os }} + name: ui_screenshots_${{ runner.os }} path: ./ui_screenshots if-no-files-found: ignore - name: Stop JupyterLab From efbae0b9fdb71ec8969f36072aaf304c0dce21dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 29 Apr 2024 12:01:28 +0200 Subject: [PATCH 098/130] Pin nodejs --- pixi.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index 76ee3e10e7..c91312a71d 100644 --- a/pixi.toml +++ b/pixi.toml @@ -25,7 +25,7 @@ linkify-it-py = "*" markdown = "*" markdown-it-py = "*" mdit-py-plugins = "*" -nodejs= ">=20" +nodejs= "20.9.*" # 20.12.2, seems to break on Windows packaging = "*" pandas = ">=1.2" param = ">=2.1.0,<3.0" From 5efa1cd21d403c47ecd205f0a339d6d77aa626bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 29 Apr 2024 12:20:19 +0200 Subject: [PATCH 099/130] Update message with Bokeh PR --- pixi.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index c91312a71d..4ddac5e78c 100644 --- a/pixi.toml +++ b/pixi.toml @@ -25,7 +25,7 @@ linkify-it-py = "*" markdown = "*" markdown-it-py = "*" mdit-py-plugins = "*" -nodejs= "20.9.*" # 20.12.2, seems to break on Windows +nodejs= "20.9.*" # 20.12.2 breaks bokeh build on Windows: https://github.com/bokeh/bokeh/pull/13851 packaging = "*" pandas = ">=1.2" param = ">=2.1.0,<3.0" From baf792111bd39005f4d61e9afea17dc187979e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 30 Apr 2024 13:34:32 +0200 Subject: [PATCH 100/130] Remove wait_locator as test would still fail --- panel/tests/ui/widgets/test_tabulator.py | 6 ++---- panel/tests/util.py | 5 ----- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/panel/tests/ui/widgets/test_tabulator.py b/panel/tests/ui/widgets/test_tabulator.py index 3c9915a7fc..823595e146 100644 --- a/panel/tests/ui/widgets/test_tabulator.py +++ b/panel/tests/ui/widgets/test_tabulator.py @@ -23,9 +23,7 @@ from panel.io.state import state from panel.layout.base import Column from panel.models.tabulator import _TABULATOR_THEMES_MAPPING -from panel.tests.util import ( - get_ctrl_modifier, serve_component, wait_locator, wait_until, -) +from panel.tests.util import get_ctrl_modifier, serve_component, wait_until from panel.widgets import Select, Tabulator pytestmark = pytest.mark.ui @@ -2403,7 +2401,7 @@ def test_tabulator_sorters_set_after_init(page, df_mixed): widget.sorters = [{'field': 'int', 'dir': 'desc'}] - sheader = wait_locator('[aria-sort="descending"]:visible', page) + sheader = page.locator('[aria-sort="descending"]:visible') expect(sheader).to_have_count(1) assert sheader.get_attribute('tabulator-field') == 'int' diff --git a/panel/tests/util.py b/panel/tests/util.py index f9009435b0..eeaefae783 100644 --- a/panel/tests/util.py +++ b/panel/tests/util.py @@ -257,11 +257,6 @@ def timed_out(): await asyncio.sleep(interval / 1000) -def wait_locator(selector, page, *, timeout=None, interval=None, **kwargs): - wait_until(lambda: page.locator(selector, **kwargs) is not None, page, timeout, interval) - return page.locator(selector) - - def get_ctrl_modifier(): """ Get the CTRL modifier on the current platform. From fcd4600f5c850b6373755ec715d76c400bd21433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 1 May 2024 09:44:23 +0200 Subject: [PATCH 101/130] Make private tasks --- pixi.toml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pixi.toml b/pixi.toml index 4ddac5e78c..bbfcc3bea5 100644 --- a/pixi.toml +++ b/pixi.toml @@ -135,11 +135,11 @@ pytest-playwright = "*" jupyter_server = "*" [feature.test-ui.tasks] -x-install-ui = 'playwright install chromium' +_install-ui = 'playwright install chromium' [feature.test-ui.tasks.test-ui] cmd = 'pytest panel/tests/ui --ui --browser chromium -n logical --dist loadgroup --reruns 3 --reruns-delay 10' -depends_on = ["x-install-ui"] +depends_on = ["_install-ui"] # ============================================= # =================== DOCS ==================== @@ -148,15 +148,15 @@ depends_on = ["x-install-ui"] nbsite = ">=0.8.4" [feature.doc.tasks] -x-docs-refmanual = 'python ./doc/generate_modules.py panel -d ./doc/api -n panel -e tests' -x-docs-convert-gallery = 'python scripts/gallery/convert_gallery.py' -x-docs-generate = 'nbsite build --what=html --output=builtdocs --org holoviz --project-name panel' -x-docs-copy-panel-dist = 'cp -r ./panel/dist ./builtdocs/panel_dist' -x-docs-pyodide = 'panel convert examples/gallery/*.ipynb doc/how_to/*/examples/*.md --to pyodide-worker --out ./builtdocs/pyodide/ --pwa --index --requirements doc/pyodide_dependencies.json' +_docs-refmanual = 'python ./doc/generate_modules.py panel -d ./doc/api -n panel -e tests' +_docs-convert-gallery = 'python scripts/gallery/convert_gallery.py' +_docs-generate = 'nbsite build --what=html --output=builtdocs --org holoviz --project-name panel' +_docs-copy-panel-dist = 'cp -r ./panel/dist ./builtdocs/panel_dist' +_docs-pyodide = 'panel convert examples/gallery/*.ipynb doc/how_to/*/examples/*.md --to pyodide-worker --out ./builtdocs/pyodide/ --pwa --index --requirements doc/pyodide_dependencies.json' docs-server = 'python -m http.server 5500 --directory ./builtdocs' [feature.doc.tasks.docs-build] -depends_on = ['x-docs-refmanual', 'x-docs-convert-gallery', 'x-docs-generate', 'x-docs-copy-panel-dist', 'x-docs-pyodide'] +depends_on = ['_docs-refmanual', '_docs-convert-gallery', '_docs-generate', '_docs-copy-panel-dist', '_docs-pyodide'] # ============================================= # ================== BUILD ==================== From 7a26528ff84a56cc11ed22df6578497018a38c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 1 May 2024 15:38:14 +0200 Subject: [PATCH 102/130] Add build-npm --- .github/workflows/build.yaml | 6 ++---- pixi.toml | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 257b3e7a99..8c4cd3abdd 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -151,11 +151,9 @@ jobs: - name: npm build shell: pixi run -e build bash -el {0} run: | - cd ${{ env.PACKAGE }} - TARBALL=$(npm pack .) + TARBALL=$(pixi run build-npm) echo "TARBALL=$TARBALL" >> $GITHUB_ENV - npm publish --dry-run $TARBALL - cd .. + npm publish --dry-run $PACKAGE/$TARBALL - uses: actions/upload-artifact@v4 if: always() with: diff --git a/pixi.toml b/pixi.toml index bbfcc3bea5..76fb3fe339 100644 --- a/pixi.toml +++ b/pixi.toml @@ -169,6 +169,7 @@ conda-build = "*" build-conda = 'bash scripts/conda/build.sh' build-pip = 'python -m build .' build-pyodide = 'python scripts/build_pyodide_wheels.py' +build-npm = { cmd = "npm pack .", cwd = "panel" } # ============================================= # =================== LINT ==================== From f684c06a78f44d98e7739de8b4a422f0ff0360ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 1 May 2024 15:38:34 +0200 Subject: [PATCH 103/130] Lint toml --- pixi.toml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pixi.toml b/pixi.toml index 76fb3fe339..bc7562f9aa 100644 --- a/pixi.toml +++ b/pixi.toml @@ -25,7 +25,7 @@ linkify-it-py = "*" markdown = "*" markdown-it-py = "*" mdit-py-plugins = "*" -nodejs= "20.9.*" # 20.12.2 breaks bokeh build on Windows: https://github.com/bokeh/bokeh/pull/13851 +nodejs = "20.9.*" # 20.12.2 breaks bokeh build on Windows: https://github.com/bokeh/bokeh/pull/13851 packaging = "*" pandas = ">=1.2" param = ">=2.1.0,<3.0" @@ -156,7 +156,13 @@ _docs-pyodide = 'panel convert examples/gallery/*.ipynb doc/how_to/*/examples/*. docs-server = 'python -m http.server 5500 --directory ./builtdocs' [feature.doc.tasks.docs-build] -depends_on = ['_docs-refmanual', '_docs-convert-gallery', '_docs-generate', '_docs-copy-panel-dist', '_docs-pyodide'] +depends_on = [ + '_docs-refmanual', + '_docs-convert-gallery', + '_docs-generate', + '_docs-copy-panel-dist', + '_docs-pyodide', +] # ============================================= # ================== BUILD ==================== From 9dd30b81c5a029202f0c0849066edc3256f1b056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 1 May 2024 15:53:29 +0200 Subject: [PATCH 104/130] Split dry-run to another step --- .github/workflows/build.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8c4cd3abdd..4780054e6d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -153,7 +153,11 @@ jobs: run: | TARBALL=$(pixi run build-npm) echo "TARBALL=$TARBALL" >> $GITHUB_ENV - npm publish --dry-run $PACKAGE/$TARBALL + - name: npm publish dry-run + run: | + cd $PACKAGE + npm publish --dry-run $TARBALL + cd .. - uses: actions/upload-artifact@v4 if: always() with: From c7024cd5dae9c14934207adefbe9bd327553b7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 2 May 2024 08:39:31 +0200 Subject: [PATCH 105/130] Update channel ordering --- pixi.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pixi.toml b/pixi.toml index bc7562f9aa..1bad7e8c98 100644 --- a/pixi.toml +++ b/pixi.toml @@ -1,6 +1,6 @@ [project] name = "panel" -channels = ["conda-forge", "pyviz/label/dev", "bokeh"] +channels = ["pyviz/label/dev", "bokeh", "conda-forge"] platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"] [tasks] @@ -127,7 +127,7 @@ test-example = 'pytest -n logical --dist loadscope --nbval-lax examples' nbval = "*" [feature.test-ui] -channels = ["conda-forge", "pyviz/label/dev", "microsoft"] +channels = ["pyviz/label/dev", "bokeh", "microsoft", "conda-forge"] [feature.test-ui.dependencies] playwright = "*" From f279f3edeb0e761855c3bc7ce7b3d6400d2240d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Thu, 2 May 2024 08:47:07 +0200 Subject: [PATCH 106/130] Add timeout to nightly_lock workflow --- .github/workflows/nightly_lock.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/nightly_lock.yaml b/.github/workflows/nightly_lock.yaml index 9d3379af2b..51eac61bef 100644 --- a/.github/workflows/nightly_lock.yaml +++ b/.github/workflows/nightly_lock.yaml @@ -8,6 +8,7 @@ jobs: pixi_lock: name: Pixi lock runs-on: ubuntu-latest + timeout-minutes: 5 steps: - uses: holoviz-dev/holoviz_tasks/pixi_lock@pixi From 97383d69b0e16c954a2a4d64678dcf26bd3ada62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Fri, 3 May 2024 15:10:21 +0200 Subject: [PATCH 107/130] Update optional dependencies --- pixi.toml | 1 + pyproject.toml | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index 1bad7e8c98..5b4ec965ec 100644 --- a/pixi.toml +++ b/pixi.toml @@ -40,6 +40,7 @@ jupyterlab = "*" matplotlib = "*" pillow = "*" plotly = ">=4.0" +# Standard watchfiles = "*" [feature.py39.dependencies] diff --git a/pyproject.toml b/pyproject.toml index 46eff2aec7..085880bdee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,7 +61,7 @@ dependencies = [ 'typing_extensions', 'pandas >=1.2', 'packaging', - 'tqdm', # TODO: Make this optional + 'tqdm', # TODO: Should this be optional? ] [project.urls] @@ -76,8 +76,17 @@ recommended = [ 'matplotlib', 'pillow', 'plotly', +] +standard = [ 'watchfiles', ] +tests = [ + 'psutil' , + 'pytest', + 'pytest-asyncio', + 'pytest-rerunfailures', + 'pytest-xdist', +] [project.scripts] panel = "panel.command:main" From d01892896f93ed2fd1f98019f05f6301872c3c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Fri, 3 May 2024 15:11:07 +0200 Subject: [PATCH 108/130] Add examples to sdist --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 085880bdee..a608a06811 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -106,7 +106,7 @@ include = ["panel"] "scripts/jupyter-config/server.json" = "etc/jupyter/jupyter_server_config.d/panel-client-jupyter.json" [tool.hatch.build.targets.sdist] -include = ["panel", "scripts"] +include = ["panel", "scripts", "examples"] [tool.hatch.build.targets.sdist.force-include] "panel/dist" = "panel/dist" From 59eb527aadbfa2032b9e75a9f4b7a7fd683e15db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Fri, 3 May 2024 15:37:36 +0200 Subject: [PATCH 109/130] Add S3 upload to pixi nightly lock --- .github/workflows/nightly_lock.yaml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly_lock.yaml b/.github/workflows/nightly_lock.yaml index 51eac61bef..c9f78ea3af 100644 --- a/.github/workflows/nightly_lock.yaml +++ b/.github/workflows/nightly_lock.yaml @@ -11,5 +11,12 @@ jobs: timeout-minutes: 5 steps: - uses: holoviz-dev/holoviz_tasks/pixi_lock@pixi - - # TODO: Upload the lock-file + - name: Upload lock-file to S3 + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: "eu-west-1" + PACKAGE: "panel" + run: | + cp pixi.lock $(date +%Y-%m-%d)-pixi.lock + aws s3 cp ./$(date +%Y-%m-%d)-pixi.lock s3://assets.holoviz.org/lock/$PACKAGE/ From 024612ca87f2630df7d0ef57e3e1caa41adc9bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 4 May 2024 10:12:01 +0200 Subject: [PATCH 110/130] Make nighly lock upload a zip [skip ci] --- .github/workflows/nightly_lock.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly_lock.yaml b/.github/workflows/nightly_lock.yaml index c9f78ea3af..67517b9220 100644 --- a/.github/workflows/nightly_lock.yaml +++ b/.github/workflows/nightly_lock.yaml @@ -18,5 +18,5 @@ jobs: AWS_DEFAULT_REGION: "eu-west-1" PACKAGE: "panel" run: | - cp pixi.lock $(date +%Y-%m-%d)-pixi.lock - aws s3 cp ./$(date +%Y-%m-%d)-pixi.lock s3://assets.holoviz.org/lock/$PACKAGE/ + zip $(date +%Y-%m-%d).zip pixi.lock + aws s3 cp ./$(date +%Y-%m-%d).zip s3://assets.holoviz.org/lock/$PACKAGE/ From 873e1f0b0a7139a6068264c03212f03e9308afab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 5 May 2024 18:58:51 +0200 Subject: [PATCH 111/130] conftest update --- panel/tests/conftest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panel/tests/conftest.py b/panel/tests/conftest.py index 41b33acb77..d4243fc031 100644 --- a/panel/tests/conftest.py +++ b/panel/tests/conftest.py @@ -32,7 +32,7 @@ from panel.io.state import set_curdoc, state from panel.pane import HTML, Markdown -CUSTOM_MARKS = ('ui', 'jupyter', 'subprocess') +CUSTOM_MARKS = ('ui', 'jupyter', 'subprocess', 'docs') config.apply_signatures = False @@ -87,7 +87,7 @@ def jupyter_preview(request): atexit.register(cleanup_jupyter) optional_markers = { "ui": { - "help": "", + "help": "Runs UI related tests", "marker-descr": "UI test marker", "skip-reason": "Test only runs with the --ui option." }, From a37358d29290f4cbfdba34b9770b9f2a06853192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 5 May 2024 19:02:21 +0200 Subject: [PATCH 112/130] Update wait-on-action --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ec023c8524..bd0d7e30d2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -212,7 +212,7 @@ jobs: python ./scripts/panelite/generate_panelite_content.py jupyter lite build --lite-dir lite --output-dir lite/dist - name: Wait for JupyterLab - uses: ifaxity/wait-on-action@v1.1.0 + uses: ifaxity/wait-on-action@v1.2.1 with: resource: http-get://localhost:8887/lab timeout: 180000 From f57738f058c7d1a68eeceb366c905cbbd78e1f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 7 May 2024 15:11:46 +0200 Subject: [PATCH 113/130] Update docs (mainly c/p from HoloViews) --- doc/conf.py | 5 + doc/developer_guide/index.md | 195 ++++++++++++++++++--------------- doc/developer_guide/testing.md | 111 ------------------- 3 files changed, 114 insertions(+), 197 deletions(-) delete mode 100644 doc/developer_guide/testing.md diff --git a/doc/conf.py b/doc/conf.py index a5eada73f9..bb29e5ace2 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -94,6 +94,11 @@ jlite_url = 'https://holoviz-dev.github.io/panelite-dev' if is_dev else 'https://panelite.holoviz.org' pyodide_url = 'https://holoviz-dev.github.io/panel/pyodide' if is_dev else 'https://panel.holoviz.org/pyodide' +rediraffe_redirects = { + # Removal of the developer testing page + 'developer_guide/testing': 'developer_guide/index', +} + nbsite_analytics = { 'goatcounter_holoviz': True, } diff --git a/doc/developer_guide/index.md b/doc/developer_guide/index.md index 2b02d60a13..49f9996ac9 100644 --- a/doc/developer_guide/index.md +++ b/doc/developer_guide/index.md @@ -1,8 +1,8 @@ -# Developer Guide +# Setting up a development environment -The Panel library is a project which provides a wide range of data interfaces and an extensible set of plotting backends, which means the development and testing process involves a wide set of libraries. +The Panel library is a project that provides a wide range of data interfaces and an extensible set of plotting backends, which means the development and testing process involves a broad set of libraries. -This guide describes how to install and configure the development environment either simplified for first time contributors or fully as done by core developers. +This guide describes how to install and configure development environments. If you have any problems with the steps here, please reach out in the `dev` channel on [Discord](https://discord.gg/rb6gPXbdAr) or on [Discourse](https://discourse.holoviz.org/). @@ -10,7 +10,7 @@ If you have any problems with the steps here, please reach out in the `dev` chan ### Basic understanding of how to contribute to Open Source -If this is your first open source contribution, please study one +If this is your first open-source contribution, please study one or more of the below resources. - [How to Get Started with Contributing to Open Source | Video](https://youtu.be/RGd5cOXpCQw) @@ -19,53 +19,48 @@ or more of the below resources. ### Git -The Panel source code is stored in a [Git](https://git-scm.com) source control repository. The first step to working on Panel is to install Git on to your system. There are different ways to do this depending on whether, you are using Windows, OSX, or Linux. +The Panel source code is stored in a [Git](https://git-scm.com) source control repository. The first step to working on Panel is to install Git onto your system. There are different ways to do this, depending on whether you use Windows, Mac, or Linux. To install Git on any platform, refer to the [Installing Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) section of the [Pro Git Book](https://git-scm.com/book/en/v2). -In order to contribute to Panel you will also need [Github account](https://github.com/join) and knowledge of the [*fork and pull request workflow*](https://docs.github.com/en/get-started/quickstart/contributing-to-projects). +To contribute to Panel, you will also need [Github account](https://github.com/join) and knowledge of the [_fork and pull request workflow_](https://docs.github.com/en/get-started/quickstart/contributing-to-projects). -### Pip +### Pixi -First time contributors can get quickly up to speed using `pip` instead of `conda`. +Developing all aspects of Panel requires a wide range of packages in different environments. To make this more manageable, Pixi manages the developer experience. To install Pixi, follow [this guide](https://pixi.sh/latest/#installation). -### Conda +#### Glossary -Developing all aspects of Panel requires a wide range of packages that are not easily and quickly available using pip. To make this more manageable, core developers rely heavily on the [conda package manager](https://conda.io/docs/intro.html) for the free [Anaconda](https://anaconda.com/downloads) Python distribution. However, ``conda`` can also install non-Python package dependencies, which helps streamline Panel development greatly. It is *strongly* recommended that any experienced or regular contributor use ``conda``. +- Tasks: A task is what can be run with `pixi run `. Tasks can be anything from installing packages to running tests. +- Environments: An environment is a set of packages installed in a virtual environment. Each environment has a name; you can run tasks in a specific environment with the `-e` flag. For example, `pixi run -e test-core test-unit` will run the `test-unit` task in the `test-core` environment. +- Lock-file: A lock-file is a file that contains all the information about the environments. -To install Conda on any platform, see the [Download conda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/download.html) section of the `conda documentation`_. +For more information, see the [Pixi documentation](https://pixi.sh/latest/). -## Cloning the Project +:::{admonition} Note +:class: info -The source code for the Panel project is hosted on [GitHub](https://github.com/holoviz/panel). +The first time you run `pixi`, it will create a `.pixi` directory in the source directory. +This directory will contain all the files needed for the virtual environments. +The `.pixi` directory can be large, so it is advised not to put the source directory into a cloud-synced directory. +::: -### Non-core developer - -To clone the source repository - -- Go to [github.com/holoviz/panel](https://github.com/holoviz/panel) -- [Fork the repository](https://docs.github.com/en/get-started/quickstart/contributing-to-projects#forking-a-repository) -- Run - -```bash -git clone https://github.com//panel.git -``` - -### Core developer +## Installing the Project -Core developers can work directly with the Panel repository. To clone run +### Cloning the Project -```base -git clone https://github.com/holoviz/panel.git -``` +The source code for the Panel project is hosted on [GitHub](https://github.com/holoviz/panel). The first thing you need to do is clone the repository. -## Installing the Project +1. Go to [github.com/holoviz/panel](https://github.com/holoviz/panel) +2. [Fork the repository](https://docs.github.com/en/get-started/quickstart/contributing-to-projects#forking-a-repository) +3. Run in your terminal: `git clone https://github.com//panel` -The instructions for cloning above created a ``panel`` directory at your file system location. This ``panel`` directory is referred to as the *source checkout* for the remainder of this document. For the remainder of this document we will assume your current working directory is the *source checkout* directory. +The instructions for cloning above created a `panel` directory at your file system location. +This `panel` directory is the _source checkout_ for the remainder of this document, and your current working directory is this directory. ### Fetch tags from upstream -Make sure to fetch tags from upstream repository before installing +The version number of the package depends on [`git tags`](https://git-scm.com/book/en/v2/Git-Basics-Tagging), so you need to fetch the tags from the upstream repository: ```bash git remote add upstream https://github.com/holoviz/panel.git @@ -73,111 +68,141 @@ git fetch --tags upstream git push --tags ``` -### Basic Install with pip +## Start developing -We recommend this install to first time contributors that +To start developing, run the following command -- want to make a simple, quick contribution to notebooks, docs or the Python code -- can use pip to create and manage [virtual environments](https://realpython.com/python-virtual-environments-a-primer/). - -Create a new virtual environment and activate it. +```bash +pixi install +``` -Run +The first time you run it, it will create a `pixi.lock` file with information for all available environments. This command will take a minute or so to run. +When this is finished, it is possible to run the following command to download the data Panel tests and examples depend upon. ```bash -pip install -e . jupyterlab pre-commit -panel bundle --all -pre-commit install +pixi run download-data ``` -We install the [pre-commit](https://pre-commit.com/) package above to avoid pushing and reviewing code with obvious issues. +All available tasks can be found by running `pixi task list`, the following sections will give a brief introduction to the most common tasks. + +### Editable install -You can start Jupyter Lab by running +It can be advantageous to install the Panel in [editable mode](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs): ```bash -jupyter lab +pixi run install ``` -If you start seeing `ImportError` due to missing packages, you can install them manually using -`pip` or consider if its time to switch to a *full install* with conda. +:::{admonition} Note +:class: info -### Full Install with conda +Currently, this needs to be run for each environment. So, if you want to install in the `test-ui` environment, you can add `--environment` / `-e` to the command: -This is the *full install* used by the *core developers*. +```bash +pixi run -e test-ui install +``` -#### Create a development environment +::: -Since Panel interfaces with a large range of different libraries the full test suite requires a wide range of dependencies. To make it easier to install and run different parts of the test suite across -different platforms Panel uses a library called `pyctdev` to make things more consistent and general. To start with `cd` into the panel directory and set up conda using the following commands: +## Linting + +Panel uses [pre-commit](https://pre-commit.com/) to apply linting to Panel code. Linting can be run for all the files with: ```bash -cd panel -conda install -c pyviz "pyctdev>0.5.0" +pixi run lint ``` -Once pyctdev is available and you are in the cloned panel repository you can set up an environment with: +Linting can also be set up to run automatically with each commit; this is the recommended way because if linting is not passing, the [Continuous Integration](https://en.wikipedia.org/wiki/Continuous_integration) (CI) will also fail. ```bash -doit env_create -c pyviz/label/dev -c conda-forge --name=panel_dev --python=3.9 +pixi run lint-install ``` -Specify the desired Python version, currently Panel officially supports Python 3.9 or later. Once the environment has been created you can activate it with: +## Testing -```bash -conda activate panel_dev -``` +To help keep Panel maintainable, all Pull Requests (PR) with code changes should typically be accompanied by relevant tests. While exceptions may be made for specific circumstances, the default assumption should be that a Pull Request without tests will not be merged. + +There are three types of tasks and five environments related to tests. -#### Install Panel in editable mode +### Unit tests -To perform an editable install of Panel, including all the dependencies required to run the full unit test suite, run the following: +Unit tests are usually small tests executed with [pytest](https://docs.pytest.org). They can be found in `panel/tests/`. +Unit tests can be run with the `test-unit` task: ```bash -doit develop_install -c pyviz/label/dev -c conda-forge -c bokeh -o build -o tests -o recommended +pixi run test-unit ``` -The above command installs Panel's dependencies using conda, then performs a pip editable install of Panel. If it fails, `nodejs>=14.0.0` may be missing from your environment, fix it with `conda install -c conda-forge nodejs` then rerun above command. +The task is available in the following environments: `test-39`, `test-310`, `test-311`, `test-312`, and `test-core`. Where the first ones have the same environments except for different Python versions, and `test-core` only has a core set of dependencies. -If you also want to run the UI tests you'll need to install pytest-playwright with `conda`: +If you haven't set the environment flag in the command, a menu will help you select which one of the environments to use. -``` bash -conda install pytest-playwright -c microsoft -c conda-forge -``` +### Example tests -or with `pip` (if you prefer it, or if there's no conda package found for your platform): +Panel's documentation consists mainly of Jupyter Notebooks. The example tests execute all the notebooks and fail if an error is raised. Example tests are possible thanks to [nbval](https://nbval.readthedocs.io/) and can be found in the `examples/` folder. +Example tests can be run with the following command: -``` bash -pip install pytest-playwright +```bash +pixi run test-example ``` -then run: +This task has the same environments as the unit tests except for `test-core`. + +### UI tests -``` bash -playwright install chromium +Panel provides web components that users can interact with through the browser. UI tests allow checking that these components get displayed as expected and that the backend <-> front-end bi-communication works correctly. UI tests are possible thanks to [Playwright](https://playwright.dev/python/). +The test can be found in the `panel/tests/ui/` folder. +UI tests can be run with the following task. This task is only available in the `test-ui` environment. The first time you run it, it will download the necessary browser files to run the tests in the Chrome browser. + +```bash +pixi run test-ui ``` -#### Enable the Jupyter extension +## Documentation -If you are running UI tests or intend to use the Panel Preview feature in Jupyter you must enable the server extension. To enable the classic notebook server extension: +The documentation can be built with the command: ```bash -jupyter serverextension enable panel.io.jupyter_server_extension --sys-prefix +pixi run docs-build ``` -For Jupyter Server: +As Panel uses notebooks for much of the documentation, this will take significant time to run (around an hour). + +A development version of Panel can be found [here](https://holoviz-dev.github.io/panel/). You can ask a maintainer if they want to make a dev release for your PR, but there is no guarantee they will say yes. + +To be able to run cells interactively you need `pyodide` server, this can be ran with: ```bash -jupyter server extension enable panel.io.jupyter_server_extension --sys-prefix +pixi run docs-server ``` -#### Setting up pre-commit +## Build -Panel uses [pre-commit](https://pre-commit.com/) to automatically apply linting to Panel code. If you intend to contribute to Panel we recommend you enable it with: +Panel have four build tasks. One is for building packages for Pip, Conda, Pyodide, and NPM. ```bash -pre-commit install +pixi run build-pip +pixi run build-conda +pixi run build-pyodide +pixi run build-npm ``` -This will ensure that every time you make a commit linting will automatically be applied. +## Continuous Integration + +Every push to the `main` branch or any PR branch on GitHub automatically triggers a test build with [GitHub Actions](https://github.com/features/actions). + +You can see the list of all current and previous builds at [this URL](https://github.com/holoviz/panel/actions) + +### Etiquette + +GitHub Actions provides free build workers for open-source projects. A few considerations will help you be considerate of others needing these limited resources: + +- Run the tests locally before opening or pushing to an opened PR. + +- Group commits to meaningful chunks of work before pushing to GitHub (i.e., don't push on every commit). + + +---- #### Developing custom models @@ -199,7 +224,6 @@ Panel bundles external resources required for custom models and templates into t You will likely want to check out the - [Extensions Guide](extensions.md) -- [Testing Guide](testing.md). - [WASM Guide](wasm.md) ## Useful Links @@ -217,7 +241,6 @@ You will likely want to check out the :maxdepth: 2 extensions -testing wasm Developing custom models ``` diff --git a/doc/developer_guide/testing.md b/doc/developer_guide/testing.md deleted file mode 100644 index 864f6ceb4b..0000000000 --- a/doc/developer_guide/testing.md +++ /dev/null @@ -1,111 +0,0 @@ -# Testing - -This chapter describes how to run various tests locally in a development environment, guidelines for writing tests, and information regarding the continuous testing infrastructure. - -## Running Tests Locally - -Before attempting to run Panel tests, make sure you have successfully run through all of the instructions in the [developer setup guide](index.md). - -### pre-commit - -Set up [pre-commit](https://pre-commit.com/) hooks to ensure that your code is linted correctly whenever you commit a change. - -To run the `pre-commit` hooks explicitly: - -```bash -pre-commit run -a -``` - -### Test Selection - -Currently Panel uses linting and three types of tests: - -* *Unit tests*: usually small tests executed with [pytest](https://docs.pytest.org), they can be found in `panel/tests/`. -* *UI tests*: Panel provides web components that users can interact with through their browser, UI tests allow to check that these components get displayed as expected, and that the backend <-> front-end bi-communication (e.g. updating a widget value in the front end should update its value in Python) works correctly. UI tests are possible thanks to [Playwright](https://playwright.dev/python/), they can be found in the `panel/tests/ui/` folder. -* *Notebooks smoke tests*: Panel's documentation consists mostly of Jupyter Notebooks, these smoke tests execute all the notebooks and fail if an error is raised during their execution. Notebook smoke tests are possible thanks to [nbval](https://nbval.readthedocs.io/) and can be found in the `examples/` folder. - - -To run flake checking explicitly run: - -```bash -doit test_flakes -``` - -To run unit tests use: - -```bash -doit test_unit -``` - -To run UI tests use: - -```bash -doit test_ui -``` - -To run example smoke tests use: - -``` -doit test_examples -``` - -## Writing Tests - -In order to help keep Panel maintainable, all Pull Requests that touch code should normally be accompanied by relevant tests. While exceptions may be made for specific circumstances, the default assumption should be that a Pull Request without tests may not be merged. - -### Python Unit Tests - -Python unit tests maintain the basic functionality of the Python portion of the Panel library. A few general guidelines will help you write Python unit tests: - -- absolute imports - - In order to ensure that Panel's unit tests as relocatable and unambiguous as possible, always prefer absolute imports in test files. When convenient, import and use the entire module under test: - - * **GOOD**: ``import panel.widgets`` - * **GOOD**: ``from panel.layout import Column`` - * **BAD**: ``from ..models.widgets import Player`` - -- pytest - - All new tests should use and assume [pytest](https://docs.pytest.org) for test running, fixtures, parameterized testing, etc. New tests should *not* use the `unittest` module of the Python standard library. - -### UI tests - -It may be difficult to write UI tests robust enough to pass all the time. For instance some tests may need to download some CSS resources online, if the domain that hosts these resources do not serve them in a limited time (defined by a Playwright timeout) then the test will fail. To cover these cases you can mark your test as flaky with `@pytest.mark.flaky`, refer to [flaky](https://github.com/box/flaky)'s documentation for more information. - -## Continuous Integration - -Every push to the `main` branch or any Pull Request branch on GitHub automatically triggers a full test build on the [GitHub Actions](https://github.com/features/actions) continuous integration service. This is most often useful for running the full Panel test suite continuously, but also triggers automated scripts for publishing releases when a tagged branch is pushed. - -You can see the list of all current and previous builds at this URL: https://github.com/holoviz/panel/actions - -### Configuration - -There are a number of files that affect the build configuration: - -* `.github/worksflows/test.yaml` - - Defines the build matrix and global configurations for the stages - described below. - -* `conda.recipe/meta.yaml` - - Instructions for building a conda noarch package for Panel. - -* `setup.py` - - Used to build sdist packages and "dev" installs. This file is the **single source of truth of all dependencies**. - -* `tox.ini` - - Contains the configuration for the doit commands . - -### Etiquette - -GitHub Actions provides free build workers to Open Source projects. A few considerations will help you be considerate of others needing these limited resources: - -* Run the tests locally before opening a Pull Request, or before committing to an opened Pull Request. - -* Group commits into meaningful chunks of work before pushing to GitHub (i.e. don't push on every commit). - -* If you must make multiple commits in succession, navigate to GitHub Actions and cancel all but the last build, in order to free up build workers. From d23cab9d8c06997b6ab9846c92459169cd9776f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 7 May 2024 15:20:43 +0200 Subject: [PATCH 114/130] Split out custom models to own page --- doc/developer_guide/custom_models.md | 18 ++++++++++++++++++ doc/developer_guide/index.md | 22 +++------------------- 2 files changed, 21 insertions(+), 19 deletions(-) create mode 100644 doc/developer_guide/custom_models.md diff --git a/doc/developer_guide/custom_models.md b/doc/developer_guide/custom_models.md new file mode 100644 index 0000000000..ed70dd36d0 --- /dev/null +++ b/doc/developer_guide/custom_models.md @@ -0,0 +1,18 @@ +# Developing custom models + +Panel ships with a number of custom Bokeh models, which have both Python and Javascript components. +When developing Panel these custom models have to be compiled. +This happens automatically with `pip install -e .` or `pixi run install`, however when running actively developing you can rebuild the extension with `panel build panel` from the source directory. The `build` command is just an alias for `bokeh build`; see +the [Bokeh developer guide](https://docs.bokeh.org/en/latest/docs/dev_guide/setup.html) for more information about developing bokeh models. + +Just like any other Javascript (or Typescript) library Panel defines a `package.json` and `package-lock.json` files. +When adding, updating or removing a dependency in the package.json file ensure you commit the changes to the `package-lock.json` after running `npm install`. + +# Bundling resources + +Panel bundles external resources required for custom models and templates into the `panel/dist` directory. +The bundled resources have to be collected whenever they change, so rerun `pip install -e .` or `pixi run install`, whenever you change one of the following: + +- A new model is added with a `__javascript_raw__` declaration or an existing model is updated +- A new template with a `_resources` declaration is added or an existing template is updated +- A CSS file in one of template directories (`panel/template/*/`) is added or modified diff --git a/doc/developer_guide/index.md b/doc/developer_guide/index.md index 49f9996ac9..eca445213c 100644 --- a/doc/developer_guide/index.md +++ b/doc/developer_guide/index.md @@ -202,29 +202,13 @@ GitHub Actions provides free build workers for open-source projects. A few consi - Group commits to meaningful chunks of work before pushing to GitHub (i.e., don't push on every commit). ----- - -#### Developing custom models - -Panel ships with a number of custom Bokeh models, which have both Python and Javascript components. When developing Panel these custom models have to be compiled. This happens automatically with `SETUPTOOLS_ENABLE_FEATURES=legacy-editable pip install -e .` or `python setup.py develop`, however when running actively developing you can rebuild the extension with `panel build panel`. The `build` command is just an alias for `bokeh build`; see -the [Bokeh developer guide](https://docs.bokeh.org/en/latest/docs/dev_guide/setup.html) for more information about developing bokeh models. - -Just like any other Javascript (or Typescript) library Panel defines a `package.json` and `package-lock.json` files. When adding, updating or removing a dependency in the package.json file ensure you commit the changes to the `package-lock.json` after running `npm install`. - -#### Bundling resources - -Panel bundles external resources required for custom models and templates into the `panel/dist` directory. The bundled resources have to be collected whenever they change, so rerun `SETUPTOOLS_ENABLE_FEATURES=legacy-editable pip install -e .` or `python setup.py develop` whenever you change one of the following: - -* A new model is added with a `__javascript_raw__` declaration or an existing model is updated -* A new template with a `_resources` declaration is added or an existing template is updated -* A CSS file in one of template directories (`panel/template/*/`) is added or modified - -#### Next Steps +## Next Steps You will likely want to check out the - [Extensions Guide](extensions.md) - [WASM Guide](wasm.md) +- [Developing custom models](custom_models.md) ## Useful Links @@ -242,5 +226,5 @@ You will likely want to check out the extensions wasm -Developing custom models +Developing custom models ``` From 1cbace98694d3e7b3345b749129bfa7846c92c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 7 May 2024 16:00:17 +0200 Subject: [PATCH 115/130] Add lxml back --- pixi.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pixi.toml b/pixi.toml index 5b4ec965ec..b49f37657c 100644 --- a/pixi.toml +++ b/pixi.toml @@ -147,6 +147,7 @@ depends_on = ["_install-ui"] # ============================================= [feature.doc.dependencies] nbsite = ">=0.8.4" +lxml = "*" [feature.doc.tasks] _docs-refmanual = 'python ./doc/generate_modules.py panel -d ./doc/api -n panel -e tests' From b9d4865e15ca20cd0a92dc443b046f780aa3682a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 7 May 2024 16:23:53 +0200 Subject: [PATCH 116/130] Add more custom.css colors --- doc/_static/css/custom.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index 34aa30b6c1..62f48e1e78 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -4,6 +4,11 @@ --pst-color-link: #0072b5; --pst-color-inline-code: #0072b5; --sd-color-card-border-hover: #0072b5; + --pst-color-link-hover: #0072b5; + --pst-color-secondary: #0072b5; + --pst-color-inline-code: #0072b5; + --pst-color-secondary-highlight: #0072b5; + --pst-color-secondary-bg: #adc9ff; } /* Fix breadcrumb overlap https://github.com/holoviz/panel/issues/5199 */ From d8a1be7d0e5ddbada604ee2536685364f06c5737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 7 May 2024 16:35:33 +0200 Subject: [PATCH 117/130] Remove setuptools legacy from binder start --- binder/start | 1 - 1 file changed, 1 deletion(-) diff --git a/binder/start b/binder/start index 8960f84b3d..20a50ffe33 100644 --- a/binder/start +++ b/binder/start @@ -1,6 +1,5 @@ #!/bin/bash export BOKEH_ALLOW_WS_ORIGIN=* -export SETUPTOOLS_ENABLE_FEATURES=legacy-editable echo '' >> panel/template/base.py echo 'BasicTemplate.param.site_url.default="./"' >> panel/template/base.py export DISPLAY=:99.0 From 682007f4751c584955aa549002b558b1e5ca1d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 7 May 2024 17:58:48 +0200 Subject: [PATCH 118/130] Small doc fixes --- doc/_static/css/custom.css | 19 ++++++++++--------- doc/index.md | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index 62f48e1e78..5d54dea5f4 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -1,14 +1,15 @@ :root[data-theme='light'], :root[data-theme='dark'] { - --pst-color-primary: #0072b5; - --pst-color-link: #0072b5; - --pst-color-inline-code: #0072b5; - --sd-color-card-border-hover: #0072b5; - --pst-color-link-hover: #0072b5; - --pst-color-secondary: #0072b5; - --pst-color-inline-code: #0072b5; - --pst-color-secondary-highlight: #0072b5; - --pst-color-secondary-bg: #adc9ff; + --holoviz-main-color: #0072b5; + --pst-color-primary: var(--holoviz-main-color); + --pst-color-link: var(--holoviz-main-color); + --pst-color-inline-code: var(--holoviz-main-color); + --sd-color-card-border-hover: var(--holoviz-main-color); + --pst-color-link-hover: var(--holoviz-main-color); + --pst-color-secondary: var(--holoviz-main-color); + --pst-color-inline-code: var(--holoviz-main-color); + --pst-color-secondary-highlight: var(--holoviz-main-color); + --pst-color-secondary-bg: #d9ebf0; } /* Fix breadcrumb overlap https://github.com/holoviz/panel/issues/5199 */ diff --git a/doc/index.md b/doc/index.md index a823e0c310..218ddc7142 100644 --- a/doc/index.md +++ b/doc/index.md @@ -237,5 +237,5 @@ about/index :maxdepth: 2 :caption: FOR DEVELOPERS -developer_guide/index +Developer Guide ``` From 12403895e8e86c4fd4049d6ea646fe02ecacf466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Tue, 7 May 2024 18:12:51 +0200 Subject: [PATCH 119/130] add comment about announcement banner --- doc/_static/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index 5d54dea5f4..235077bc2c 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -9,7 +9,7 @@ --pst-color-secondary: var(--holoviz-main-color); --pst-color-inline-code: var(--holoviz-main-color); --pst-color-secondary-highlight: var(--holoviz-main-color); - --pst-color-secondary-bg: #d9ebf0; + --pst-color-secondary-bg: #d9ebf0; /* Announcement banner */ } /* Fix breadcrumb overlap https://github.com/holoviz/panel/issues/5199 */ From 2f4de71ebef0c0bb3bf1772cbf54b68f4140ef8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 8 May 2024 10:09:36 +0200 Subject: [PATCH 120/130] Add --cov-append --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index bd0d7e30d2..55e175b9d2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -35,7 +35,7 @@ env: DISPLAY: ":99.0" PYTHONIOENCODING: "utf-8" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - COV: "--cov=./panel --cov-report=xml" + COV: "--cov=./panel --cov-report=xml --cov-append" jobs: pre_commit: From c60fdd9bf69f3b3334f25954b1d1d4cbb11192dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Wed, 8 May 2024 10:53:17 +0200 Subject: [PATCH 121/130] Remove xyzservices from dependencies --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8e30f08d2e..0a368270fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,6 @@ dependencies = [ 'bokeh >=3.4.0,<3.5.0', 'param >=2.1.0,<3.0', 'pyviz_comms >=2.0.0', - 'xyzservices >=2021.09.1', # Bokeh dependency, but pyodide 23.0.0 does not always pick it up 'markdown', 'markdown-it-py', 'linkify-it-py', From 48b16f6671b848060d731155273d478c559220d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Fri, 10 May 2024 13:15:03 +0200 Subject: [PATCH 122/130] remove wrong setting --- .github/workflows/test.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index a10badf366..55e175b9d2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -197,7 +197,6 @@ jobs: - uses: holoviz-dev/holoviz_tasks/pixi_install@pixi with: environments: ${{ matrix.environment }} - playwright: true id: install - name: Launch JupyterLab shell: pixi run -e test-ui bash -el {0} From ef735d709137013983d4a562396a4aca328d87ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Fri, 10 May 2024 14:03:07 +0200 Subject: [PATCH 123/130] Try pin IPython for UI tests --- pixi.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pixi.toml b/pixi.toml index b49f37657c..b93fe1511f 100644 --- a/pixi.toml +++ b/pixi.toml @@ -134,6 +134,7 @@ channels = ["pyviz/label/dev", "bokeh", "microsoft", "conda-forge"] playwright = "*" pytest-playwright = "*" jupyter_server = "*" +ipython = "<8.24" [feature.test-ui.tasks] _install-ui = 'playwright install chromium' From 4862f1b9871548b19cb12c9ec091100880e42267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Fri, 10 May 2024 15:42:54 +0200 Subject: [PATCH 124/130] Remove ipython pin --- pixi.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index b93fe1511f..b49f37657c 100644 --- a/pixi.toml +++ b/pixi.toml @@ -134,7 +134,6 @@ channels = ["pyviz/label/dev", "bokeh", "microsoft", "conda-forge"] playwright = "*" pytest-playwright = "*" jupyter_server = "*" -ipython = "<8.24" [feature.test-ui.tasks] _install-ui = 'playwright install chromium' From b7cac3d0cc3a442474a74cbcaa60f9a35391209d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sat, 11 May 2024 10:26:29 +0200 Subject: [PATCH 125/130] Sort colors --- doc/_static/css/custom.css | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index 235077bc2c..fcf10acd2a 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -1,15 +1,14 @@ :root[data-theme='light'], :root[data-theme='dark'] { --holoviz-main-color: #0072b5; - --pst-color-primary: var(--holoviz-main-color); - --pst-color-link: var(--holoviz-main-color); --pst-color-inline-code: var(--holoviz-main-color); - --sd-color-card-border-hover: var(--holoviz-main-color); --pst-color-link-hover: var(--holoviz-main-color); - --pst-color-secondary: var(--holoviz-main-color); - --pst-color-inline-code: var(--holoviz-main-color); - --pst-color-secondary-highlight: var(--holoviz-main-color); + --pst-color-link: var(--holoviz-main-color); + --pst-color-primary: var(--holoviz-main-color); --pst-color-secondary-bg: #d9ebf0; /* Announcement banner */ + --pst-color-secondary-highlight: var(--holoviz-main-color); + --pst-color-secondary: var(--holoviz-main-color); + --sd-color-card-border-hover: var(--holoviz-main-color); } /* Fix breadcrumb overlap https://github.com/holoviz/panel/issues/5199 */ From e638a1e1e9b02f3ace7c5b30866fcb7c636781cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Sun, 12 May 2024 09:15:33 +0200 Subject: [PATCH 126/130] Remove shell from build --- .github/workflows/build.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4780054e6d..23c3c97629 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -149,7 +149,6 @@ jobs: environments: "build" download-data: false - name: npm build - shell: pixi run -e build bash -el {0} run: | TARBALL=$(pixi run build-npm) echo "TARBALL=$TARBALL" >> $GITHUB_ENV From 355d67ba4c836f22cb2b67a73b5fa60c23abf0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 13 May 2024 13:19:44 +0200 Subject: [PATCH 127/130] Move hatch_build.py to root directory --- scripts/hatch_build.py => hatch_build.py | 0 pyproject.toml | 3 --- 2 files changed, 3 deletions(-) rename scripts/hatch_build.py => hatch_build.py (100%) diff --git a/scripts/hatch_build.py b/hatch_build.py similarity index 100% rename from scripts/hatch_build.py rename to hatch_build.py diff --git a/pyproject.toml b/pyproject.toml index 0a368270fe..c363e0fc67 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -113,9 +113,6 @@ include = ["panel", "scripts", "examples"] [tool.hatch.build.hooks.vcs] version-file = "panel/_version.py" -[tool.hatch.build.hooks.custom] -path = "scripts/hatch_build.py" - [tool.ruff] exclude = [ ".git", From a4faf34a3546aa436f8128dd84eb524c2c4de4c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 13 May 2024 13:26:51 +0200 Subject: [PATCH 128/130] Move custom models to markdown file --- doc/developer_guide/custom_models.md | 340 +++++++++++++++ .../Developing_Custom_Models.ipynb | 404 ------------------ 2 files changed, 340 insertions(+), 404 deletions(-) delete mode 100644 examples/developer_guide/Developing_Custom_Models.ipynb diff --git a/doc/developer_guide/custom_models.md b/doc/developer_guide/custom_models.md index ed70dd36d0..43daff4eba 100644 --- a/doc/developer_guide/custom_models.md +++ b/doc/developer_guide/custom_models.md @@ -8,6 +8,346 @@ the [Bokeh developer guide](https://docs.bokeh.org/en/latest/docs/dev_guide/setu Just like any other Javascript (or Typescript) library Panel defines a `package.json` and `package-lock.json` files. When adding, updating or removing a dependency in the package.json file ensure you commit the changes to the `package-lock.json` after running `npm install`. +## Adding a new Custom Model + +This example will guide you through adding a new model. + +We will use the the `ChartJS` model as an example. But you should replace `ChartJS` and similar with the name of your model. + +Here we will add a simple Button model to start with. But we call it `ChartJS`. + +My experience is that you should start small with a working example and the continue in small, incremental steps. For me it did not work trying to copy a large, complex example and refactoring it when I started out learning about Custom Models. + +1. Create a new branch `chartjs`. +2. Add the files and code for a *minimum working model*. This includes + - A Panel Python model + - A Bokeh Python and TypeScript model + +#### Add the Panel Python Model + +Add the file *panel/pane/chartjs.py* and the code + +```python +import param + +from panel.widgets.base import Widget + +from ..models import ChartJS as _BkChartJS + + +class ChartJS(Widget): + # Set the Bokeh model to use + _widget_type = _BkChartJS + + # Rename Panel Parameters -> Bokeh Model properties + # Parameters like title that does not exist on the Bokeh model should be renamed to None + _rename = { + "title": None, + } + + # Parameters to be mapped to Bokeh model properties + object = param.String(default="Click Me!") + clicks = param.Integer(default=0) +``` + +Add the Panel model to `panel/pane/__init__.py` + +```python +from .chartjs import ChartJS +``` + +#### Add the Bokeh Python Model + +Add the file *panel/models/chartjs.py* and the code + +```python +from bokeh.core.properties import Int, String +from bokeh.models import HTMLBox + +class ChartJS(HTMLBox): + """Custom ChartJS Model""" + + object = String() + clicks = Int() +``` + +Add the Bokeh model to `panel/models/__init__.py` file + +```python +from .chartjs import ChartJS +``` + +#### Add the Bokeh TypeScript Model + +Add the file *panel/models/chartjs.ts* and the code + +```typescript +// See https://docs.bokeh.org/en/latest/docs/reference/models/layouts.html +import { HTMLBox, HTMLBoxView } from "@bokehjs/models/layouts/html_box" + +// See https://docs.bokeh.org/en/latest/docs/reference/core/properties.html +import * as p from "@bokehjs/core/properties" + +// The view of the Bokeh extension/ HTML element +// Here you can define how to render the model as well as react to model changes or View events. +export class ChartJSView extends HTMLBoxView { + model: ChartJS + objectElement: any // Element + + connect_signals(): void { + super.connect_signals() + + this.on_change(this.model.properties.object, () => { + this.render(); + }) + } + + render(): void { + super.render() + this.el.innerHTML = `` + this.objectElement = this.el.firstElementChild + + this.objectElement.addEventListener("click", () => {this.model.clicks+=1;}, false) + } +} + +export namespace ChartJS { + export type Attrs = p.AttrsOf + export type Props = HTMLBox.Props & { + object: p.Property, + clicks: p.Property, + } +} + +export interface ChartJS extends ChartJS.Attrs { } + +// The Bokeh .ts model corresponding to the Bokeh .py model +export class ChartJS extends HTMLBox { + properties: ChartJS.Props + + constructor(attrs?: Partial) { + super(attrs) + } + + static __module__ = "panel.models.chartjs" + + static { + this.prototype.default_view = ChartJSView; + + this.define(({Int, String}) => ({ + object: [String, "Click Me!"], + clicks: [Int, 0], + })) + } +} +``` + +Add the `ChartJS` typescript model to *panel/models/index.ts* + +```typescript +export {ChartJS} from "./chartjs" +``` + +#### Build the Model + +You can now build the model using `panel build panel`. It should look similar to + +```bash +(base) root@475bb36209a9:/workspaces/panel# panel build panel +Working directory: /workspaces/panel/panel +Using /workspaces/panel/panel/tsconfig.json +Compiling styles +Compiling TypeScript (45 files) +Linking modules +Output written to /workspaces/panel/panel/dist +All done. +``` + +#### Test the Model + +Add the file *panel/tests/pane/test_chartjs.py* and the code + +```python +import panel as pn + + +def test_constructor(): + chartjs = pn.pane.ChartJS(object="Click Me Now!") + +def get_app(): + chartjs = pn.pane.ChartJS(object="Click Me Now!") + return pn.Column( + chartjs, pn.Param(chartjs, parameters=["object", "clicks"]) + ) + +if __name__.startswith("bokeh"): + get_app().servable() +``` + +Run `pytest panel/tests/pane/test_chartjs.py` and make sure it passes. + +Serve the app with `panel serve panel/tests/pane/test_chartjs.py --auto --show` + +You have to *hard refresh* your browser to reload the new panel `.js` files with your `ChartJS` model. In Chrome I press `CTRL+F5`. See [How to hard refresh in Chrome, Firefox and IE](https://www.namecheap.com/support/knowledgebase/article.aspx/10078/2194/how-to-do-a-hard-refresh-in-chrome-firefox-and-ie/) for other browsers. + +Now you can manually test your model + +![Chart JS Button](../assets/chartjs-button.gif) + +#### Save your new Model + +Finally you should save your changes via `git add .` and maybe even commit them `git commit -m "First iteration on ChartJS model"` + +## Build a small HTML Example + +In the beginning of your journey into Custom Models there will be things that break and difficulties figuring out why. When you combine several new things it can be really difficult to figure out why. Is the problem Panel, Bokeh, Python, Javascript, Node or ....? + +So I suggest creating a small, working example in plain HTML/ JS before you start combining with Panel and Bokeh Models. + +Please note the below example works out of the box. It is not always that easy importing javascript libraries in a Notebook. So it can be a good idea to work in a `.html` file first. + + +```html + +
+ +
+ +``` + +## Using the Javascript Model + +Getting something shown using the `ChartJS` `js` library would be the next step. It might require a bit of experimentation, looking at other examples, google or support from the community. + +Here I found that a good step where the following changes + +#### Import the Javascript Library + +Update *test_chartjs.py* tp + +```python +import panel as pn + + +def test_constructor(): + chartjs = pn.pane.ChartJS(object="Click Me Now!") + +def get_app(): + chartjs = pn.pane.ChartJS(object="Click Me Now!") + return pn.Column( + chartjs, pn.Param(chartjs, parameters=["object", "clicks"]) + ) + +if __name__.startswith("bokeh"): + pn.config.js_files["chartjs"]="https://cdn.jsdelivr.net/npm/chart.js@2.8.0" + get_app().servable() +``` + +#### Render the Plot + +In the *chartjs.ts* file add `import { canvas, div } from "@bokehjs/core/dom";` at the top and change the `render` function to + +```typescript +render(): void { + super.render() + var object = { + type: 'line', + data: { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [{ + label: 'My First dataset', + backgroundColor: 'rgb(255, 99, 132)', + borderColor: 'rgb(255, 99, 132)', + data: [0, 10, 5, 2, 20, 30, 45] + }] + }, + options: { + responsive: true, + maintainAspectRatio: false, + } + } + + var chartContainer = div({class: "chartjs-container", style: "position: relative; height:400px; width:100%"}) + var chartCanvas = canvas({class: "chartjs"}) + chartContainer.appendChild(chartCanvas) + var ctx: any = chartCanvas.getContext('2d'); + new (window as any).Chart(ctx, object); + + this.el.appendChild(chartContainer) +} +``` + +#### Build and Test + +Run `panel build panel` and hard refresh your browser. You should see + +![ChartJS Hello World](../assets/chartjs-hello-world.png) + +#### Save Your Model + +Remember to stage and/ or commit your working changes. + +## Next Steps + +- Enable setting the Python `ChartJS.object` parameter to any ChartJS dictionary. +- Checkout support for different sizing modes, responsiveness and window maximize. +- Configure the javascript, css, .. dependencies in the Bokeh Python File. +- ..... + +## Check List + +When you develop and test your model eventually you should consider implementing and testing + +- Dynamic updates to the `object` parameter and any other parameters added. +- Resizing + - Does it resize when `width` is changed dynamically? + - Does it resize when `height` is changed dynamically? + - Does it work with `sizing_mode="stretch_width"` etc. +- Themes (Light, Dark) +- Window Resizing, Window Maximizing, Window Minimizing. +- Streaming of Data. Is it efficient? +- Events (Click, Hover etc.) +- Consider supporting the Python Wrapper (ECharts -> PyECharts, ChartJS -> [PyChart.JS](https://pypi.org/project/pyChart.JS/)) +- Tests +- Reference Notebook +- Communication also to for example ChartJS community and developers. + +## Tips and Tricks + +- Work in small increments and stage your changes when they work +- Remember to `panel build panel` and hard refresh before you test. +- Add [console.log](https://www.w3schools.com/jsref/met_console_log.asp) statements to your `.ts` code for debugging. +- Use the [*Developer Tools*](https://developers.google.com/web/tools/chrome-devtools) *console* to see the `console.log` output and identify errors. In my browsers I toggle the Developer Tools using `CTRL+SHIFT+I`. +- Find inspiration for next steps in the [existing Panel Custom Models](https://github.com/holoviz/panel/tree/main/panel/models). For `ChartJS` one of the most relevant custom models would be `Echarts`. See Panel [echarts.py](https://github.com/holoviz/panel/blob/main/panel/pane/echarts.py), Bokeh [echarts.py](https://github.com/holoviz/panel/blob/main/panel/models/echarts.py) and [echarts.ts](https://github.com/holoviz/panel/blob/main/panel/models/echarts.ts). +- Use the existing documentation + - [Panel - Developer Guide](https://panel.holoviz.org/developer_guide/index.html) + - [Bokeh - Extending Bokeh](https://docs.bokeh.org/en/latest/docs/user_guide/extensions.html) +- Use Google Search. You don't have to be an expert javascript or typescript developer. It's a very small subset of those languages that is used when developing Custom Models. +- Ask for help in [Discord](https://discord.gg/rb6gPXbdAr), [HoloViz Discourse](https://discourse.holoviz.org/) and [Bokeh Discourse](https://discourse.bokeh.org/) forums. + # Bundling resources Panel bundles external resources required for custom models and templates into the `panel/dist` directory. diff --git a/examples/developer_guide/Developing_Custom_Models.ipynb b/examples/developer_guide/Developing_Custom_Models.ipynb deleted file mode 100644 index 58b795ef0f..0000000000 --- a/examples/developer_guide/Developing_Custom_Models.ipynb +++ /dev/null @@ -1,404 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "opposed-review", - "metadata": {}, - "source": [ - "Panel ships with a number of custom Bokeh models, which have both Python and Javascript components. When developing Panel these custom models have to be compiled. This happens automatically with `pip install -e .` or `python setup.py develop`, however when running actively developing you can rebuild the extension with `panel build panel`. The build command is just an alias for `bokeh build`; see the [Bokeh developer guide](https://docs.bokeh.org/en/latest/docs/dev_guide/setup.html) for more information about developing bokeh models or the [Awesome Panel - Bokeh Extensions Guide](https://awesome-panel.readthedocs.io/en/latest/guides/awesome-panel-extensions-guide/bokeh-extensions.html)\n", - "\n", - "Just like any other Javascript (or Typescript) library Panel defines a `package.json` and `package-lock.json` files. When adding, updating or removing a dependency in the `package.json` file ensure you commit the changes to the `package-lock.json` after running npm install." - ] - }, - { - "cell_type": "markdown", - "id": "raising-serum", - "metadata": {}, - "source": [ - "## Adding a new Custom Model\n", - "\n", - "This example will guide you through adding a new model. \n", - "\n", - "We will use the the `ChartJS` model as an example. But you should replace `ChartJS` and similar with the name of your model. \n", - "\n", - "Here we will add a simple Button model to start with. But we call it `ChartJS`. \n", - "\n", - "My experience is that you should start small with a working example and the continue in small, incremental steps. For me it did not work trying to copy a large, complex example and refactoring it when I started out learning about Custom Models.\n", - "\n", - "1. Create a new branch `chartjs`.\n", - "2. Add the files and code for a *minimum working model*. This includes\n", - " - A Panel Python model\n", - " - A Bokeh Python and TypeScript model\n", - "\n", - "#### Add the Panel Python Model\n", - "\n", - "Add the file *panel/pane/chartjs.py* and the code\n", - " \n", - "```python\n", - "import param\n", - "\n", - "from panel.widgets.base import Widget\n", - "\n", - "from ..models import ChartJS as _BkChartJS\n", - "\n", - "\n", - "class ChartJS(Widget):\n", - " # Set the Bokeh model to use\n", - " _widget_type = _BkChartJS\n", - "\n", - " # Rename Panel Parameters -> Bokeh Model properties\n", - " # Parameters like title that does not exist on the Bokeh model should be renamed to None\n", - " _rename = {\n", - " \"title\": None,\n", - " }\n", - "\n", - " # Parameters to be mapped to Bokeh model properties\n", - " object = param.String(default=\"Click Me!\")\n", - " clicks = param.Integer(default=0)\n", - "```\n", - "\n", - "Add the Panel model to `panel/pane/__init__.py`\n", - "\n", - "```python\n", - "from .chartjs import ChartJS\n", - "```\n", - "\n", - "#### Add the Bokeh Python Model\n", - "\n", - "Add the file *panel/models/chartjs.py* and the code\n", - "\n", - "```python\n", - "from bokeh.core.properties import Int, String\n", - "from bokeh.models import HTMLBox\n", - "\n", - "class ChartJS(HTMLBox):\n", - " \"\"\"Custom ChartJS Model\"\"\"\n", - "\n", - " object = String()\n", - " clicks = Int()\n", - "```\n", - "\n", - "Add the Bokeh model to `panel/models/__init__.py` file\n", - "\n", - "```python\n", - "from .chartjs import ChartJS\n", - "```\n", - "\n", - "#### Add the Bokeh TypeScript Model\n", - "\n", - "Add the file *panel/models/chartjs.ts* and the code\n", - "\n", - "```typescript\n", - "// See https://docs.bokeh.org/en/latest/docs/reference/models/layouts.html\n", - "import { HTMLBox, HTMLBoxView } from \"@bokehjs/models/layouts/html_box\"\n", - "\n", - "// See https://docs.bokeh.org/en/latest/docs/reference/core/properties.html\n", - "import * as p from \"@bokehjs/core/properties\"\n", - "\n", - "// The view of the Bokeh extension/ HTML element\n", - "// Here you can define how to render the model as well as react to model changes or View events.\n", - "export class ChartJSView extends HTMLBoxView {\n", - " model: ChartJS\n", - " objectElement: any // Element\n", - "\n", - " connect_signals(): void {\n", - " super.connect_signals()\n", - "\n", - " this.on_change(this.model.properties.object, () => {\n", - " this.render();\n", - " })\n", - " }\n", - "\n", - " render(): void {\n", - " super.render()\n", - " this.el.innerHTML = ``\n", - " this.objectElement = this.el.firstElementChild\n", - "\n", - " this.objectElement.addEventListener(\"click\", () => {this.model.clicks+=1;}, false)\n", - " }\n", - "}\n", - "\n", - "export namespace ChartJS {\n", - " export type Attrs = p.AttrsOf\n", - " export type Props = HTMLBox.Props & {\n", - " object: p.Property,\n", - " clicks: p.Property,\n", - " }\n", - "}\n", - "\n", - "export interface ChartJS extends ChartJS.Attrs { }\n", - "\n", - "// The Bokeh .ts model corresponding to the Bokeh .py model\n", - "export class ChartJS extends HTMLBox {\n", - " properties: ChartJS.Props\n", - "\n", - " constructor(attrs?: Partial) {\n", - " super(attrs)\n", - " }\n", - "\n", - " static __module__ = \"panel.models.chartjs\"\n", - "\n", - " static {\n", - " this.prototype.default_view = ChartJSView;\n", - "\n", - " this.define(({Int, String}) => ({\n", - " object: [String, \"Click Me!\"],\n", - " clicks: [Int, 0],\n", - " }))\n", - " }\n", - "}\n", - "```\n", - "\n", - "Add the `ChartJS` typescript model to *panel/models/index.ts*\n", - "\n", - "```typescript\n", - "export {ChartJS} from \"./chartjs\"\n", - "```\n", - "\n", - "#### Build the Model\n", - "\n", - "You can now build the model using `panel build panel`. It should look similar to\n", - "\n", - "```bash\n", - "(base) root@475bb36209a9:/workspaces/panel# panel build panel\n", - "Working directory: /workspaces/panel/panel\n", - "Using /workspaces/panel/panel/tsconfig.json\n", - "Compiling styles\n", - "Compiling TypeScript (45 files)\n", - "Linking modules\n", - "Output written to /workspaces/panel/panel/dist\n", - "All done.\n", - "```\n", - "\n", - "#### Test the Model\n", - "\n", - "Add the file *panel/tests/pane/test_chartjs.py* and the code\n", - "\n", - "```python\n", - "import panel as pn\n", - "\n", - "\n", - "def test_constructor():\n", - " chartjs = pn.pane.ChartJS(object=\"Click Me Now!\")\n", - "\n", - "def get_app():\n", - " chartjs = pn.pane.ChartJS(object=\"Click Me Now!\")\n", - " return pn.Column(\n", - " chartjs, pn.Param(chartjs, parameters=[\"object\", \"clicks\"])\n", - " )\n", - "\n", - "if __name__.startswith(\"bokeh\"):\n", - " get_app().servable()\n", - "```\n", - "\n", - "Run `pytest panel/tests/pane/test_chartjs.py` and make sure it passes.\n", - "\n", - "Serve the app with `panel serve panel/tests/pane/test_chartjs.py --auto --show`\n", - "\n", - "You have to *hard refresh* your browser to reload the new panel `.js` files with your `ChartJS` model. In Chrome I press `CTRL+F5`. See [How to hard refresh in Chrome, Firefox and IE](https://www.namecheap.com/support/knowledgebase/article.aspx/10078/2194/how-to-do-a-hard-refresh-in-chrome-firefox-and-ie/) for other browsers.\n", - "\n", - "Now you can manually test your model\n", - "\n", - "![Chart JS Button](../assets/chartjs-button.gif)\n", - "\n", - "#### Save your new Model\n", - "\n", - "Finally you should save your changes via `git add .` and maybe even commit them `git commit -m \"First iteration on ChartJS model\"`" - ] - }, - { - "cell_type": "markdown", - "id": "blessed-railway", - "metadata": {}, - "source": [ - "## Build a small HTML Example\n", - "\n", - "In the beginning of your journey into Custom Models there will be things that break and difficulties figuring out why. When you combine several new things it can be really difficult to figure out why. Is the problem Panel, Bokeh, Python, Javascript, Node or ....? \n", - "\n", - "So I suggest creating a small, working example in plain HTML/ JS before you start combining with Panel and Bokeh Models.\n", - "\n", - "Please note the below example works out of the box. It is not always that easy importing javascript libraries in a Notebook. So it can be a good idea to work in a `.html` file first." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "funded-traffic", - "metadata": {}, - "outputs": [], - "source": [ - "%%HTML\n", - "\n", - "
\n", - " \n", - "
\n", - "" - ] - }, - { - "cell_type": "markdown", - "id": "raising-burner", - "metadata": {}, - "source": [ - "## Using the Javascript Model\n", - "\n", - "Getting something shown using the `ChartJS` `js` library would be the next step. It might require a bit of experimentation, looking at other examples, google or support from the community.\n", - "\n", - "Here I found that a good step where the following changes\n", - "\n", - "#### Import the Javascript Library\n", - "\n", - "Update *test_chartjs.py* tp\n", - "\n", - "```python\n", - "import panel as pn\n", - "\n", - "\n", - "def test_constructor():\n", - " chartjs = pn.pane.ChartJS(object=\"Click Me Now!\")\n", - "\n", - "def get_app():\n", - " chartjs = pn.pane.ChartJS(object=\"Click Me Now!\")\n", - " return pn.Column(\n", - " chartjs, pn.Param(chartjs, parameters=[\"object\", \"clicks\"])\n", - " )\n", - "\n", - "if __name__.startswith(\"bokeh\"):\n", - " pn.config.js_files[\"chartjs\"]=\"https://cdn.jsdelivr.net/npm/chart.js@2.8.0\"\n", - " get_app().servable()\n", - "```\n", - "\n", - "#### Render the Plot\n", - "\n", - "In the *chartjs.ts* file add `import { canvas, div } from \"@bokehjs/core/dom\";` at the top and change the `render` function to \n", - "\n", - "```typescript\n", - "render(): void {\n", - " super.render()\n", - " var object = {\n", - " type: 'line',\n", - " data: {\n", - " labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],\n", - " datasets: [{\n", - " label: 'My First dataset',\n", - " backgroundColor: 'rgb(255, 99, 132)',\n", - " borderColor: 'rgb(255, 99, 132)',\n", - " data: [0, 10, 5, 2, 20, 30, 45]\n", - " }]\n", - " },\n", - " options: {\n", - " responsive: true,\n", - " maintainAspectRatio: false,\n", - " }\n", - " }\n", - "\n", - " var chartContainer = div({class: \"chartjs-container\", style: \"position: relative; height:400px; width:100%\"})\n", - " var chartCanvas = canvas({class: \"chartjs\"})\n", - " chartContainer.appendChild(chartCanvas)\n", - " var ctx: any = chartCanvas.getContext('2d');\n", - " new (window as any).Chart(ctx, object);\n", - "\n", - " this.el.appendChild(chartContainer)\n", - "}\n", - "```\n", - "\n", - "#### Build and Test\n", - "\n", - "Run `panel build panel` and hard refresh your browser. You should see\n", - "\n", - "![ChartJS Hello World](../assets/chartjs-hello-world.png)\n", - "\n", - "#### Save Your Model\n", - "\n", - "Remember to stage and/ or commit your working changes." - ] - }, - { - "cell_type": "markdown", - "id": "compound-optics", - "metadata": {}, - "source": [ - "## Next Steps\n", - "\n", - "- Enable setting the Python `ChartJS.object` parameter to any ChartJS dictionary.\n", - "- Checkout support for different sizing modes, responsiveness and window maximize.\n", - "- Configure the javascript, css, .. dependencies in the Bokeh Python File.\n", - "- ....." - ] - }, - { - "cell_type": "markdown", - "id": "middle-nelson", - "metadata": {}, - "source": [ - "## Check List\n", - "\n", - "When you develop and test your model eventually you should consider implementing and testing\n", - "\n", - "- Dynamic updates to the `object` parameter and any other parameters added.\n", - "- Resizing\n", - " - Does it resize when `width` is changed dynamically?\n", - " - Does it resize when `height` is changed dynamically?\n", - " - Does it work with `sizing_mode=\"stretch_width\"` etc.\n", - "- Themes (Light, Dark)\n", - "- Window Resizing, Window Maximizing, Window Minimizing.\n", - "- Streaming of Data. Is it efficient?\n", - "- Events (Click, Hover etc.)\n", - "- Consider supporting the Python Wrapper (ECharts -> PyECharts, ChartJS -> [PyChart.JS](https://pypi.org/project/pyChart.JS/))\n", - "- Tests\n", - "- Reference Notebook\n", - "- Communication also to for example ChartJS community and developers." - ] - }, - { - "cell_type": "markdown", - "id": "invisible-physics", - "metadata": {}, - "source": [ - "## Tips and Tricks\n", - "\n", - "- Work in small increments and stage your changes when they work\n", - "- Remember to `panel build panel` and hard refresh before you test.\n", - "- Add [console.log](https://www.w3schools.com/jsref/met_console_log.asp) statements to your `.ts` code for debugging.\n", - "- Use the [*Developer Tools*](https://developers.google.com/web/tools/chrome-devtools) *console* to see the `console.log` output and identify errors. In my browsers I toggle the Developer Tools using `CTRL+SHIFT+I`.\n", - "- Find inspiration for next steps in the [existing Panel Custom Models](https://github.com/holoviz/panel/tree/main/panel/models). For `ChartJS` one of the most relevant custom models would be `Echarts`. See Panel [echarts.py](https://github.com/holoviz/panel/blob/main/panel/pane/echarts.py), Bokeh [echarts.py](https://github.com/holoviz/panel/blob/main/panel/models/echarts.py) and [echarts.ts](https://github.com/holoviz/panel/blob/main/panel/models/echarts.ts).\n", - "- Use the existing documentation\n", - " - [Panel - Developer Guide](https://panel.holoviz.org/developer_guide/index.html)\n", - " - [Bokeh - Extending Bokeh](https://docs.bokeh.org/en/latest/docs/user_guide/extensions.html)\n", - "- Use Google Search. You don't have to be an expert javascript or typescript developer. It's a very small subset of those languages that is used when developing Custom Models.\n", - "- Ask for help in [Discord](https://discord.gg/rb6gPXbdAr), [HoloViz Discourse](https://discourse.holoviz.org/) and [Bokeh Discourse](https://discourse.bokeh.org/) forums." - ] - } - ], - "metadata": { - "language_info": { - "name": "python", - "pygments_lexer": "ipython3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 1398221813a939c79efad3bfa64425e40a587f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 13 May 2024 13:37:50 +0200 Subject: [PATCH 129/130] Fix root directory for hatch_build.py --- hatch_build.py | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hatch_build.py b/hatch_build.py index 380db12923..37bb8f072c 100644 --- a/hatch_build.py +++ b/hatch_build.py @@ -9,7 +9,7 @@ from hatchling.builders.hooks.plugin.interface import BuildHookInterface -BASE_DIR = Path(__file__).parents[1] +BASE_DIR = Path(__file__).parent GREEN, RED, RESET = "\033[92m", "\033[91m", "\033[0m" diff --git a/pyproject.toml b/pyproject.toml index c363e0fc67..60b444c786 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -171,6 +171,7 @@ unfixable = [ "panel/io/convert.py" = ["T201"] "panel/pane/vtk/synchronizable_*.py" = ["T201"] "scripts/*.py" = ["T201"] +"hatch_build.py" = ["T201"] [tool.isort] force_grid_wrap = 4 From 7ab9403d7b1e5f848dfa7ada62010356f9b192ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 13 May 2024 13:55:13 +0200 Subject: [PATCH 130/130] Add hook back in Pyproject.toml --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 60b444c786..22108c701b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -113,6 +113,9 @@ include = ["panel", "scripts", "examples"] [tool.hatch.build.hooks.vcs] version-file = "panel/_version.py" +[tool.hatch.build.hooks.custom] +path = 'hatch_build.py' + [tool.ruff] exclude = [ ".git",