servable panel app ModuleNotFoundError on included local module

208 views Asked by At

I'm having issues deploying my Panel app to be served up as HTML.

Following instructions at https://panel.holoviz.org/user_guide/Running_in_Webassembly.html, with script.py as

import panel as pn

from mymodule import MyObj

pn.extension('terminal', 'tabulator', sizing_mode="stretch_width")

gspec = pn.GridSpec(sizing_mode='stretch_width', max_height=100, ncols=3)
PI = MyObj()
gspec[0, 0:1] = PI.tabs
gspec[0, 2] = PI.view

pn.Column(
    "Text Text Text"
    , gspec
).servable()

and mymodule/__init__.py:

__version__ = '0.1.0'
from .my_obj import MyObj

and mymodule/my_obj.py:

from .param_classes import ClassA
from .param_classes import ClassB
# etc

from .compute_obj import ComputeObj

class MyObj(object):
    # all the details of the panel build, calling in turn  
    # param classes detailed in another file, and also calling another module
    # to handle all the computation behind the panel

panel serve script.py --autoreload works perfectly, but

$ panel convert script.py --to pyodide-worker --out pyodide
$ python3 -m http.server

does not work. I get a big display at http://localhost:8000/pyodide/script.html: ModuleNotFoundError: no module named 'mymodule', and an infinite loop spinning graphic, and in the Developer Tools Console output:

pyodide.asm.js:10 Uncaught (in promise) PythonError: Traceback (most recent call last):
  File "/lib/python3.10/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/lib/python3.10/asyncio/tasks.py", line 232, in __step
    result = coro.send(None)
  File "/lib/python3.10/site-packages/_pyodide/_base.py", line 506, in eval_code_async
    await CodeRunner(
  File "/lib/python3.10/site-packages/_pyodide/_base.py", line 359, in run_async
    await coroutine
  File "<exec>", line 11, in <module>
ModuleNotFoundError: No module named 'mymodule'

    at new_error (pyodide.asm.js:10:218123)
    at pyodide.asm.wasm:0xdef7c
    at pyodide.asm.wasm:0xe37ae
    at method_call_trampoline (pyodide.asm.js:10:218037)
    at pyodide.asm.wasm:0x126317
    at pyodide.asm.wasm:0x1f6f2e
    at pyodide.asm.wasm:0x161a32
    at pyodide.asm.wasm:0x126827
    at pyodide.asm.wasm:0x126921
    at pyodide.asm.wasm:0x1269c4
    at pyodide.asm.wasm:0x1e0697
    at pyodide.asm.wasm:0x1da6a5
    at pyodide.asm.wasm:0x126a07
    at pyodide.asm.wasm:0x1e248c
    at pyodide.asm.wasm:0x1e00d9
    at pyodide.asm.wasm:0x1da6a5
    at pyodide.asm.wasm:0x126a07
    at pyodide.asm.wasm:0xe347a
    at Module.callPyObjectKwargs (pyodide.asm.js:10:119064)
    at Module.callPyObject (pyodide.asm.js:10:119442)
    at wrapper (pyodide.asm.js:10:183746)

I should add that I'm using poetry to manage packages and build the venv, and I'm operating all the above from within the activated .venv (via poetry shell)

I've tried all the tips and tricks around append the local path to sys.path. Looking at the .js file that the convert utility generates, I gather it would work if all the code were in one file, but forcing bad coding practice doesn't sound right.

I imagine there could be some kind of C++ build-style --include argument to panel convert, but there are no man pages, and the closest I can get with online documentation is --requirements ./mymodule, but no joy.

Could anybody please advise?

1

There are 1 answers

0
DaveRGP On

Not got a 100 solution, but maybe an idea. This line Suggests that your local module is unsupported because it is local. If you can publish the module to PyPi it will be loaded FROM PyPi at run time.

This might be suitable for your needs, but maybe not. Good Luck :)