import json
import os
import pathlib
from typing import Any
import param
param.parameterized.docstring_signature = False
param.parameterized.docstring_describe_params = False
from nbsite.shared_conf import *
project = 'Panel'
authors = 'Panel contributors'
copyright_years['start_year'] = '2019'
copyright = copyright_fmt.format(**copyright_years)
description = 'High-level dashboarding for python visualization libraries'
import panel
from panel.io.convert import (
BOKEH_VERSION, MINIMUM_VERSIONS, PY_VERSION, PYODIDE_VERSION,
PYSCRIPT_VERSION,
)
from panel.io.resources import CDN_ROOT
PANEL_ROOT = pathlib.Path(panel.__file__).parent
version = release = base_version(panel.__version__)
js_version = json.loads((PANEL_ROOT / 'package.json').read_text())['version']
is_dev = any(ext in version for ext in ('a', 'b', 'rc'))
os.environ['BRANCH'] = f"v{release}"
html_static_path += ['_static']
html_css_files += [
'css/custom.css',
]
html_theme = "pydata_sphinx_theme"
html_favicon = "_static/icons/favicon.ico"
current_release = panel.__version__
announcement_text = f"Panel {current_release} has just been released! Check out the <a href='https://panel.holoviz.org/about/releases.html'>release notes</a> and support Panel by giving it a 🌟 on <a href='https://github.com/holoviz/panel'>Github</a>."
html_theme_options = {
"logo": {
"image_light": "_static/logo_horizontal_light_theme.png",
"image_dark": "_static/logo_horizontal_dark_theme.png",
},
"github_url": "https://github.com/holoviz/panel",
"icon_links": [
{
"name": "Twitter",
"url": "https://twitter.com/Panel_Org",
"icon": "fa-brands fa-twitter-square",
},
{
"name": "Discourse",
"url": "https://discourse.holoviz.org/c/panel/5",
"icon": "fa-brands fa-discourse",
},
{
"name": "Discord",
"url": "https://discord.gg/UXdtYyGVQX",
"icon": "fa-brands fa-discord",
},
],
"pygments_light_style": "material",
"pygments_dark_style": "material",
"header_links_before_dropdown": 5,
'secondary_sidebar_items': [
"github-stars-button",
"panelitelink",
"page-toc",
],
"announcement": announcement_text,
}
extensions = [
'numpydoc',
'bokeh.sphinxext.bokeh_plot',
'myst_parser',
'sphinx_design',
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.coverage',
'sphinx.ext.mathjax',
'sphinx.ext.ifconfig',
'sphinx.ext.linkcode',
'sphinx.ext.inheritance_diagram',
'sphinx_copybutton',
'sphinxext.rediraffe',
'nbsite.gallery',
'nbsite.pyodide',
'nbsite.analytics',
]
numpydoc_show_inherited_class_members = False
numpydoc_class_members_toctree = False
napoleon_numpy_docstring = True
autodoc_mock_imports = ["panel.pane.vtk"]
myst_enable_extensions = ["colon_fence", "deflist"]
gallery_endpoint = 'panel-gallery-dev' if is_dev else 'panel-gallery'
gallery_url = f'https://{gallery_endpoint}.holoviz-demo.anaconda.com'
jlite_url = 'https://holoviz-dev.github.io/panelite-dev/lab' if is_dev else 'https://panelite.holoviz.org/lab'
pyodide_url = 'https://holoviz-dev.github.io/panel/pyodide' if is_dev else 'https://panel.holoviz.org/pyodide'
rediraffe_redirects = {
'developer_guide/testing': 'developer_guide/index',
'user_guide/APIs': 'explanation/api/index',
'user_guide/Pipelines': 'how_to/pipeline/index',
'user_guide/Templates': 'how_to/templates/index',
'user_guide/Server_Configuration': 'how_to/server/index',
}
nbsite_analytics = {
'goatcounter_holoviz': True,
}
nbsite_gallery_conf = {
'github_org': 'holoviz',
'github_project': 'panel',
'galleries': {
'reference': {
'title': 'Component Gallery',
'extensions': ['*.ipynb', '*.py', '*.md'],
'sections': [
'panes',
'widgets',
'layouts',
'chat',
'global',
'indicators',
'templates',
'custom_components',
],
'titles': {
'Vega': 'Altair & Vega',
'DeckGL': 'PyDeck & Deck.gl',
'ECharts': 'PyEcharts & ECharts',
'IPyWidget': 'ipywidgets',
'PanelCallbackHandler': 'LangChain CallbackHandler',
},
'as_pyodide': True,
'normalize_titles': False,
}
},
'thumbnail_url': 'https://assets.holoviz.org/panel/thumbnails',
'deployment_url': gallery_url,
'jupyterlite_url': jlite_url,
'only_use_existing': True,
}
if panel.__version__ != version and (PANEL_ROOT / 'dist' / 'wheels').is_dir():
py_version = panel.__version__.replace("-dirty", "")
panel_req = f'./wheels/panel-{py_version}-py3-none-any.whl'
bokeh_req = f'./wheels/bokeh-{BOKEH_VERSION}-py3-none-any.whl'
else:
panel_req = f'{CDN_ROOT}wheels/panel-{PY_VERSION}-py3-none-any.whl'
bokeh_req = f'{CDN_ROOT}wheels/bokeh-{BOKEH_VERSION}-py3-none-any.whl'
def get_requirements():
with open('pyodide_dependencies.json') as deps:
dependencies = json.load(deps)
requirements = {}
for src, deps in dependencies.items():
if deps is None:
continue
src = src.replace('.ipynb', '').replace('.md', '')
for name, min_version in MINIMUM_VERSIONS.items():
if any(name in req for req in deps):
deps = [f'{name}>={min_version}' if name in req else req for req in deps]
requirements[src] = deps
return requirements
html_js_files = [
(None, {'body': '{"shimMode": true}', 'type': 'esms-options'}),
f'https://cdn.holoviz.org/panel/{js_version}/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js',
]
nbsite_pyodide_conf = {
'PYODIDE_URL': f'https://cdn.jsdelivr.net/pyodide/{PYODIDE_VERSION}/full/pyodide.js',
'requirements': [bokeh_req, panel_req, 'pyodide-http'],
'requires': get_requirements(),
}
templates_path += [
'_templates'
]
html_context.update({
"last_release": f"v{release}",
"github_user": "holoviz",
"github_repo": "panel",
"default_mode": "light",
"panelite_endpoint": jlite_url,
"gallery_url": gallery_url,
"pyodide_url": pyodide_url
})
nbbuild_patterns_to_take_along = ["simple.html", "*.json", "json_*"]
html_title = f'{project} v{version}'
if is_dev:
version = panel.__version__
from sphinx_design.cards import CardDirective
from sphinx_design.grids import GridItemCardDirective
orig_grid_run = GridItemCardDirective.run
def patched_grid_run(self):
app = self.state.document.settings.env.app
existing_link = self.options.get('link')
domain = getattr(app.config, 'grid_item_link_domain', None)
if self.has_content:
self.content.replace('|gallery-endpoint|', domain)
if existing_link and domain:
new_link = existing_link.replace('|gallery-endpoint|', domain)
self.options['link'] = new_link
return list(orig_grid_run(self))
GridItemCardDirective.run = patched_grid_run
orig_card_run = CardDirective.run
def patched_card_run(self):
app = self.state.document.settings.env.app
existing_link = self.options.get('link')
domain = getattr(app.config, 'grid_item_link_domain', None)
if existing_link and domain:
new_link = existing_link.replace('|gallery-endpoint|', domain)
self.options['link'] = new_link
return orig_card_run(self)
CardDirective.run = patched_card_run
def _get_pyodide_version():
if PYODIDE_VERSION.startswith("v"):
return PYODIDE_VERSION[1:]
raise NotImplementedError(F"{PYODIDE_VERSION=} is not valid")
def update_versions(app, docname, source):
from panel.models.tabulator import TABULATOR_VERSION
from panel.models.vizzu import VIZZU_VERSION
version_replace = {
"{{PANEL_VERSION}}" : PY_VERSION,
"{{BOKEH_VERSION}}" : BOKEH_VERSION,
"{{PYSCRIPT_VERSION}}" : PYSCRIPT_VERSION,
"{{PYODIDE_VERSION}}" : _get_pyodide_version(),
"{{TABULATOR_VERSION}}" : TABULATOR_VERSION,
"{{TABULATOR_VERSION_WWW}}" : ".".join(TABULATOR_VERSION.split(".")[:2]),
"{{VIZZU_VERSION}}" : VIZZU_VERSION,
}
for old, new in version_replace.items():
source[0] = source[0].replace(old, new)
def setup_mystnb(app):
from myst_nb.core.config import NbParserConfig
from myst_nb.sphinx_ import (
HideCodeCellNode, HideInputCells, SelectMimeType,
)
from myst_nb.sphinx_ext import create_mystnb_config
_UNSET = "--unset--"
for name, default, field in NbParserConfig().as_triple():
if not field.metadata.get("sphinx_exclude"):
app.add_config_value(f"nb_{name}", default, "env", Any)
if "legacy_name" in field.metadata:
app.add_config_value(
f"{field.metadata['legacy_name']}",
_UNSET,
"env",
Any,
)
app.add_config_value("nb_render_priority", _UNSET, "env", Any)
create_mystnb_config(app)
app.add_post_transform(SelectMimeType)
app.add_post_transform(HideInputCells)
HideCodeCellNode.add_to_app(app)
def setup(app) -> None:
try:
from nbsite.paramdoc import param_formatter, param_skip
app.connect('autodoc-process-docstring', param_formatter)
app.connect('autodoc-skip-member', param_skip)
except ImportError:
print('no param_formatter (no param?)')
app.connect('builder-inited', setup_mystnb)
app.connect('source-read', update_versions)
nbbuild.setup(app)
app.add_config_value('grid_item_link_domain', '', 'html')
app.add_config_value('nbsite_hv_sidebar_dropdown', {}, 'html')
app.connect("html-page-context", add_hv_sidebar_dropdown_context)
grid_item_link_domain = gallery_endpoint