Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converted panel does not work (after updates?) #5037

Closed
mtyszler opened this issue Jun 5, 2023 · 3 comments
Closed

Converted panel does not work (after updates?) #5037

mtyszler opened this issue Jun 5, 2023 · 3 comments

Comments

@mtyszler
Copy link

mtyszler commented Jun 5, 2023

ALL software version info

Package Version


aiofiles 22.1.0
aiohttp 3.8.4
aiosignal 1.3.1
aiosqlite 0.18.0
anyio 3.6.2
argon2-cffi 21.3.0
argon2-cffi-bindings 21.2.0
arrow 1.2.3
asttokens 2.2.1
async-timeout 4.0.2
attrs 22.2.0
auto-mix-prep 0.2.0
Babel 2.12.1
backcall 0.2.0
beautifulsoup4 4.12.0
bleach 6.0.0
bokeh 3.1.1
certifi 2022.12.7
cffi 1.15.1
charset-normalizer 3.1.0
colorama 0.4.6
comm 0.1.3
contourpy 1.0.7
debugpy 1.6.6
decorator 5.1.1
defusedxml 0.7.1
docopt 0.6.2
et-xmlfile 1.1.0
executing 1.2.0
fastjsonschema 2.16.3
fqdn 1.5.1
frozenlist 1.3.3
idna 3.4
ipykernel 6.22.0
ipython 8.12.0
ipython-genutils 0.2.0
isoduration 20.11.0
jedi 0.18.2
Jinja2 3.1.2
json5 0.9.11
jsonpointer 2.3
jsonschema 4.17.3
jupyter_client 8.1.0
jupyter_core 5.3.0
jupyter-events 0.6.3
jupyter_server 2.5.0
jupyter_server_fileid 0.8.0
jupyter_server_terminals 0.4.4
jupyter_server_ydoc 0.8.0
jupyter-ydoc 0.2.3
jupyterlab 3.6.3
jupyterlab-pygments 0.2.2
jupyterlab_server 2.22.0
linkify-it-py 2.0.2
Markdown 3.4.3
markdown-it-py 2.2.0
MarkupSafe 2.1.2
matplotlib-inline 0.1.6
mdit-py-plugins 0.3.5
mdurl 0.1.2
mistune 2.0.5
multidict 6.0.4
nbclassic 0.5.4
nbclient 0.7.3
nbconvert 7.3.0
nbformat 5.8.0
nest-asyncio 1.5.6
notebook 6.5.3
notebook_shim 0.2.2
numpy 1.24.2
openpyxl 3.1.2
packaging 23.0
pandas 2.0.0
pandocfilters 1.5.0
panel 1.0.4
param 1.13.0
parso 0.8.3
pickleshare 0.7.5
Pillow 9.5.0
pip 23.0.1
pipreqs 0.4.11
platformdirs 3.2.0
prometheus-client 0.16.0
prompt-toolkit 3.0.38
psutil 5.9.4
pure-eval 0.2.2
pycparser 2.21
pyct 0.5.0
pydub 0.25.1
Pygments 2.14.0
pyrsistent 0.19.3
python-dateutil 2.8.2
python-json-logger 2.0.7
pytz 2023.3
pyviz-comms 2.2.1
pywin32 306
pywinpty 2.0.10
PyYAML 6.0
pyzmq 25.0.2
requests 2.28.2
rfc3339-validator 0.1.4
rfc3986-validator 0.1.1
Send2Trash 1.8.0
setuptools 65.6.3
six 1.16.0
sniffio 1.3.0
soupsieve 2.4
stack-data 0.6.2
terminado 0.17.1
tinycss2 1.2.1
tornado 6.2
tqdm 4.65.0
traitlets 5.9.0
typing_extensions 4.5.0
tzdata 2023.3
uc-micro-py 1.0.2
uri-template 1.2.0
urllib3 1.26.15
wcwidth 0.2.6
webcolors 1.13
webencodings 0.5.1
websocket-client 1.5.1
wheel 0.38.4
wincertstore 0.2
xyzservices 2023.5.0
y-py 0.5.9
yarg 0.1.9
yarl 1.8.2
ypy-websocket 0.8.2

Description of expected behavior and the observed behavior

A simple panel application, which works locally, does not work after panel convert. It seems that there is a conflict with the version of markdown-it-py installed by panel on pyodide

error on web app:

ValueError: Requested 'markdown-it-py<3.0.0,>=1.0.0', but markdown-it-py==3.0.0 is already installed

Complete, minimal, self-contained example code that reproduces the issue

script.py

import panel as pn
import panel


pn.panel("hello").servable()

converted with panel convert src/dashboard/script.py --to pyodide-worker --out public
resulting script.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Panel Application</title>
    <style>
      html, body {
        box-sizing: border-box;
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>

<style type="text/css">
:host(.pn-loading),
.pn-loading {
  overflow: hidden;
}

:host(.pn-loading):before,
.pn-loading:before {
  position: absolute;
  height: 100%;
  width: 100%;
  content: '';
  z-index: 1000;
  background-color: rgb(255, 255, 255, 0.5);
  border-color: lightgray;
  background-repeat: no-repeat;
  background-position: center;
  background-size: auto 50%;
  border-width: 1px;
  cursor: progress;
}

:host(.pn-loading) .pn-loading-msg,
.pn-loading .pn-loading-msg {
  position: absolute;
  top: 72%;
  font-size: 2em;
  color: black;
  width: 100%;
  text-align: center;
}


:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=");
  background-size: auto calc(min(50%, 400px));
}
</style><script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-3.1.1.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.1.1.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.1.1.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.1.1.min.js"></script>
<script type="text/javascript" src="https://cdn.holoviz.org/panel/1.0.4/dist/panel.min.js"></script>

<script type="text/javascript">
  Bokeh.set_log_level("info");
</script>  </head>
  <body class="pn-loading pn-arc">
    <div id="d7e4755c-bb6b-4c2e-9da6-74610d5e1d60" data-root-id="p1005" style="display: contents;"></div>
  <div id="ebd027d5-0f74-4c89-ba06-a1d99d2bf795" data-root-id="p1006" style="display: contents;"></div>
  <div id="d825f0c1-b9d2-42fb-9ae9-f40cce4ec1e7" data-root-id="p1007" style="display: contents;"></div>
  
    <script type="text/javascript">
      const pyodideWorker = new Worker("./script.js");
      pyodideWorker.busy = false
      pyodideWorker.queue = []
      
      function send_change(jsdoc, event) {
        if (event.setter_id != null && event.setter_id == 'py') {
          return
        } else if (pyodideWorker.busy && event.model && event.attr) {
          let events = []
          for (const old_event of pyodideWorker.queue) {
            if (!(old_event.model === event.model && old_event.attr === event.attr)) {
              events.push(old_event)
            }
          }
          events.push(event)
          pyodideWorker.queue = events
          return
        }
        const patch = jsdoc.create_json_patch([event])
        pyodideWorker.busy = true
        pyodideWorker.postMessage({type: 'patch', patch: patch})
      }
      
      pyodideWorker.onmessage = async (event) => {
        const msg = event.data
      
        const body = document.getElementsByTagName('body')[0]
        const loading_msgs = document.getElementsByClassName('pn-loading-msg')
        if (msg.type === 'idle') {
          if (pyodideWorker.queue.length) {
            const patch = pyodideWorker.jsdoc.create_json_patch(pyodideWorker.queue)
            pyodideWorker.busy = true
            pyodideWorker.queue = []
            pyodideWorker.postMessage({type: 'patch', patch: patch})
          } else {
            pyodideWorker.busy = false
          }
        } else if (msg.type === 'status') {
          let loading_msg
          if (loading_msgs.length) {
            loading_msg = loading_msgs[0]
          } else if (body.classList.contains('pn-loading')) {
            loading_msg = document.createElement('div')
            loading_msg.classList.add('pn-loading-msg')
            body.appendChild(loading_msg)
          }
          if (loading_msg != null) {
            loading_msg.innerHTML = msg.msg
          }
        } else if (msg.type === 'render') {
          const docs_json = JSON.parse(msg.docs_json)
          const render_items = JSON.parse(msg.render_items)
          const root_ids = JSON.parse(msg.root_ids)
      
          // Remap roots in message to element IDs
          const root_els = document.querySelectorAll('[data-root-id]')
          const data_roots = []
          for (const el of root_els) {
             el.innerHTML = ''
             data_roots.push([el.getAttribute('data-root-id'), el.id])
          }
          data_roots.sort((a, b) => a[0]<b[0] ? -1: 1)
          const roots = {}
          for (let i=0; i<data_roots.length; i++) {
            roots[root_ids[i]] = data_roots[i][1]
          }
          render_items[0]['roots'] = roots
          render_items[0]['root_ids'] = root_ids
      
          // Embed content
          const [views] = await Bokeh.embed.embed_items(docs_json, render_items)
      
          // Remove loading spinner and message
          body.classList.remove("pn-loading", "arc")
          for (const loading_msg of loading_msgs) {
            loading_msg.remove()
          }
      
          // Setup bi-directional syncing
          pyodideWorker.jsdoc = jsdoc = [...views.roots.values()][0].model.document
          jsdoc.on_change(send_change.bind(null, jsdoc), false)
          pyodideWorker.postMessage({'type': 'rendered'})
          pyodideWorker.postMessage({'type': 'location', location: JSON.stringify(window.location)})
        } else if (msg.type === 'patch') {
          pyodideWorker.jsdoc.apply_json_patch(msg.patch, msg.buffers, setter_id='py')
        }
      };
    </script>
    <script type="application/json" id="p1008">
      {"6bcf3ae9-2151-4cec-94f0-d381ae4cb711":{"version":"3.1.1","title":"Panel Application","defs":[{"type":"model","name":"ReactiveHTML1"},{"type":"model","name":"FlexBox1","properties":[{"name":"align_content","kind":"Any","default":"flex-start"},{"name":"align_items","kind":"Any","default":"flex-start"},{"name":"flex_direction","kind":"Any","default":"row"},{"name":"flex_wrap","kind":"Any","default":"wrap"},{"name":"justify_content","kind":"Any","default":"flex-start"}]},{"type":"model","name":"FloatPanel1","properties":[{"name":"config","kind":"Any","default":{"type":"map"}},{"name":"contained","kind":"Any","default":true},{"name":"position","kind":"Any","default":"right-top"},{"name":"offsetx","kind":"Any","default":null},{"name":"offsety","kind":"Any","default":null},{"name":"theme","kind":"Any","default":"primary"},{"name":"status","kind":"Any","default":"normalized"}]},{"type":"model","name":"GridStack1","properties":[{"name":"mode","kind":"Any","default":"warn"},{"name":"ncols","kind":"Any","default":null},{"name":"nrows","kind":"Any","default":null},{"name":"allow_resize","kind":"Any","default":true},{"name":"allow_drag","kind":"Any","default":true},{"name":"state","kind":"Any","default":[]}]},{"type":"model","name":"drag1","properties":[{"name":"slider_width","kind":"Any","default":5},{"name":"slider_color","kind":"Any","default":"black"},{"name":"value","kind":"Any","default":50}]},{"type":"model","name":"click1","properties":[{"name":"terminal_output","kind":"Any","default":""},{"name":"debug_name","kind":"Any","default":""},{"name":"clears","kind":"Any","default":0}]},{"type":"model","name":"FastWrapper1","properties":[{"name":"object","kind":"Any","default":null},{"name":"style","kind":"Any","default":null}]},{"type":"model","name":"NotificationAreaBase1","properties":[{"name":"position","kind":"Any","default":"bottom-right"},{"name":"_clear","kind":"Any","default":0}]},{"type":"model","name":"NotificationArea1","properties":[{"name":"notifications","kind":"Any","default":[]},{"name":"position","kind":"Any","default":"bottom-right"},{"name":"_clear","kind":"Any","default":0},{"name":"types","kind":"Any","default":[{"type":"map","entries":[["type","warning"],["background","#ffc107"],["icon",{"type":"map","entries":[["className","fas fa-exclamation-triangle"],["tagName","i"],["color","white"]]}]]},{"type":"map","entries":[["type","info"],["background","#007bff"],["icon",{"type":"map","entries":[["className","fas fa-info-circle"],["tagName","i"],["color","white"]]}]]}]}]},{"type":"model","name":"Notification","properties":[{"name":"background","kind":"Any","default":null},{"name":"duration","kind":"Any","default":3000},{"name":"icon","kind":"Any","default":null},{"name":"message","kind":"Any","default":""},{"name":"notification_type","kind":"Any","default":null},{"name":"_destroyed","kind":"Any","default":false}]},{"type":"model","name":"TemplateActions1","properties":[{"name":"open_modal","kind":"Any","default":0},{"name":"close_modal","kind":"Any","default":0}]},{"type":"model","name":"BootstrapTemplateActions1","properties":[{"name":"open_modal","kind":"Any","default":0},{"name":"close_modal","kind":"Any","default":0}]},{"type":"model","name":"MaterialTemplateActions1","properties":[{"name":"open_modal","kind":"Any","default":0},{"name":"close_modal","kind":"Any","default":0}]}],"roots":[{"type":"object","name":"panel.models.markup.HTML","id":"p1005","attributes":{"css_classes":["markdown"],"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n  background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n  background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1003","attributes":{"url":"https://cdn.holoviz.org/panel/1.0.4/dist/css/loading.css"}},{"type":"object","name":"ImportedStyleSheet","id":"p1004","attributes":{"url":"https://cdn.holoviz.org/panel/1.0.4/dist/css/markdown.css"}},{"type":"object","name":"ImportedStyleSheet","id":"p1001","attributes":{"url":"https://cdn.holoviz.org/panel/1.0.4/dist/bundled/theme/default.css"}},{"type":"object","name":"ImportedStyleSheet","id":"p1002","attributes":{"url":"https://cdn.holoviz.org/panel/1.0.4/dist/bundled/theme/native.css"}}],"margin":[5,10],"align":"start","text":"&amp;lt;p&amp;gt;hello&amp;lt;/p&amp;gt;\n"}},{"type":"object","name":"panel.models.location.Location","id":"p1006","attributes":{"name":"location","reload":false}},{"type":"object","name":"panel.models.browser.BrowserInfo","id":"p1007","attributes":{"name":"browser_info"}}],"callbacks":{"type":"map"}}}
    </script>
    <script type="text/javascript">
      (function() {
        const fn = function() {
          Bokeh.safely(function() {
            (function(root) {
              function embed_document(root) {
              const docs_json = document.getElementById('p1008').textContent;
              const render_items = [{"docid":"6bcf3ae9-2151-4cec-94f0-d381ae4cb711","roots":{"p1005":"d7e4755c-bb6b-4c2e-9da6-74610d5e1d60","p1006":"ebd027d5-0f74-4c89-ba06-a1d99d2bf795","p1007":"d825f0c1-b9d2-42fb-9ae9-f40cce4ec1e7"},"root_ids":["p1005","p1006","p1007"]}];
              root.Bokeh.embed.embed_items(docs_json, render_items);
              }
              if (root.Bokeh !== undefined) {
                embed_document(root);
              } else {
                let attempts = 0;
                const timer = setInterval(function(root) {
                  if (root.Bokeh !== undefined) {
                    clearInterval(timer);
                    embed_document(root);
                  } else {
                    attempts++;
                    if (attempts > 100) {
                      clearInterval(timer);
                      console.log("Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing");
                    }
                  }
                }, 10, root)
              }
            })(window);
          });
        };
        if (document.readyState != "loading") fn();
        else document.addEventListener("DOMContentLoaded", fn);
      })();
    </script>
  </body>
</html>

resulting script.js:

importScripts("https://cdn.jsdelivr.net/pyodide/v0.23.0/full/pyodide.js");

function sendPatch(patch, buffers, msg_id) {
  self.postMessage({
    type: 'patch',
    patch: patch,
    buffers: buffers
  })
}

async function startApplication() {
  console.log("Loading pyodide!");
  self.postMessage({type: 'status', msg: 'Loading pyodide'})
  self.pyodide = await loadPyodide();
  self.pyodide.globals.set("sendPatch", sendPatch);
  console.log("Loaded!");
  await self.pyodide.loadPackage("micropip");
  const env_spec = ['https://cdn.holoviz.org/panel/1.0.4/dist/wheels/bokeh-3.1.1-py3-none-any.whl', 'https://cdn.holoviz.org/panel/1.0.4/dist/wheels/panel-1.0.4-py3-none-any.whl', 'pyodide-http==0.2.1']
  for (const pkg of env_spec) {
    let pkg_name;
    if (pkg.endsWith('.whl')) {
      pkg_name = pkg.split('/').slice(-1)[0].split('-')[0]
    } else {
      pkg_name = pkg
    }
    self.postMessage({type: 'status', msg: `Installing ${pkg_name}`})
    try {
      await self.pyodide.runPythonAsync(`
        import micropip
        await micropip.install('${pkg}');
      `);
    } catch(e) {
      console.log(e)
      self.postMessage({
	type: 'status',
	msg: `Error while installing ${pkg_name}`
      });
    }
  }
  console.log("Packages loaded!");
  self.postMessage({type: 'status', msg: 'Executing code'})
  const code = `
  
import asyncio

from panel.io.pyodide import init_doc, write_doc

init_doc()

import panel as pn
import panel


pn.panel("hello").servable()

await write_doc()
  `

  try {
    const [docs_json, render_items, root_ids] = await self.pyodide.runPythonAsync(code)
    self.postMessage({
      type: 'render',
      docs_json: docs_json,
      render_items: render_items,
      root_ids: root_ids
    })
  } catch(e) {
    const traceback = `${e}`
    const tblines = traceback.split('\n')
    self.postMessage({
      type: 'status',
      msg: tblines[tblines.length-2]
    });
    throw e
  }
}

self.onmessage = async (event) => {
  const msg = event.data
  if (msg.type === 'rendered') {
    self.pyodide.runPythonAsync(`
    from panel.io.state import state
    from panel.io.pyodide import _link_docs_worker

    _link_docs_worker(state.curdoc, sendPatch, setter='js')
    `)
  } else if (msg.type === 'patch') {
    self.pyodide.globals.set('patch', msg.patch)
    self.pyodide.runPythonAsync(`
    state.curdoc.apply_json_patch(patch.to_py(), setter='js')
    `)
    self.postMessage({type: 'idle'})
  } else if (msg.type === 'location') {
    self.pyodide.globals.set('location', msg.location)
    self.pyodide.runPythonAsync(`
    import json
    from panel.io.state import state
    from panel.util import edit_readonly
    if state.location:
        loc_data = json.loads(location)
        with edit_readonly(state.location):
            state.location.param.update({
                k: v for k, v in loc_data.items() if k in state.location.param
            })
    `)
  }
}

startApplication()

served with python -m http.server

Stack traceback and/or browser JavaScript console output

ValueError: Requested 'markdown-it-py<3.0.0,>=1.0.0', but markdown-it-py==3.0.0 is already installed

Screenshots or screencasts of the bug in action

See:
image

@philippjfr
Copy link
Member

Thanks for reporting @mtyszler, this is a duplicate of #5034.

@mtyszler
Copy link
Author

mtyszler commented Jun 5, 2023

Ok, tks.

Btw, it worked locally indeed using this fix from 2112b44

image

@philippjfr
Copy link
Member

Really hoping they get a release out today so I don't have to release Panel with that pin in it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants