CoolFace
Apppublic

awesome-panel/caching_example

sourceHugging Facemitupdated 3y agoView on Hugging Face
0likes
index.js215 linesDownload Raw Back to root
1importScripts("https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js");2 3function sendPatch(patch, buffers, msg_id) {4  self.postMessage({5    type: 'patch',6    patch: patch,7    buffers: buffers8  })9}10 11async function startApplication() {12  console.log("Loading pyodide!");13  self.postMessage({type: 'status', msg: 'Loading pyodide'})14  self.pyodide = await loadPyodide();15  self.pyodide.globals.set("sendPatch", sendPatch);16  console.log("Loaded!");17  await self.pyodide.loadPackage("micropip");18  const env_spec = ['https://cdn.holoviz.org/panel/wheels/bokeh-3.3.2-py3-none-any.whl', 'https://cdn.holoviz.org/panel/1.3.6/dist/wheels/panel-1.3.6-py3-none-any.whl', 'pyodide-http==0.2.1', 'hvplot', 'numpy', 'pandas']19  for (const pkg of env_spec) {20    let pkg_name;21    if (pkg.endsWith('.whl')) {22      pkg_name = pkg.split('/').slice(-1)[0].split('-')[0]23    } else {24      pkg_name = pkg25    }26    self.postMessage({type: 'status', msg: `Installing ${pkg_name}`})27    try {28      await self.pyodide.runPythonAsync(`29        import micropip30        await micropip.install('${pkg}');31      `);32    } catch(e) {33      console.log(e)34      self.postMessage({35	type: 'status',36	msg: `Error while installing ${pkg_name}`37      });38    }39  }40  console.log("Packages loaded!");41  self.postMessage({type: 'status', msg: 'Executing code'})42  const code = `43  44import asyncio45 46from panel.io.pyodide import init_doc, write_doc47 48init_doc()49 50"""51# Caching Example52 53See https://awesome-panel.org/resources/caching_example54"""55import time56 57import hvplot.pandas  # pylint: disable=unused-import58import numpy as np59import pandas as pd60import panel as pn61 62pn.extension(design="material")63 64ACCENT_COLOR = "#1f77b4"65 66np.random.seed([3, 1415])67PERIODS = 1 * 24 * 60  # minutes. I.e. 1 days68DATA = pd.DataFrame(69    {70        "time": pd.date_range("2020-01-01", periods=PERIODS, freq="T"),71        "price": np.random.randn(PERIODS) + 98,72    }73)74 75def _load_data(frac=0.1):76    time.sleep(0.5 + frac * 0.5)77    return DATA.sample(frac=frac)78 79def _plot_data(frac=0.1):80    time.sleep(0.5)81    data = _load_data(frac)82    return data.hvplot(x="time", y="price")83 84@pn.cache(per_session=True, ttl=60*60*24)85def _plot_data_cached(frac):86    return _plot_data(frac)87 88 89# Create Widgets90fraction = pn.widgets.FloatSlider(value=0.1, start=0.1, end=1.0, step=0.1, name="Fraction of data")91duration = pn.widgets.StaticText(value="", name="Time to create plot")92use_cache = pn.widgets.Checkbox(value=False, name="Use Cache")93preload_cache = pn.widgets.Button(name="Preload Cache", button_type="primary", disabled=True)94clear_cache = pn.widgets.Button(name="Clear Cache", disabled=True)95preload_progress = pn.widgets.Progress(96    name="Progress", active=False, value=0, max=100, sizing_mode="stretch_width", disabled=True97)98 99plot_panel = pn.pane.HoloViews(min_height=500, sizing_mode="stretch_both")100 101# Setup interactivity102def _clear_cache(*_):103    _plot_data_cached.clear()104 105 106clear_cache.on_click(_clear_cache)107 108 109def _preload_cache(*_):110    for index in range(0, 11, 1):111        frac_ = round(index / 10, 1)112        preload_progress.value = int(frac_ * 100)113        _plot_data_cached(frac_)114    preload_progress.value = 0115 116 117preload_cache.on_click(_preload_cache)118 119 120@pn.depends(frac=fraction, watch=True)121def _update_plot(frac):122    start_counter = time.perf_counter()123 124    frac = round(frac, 1)125    if use_cache.value:126        plot = _plot_data_cached(frac)127    else:128        plot = _plot_data(frac)129 130    end_counter = time.perf_counter()131    duration.value = str(round(end_counter - start_counter, 4)) + " seconds"132 133    # Please note DiskCache does not cache the options134    plot.opts(color=ACCENT_COLOR, responsive=True)135    plot_panel.object = plot136 137 138@pn.depends(use_cache=use_cache, watch=True)139def _update_cache_widgets(use_cache):  # pylint: disable=redefined-outer-name140    disabled = not use_cache141    preload_cache.disabled = disabled142    clear_cache.disabled = disabled143    preload_progress.disabled = disabled144 145 146# Layout the app147pn.Column(148    pn.pane.Markdown(149        "# Speed up slow functions with caching", sizing_mode="stretch_width"150    ),151    fraction,152    duration,153    use_cache,154    plot_panel,155    pn.Row(preload_cache, clear_cache,),156    preload_progress,157).servable()158 159pn.state.onload(lambda: fraction.param.trigger("value"))160 161 162await write_doc()163  `164 165  try {166    const [docs_json, render_items, root_ids] = await self.pyodide.runPythonAsync(code)167    self.postMessage({168      type: 'render',169      docs_json: docs_json,170      render_items: render_items,171      root_ids: root_ids172    })173  } catch(e) {174    const traceback = `${e}`175    const tblines = traceback.split('\n')176    self.postMessage({177      type: 'status',178      msg: tblines[tblines.length-2]179    });180    throw e181  }182}183 184self.onmessage = async (event) => {185  const msg = event.data186  if (msg.type === 'rendered') {187    self.pyodide.runPythonAsync(`188    from panel.io.state import state189    from panel.io.pyodide import _link_docs_worker190 191    _link_docs_worker(state.curdoc, sendPatch, setter='js')192    `)193  } else if (msg.type === 'patch') {194    self.pyodide.globals.set('patch', msg.patch)195    self.pyodide.runPythonAsync(`196    state.curdoc.apply_json_patch(patch.to_py(), setter='js')197    `)198    self.postMessage({type: 'idle'})199  } else if (msg.type === 'location') {200    self.pyodide.globals.set('location', msg.location)201    self.pyodide.runPythonAsync(`202    import json203    from panel.io.state import state204    from panel.util import edit_readonly205    if state.location:206        loc_data = json.loads(location)207        with edit_readonly(state.location):208            state.location.param.update({209                k: v for k, v in loc_data.items() if k in state.location.param210            })211    `)212  }213}214 215startApplication()