panel.pane.Markdown leads to ModuleNotFoundError: No module named 'extra'

148 views
Skip to first unread message

mdk

unread,
Apr 3, 2022, 10:16:57 AM4/3/22
to PyInstaller
Hi,

I am stuck with solving an ModuleNotFoundError when using a submodule panel.pane.Markdown.
My impression from the docs is, that this could be solved with hooks and / or hidden imports, but so far the error is still there.
Any hints or code snippets on how to solve this problem would be very welcome, thanks in advance.

I am using a current miniconda python on a windows machine.

Here is my code, unfortunaletely this minimal running example has still auite some lines of code.:

A) The application file, named "paneltest.py"
import panel as pn

if __name__ == '__main__':
    print('Panel Test with Markdown')

    # version a)
    # To see version a) in a webpage comment out version b)
    test = pn.widgets.TextInput(name='A widget', value='A string')

    # version b)
        # to see version a) comment out this line
    test = pn.pane.Markdown('#Test')

    # opens a page in your browser showing
    # a) an widget
    # or b) throws a ModuleNotFoundError
    server = test.show(threaded=False)

B) the specs-file, named "paneltest.spec"
# run at console in the directory e.g. with the following options
# pyinstaller -D -y paneltest.spec

from PyInstaller.utils.hooks import collect_submodules

block_cipher = None

# Change path to python version on your workstation
pypath = 'C:\\[your path]\\miniconda3\\'

# This does not solve the ModuleNotFoundError
hiddenimports_markdown = collect_submodules('markdown')

# 'markdown.extensions.extra' is among the collected submodules
print(hiddenimports_markdown)

a = Analysis(
     ['paneltest.py'],
     pathex=[
          'C:\\Users\\[your path]'],
     datas=[
          # some html and js files are needed, for simplicity all files are copied
          # for these modules, this approach worked solving issues
          (
               pypath + 'Lib\\site-packages\\pyviz_comms',
               'pyviz_comms'),
          (
               pypath + 'Lib\\site-packages\\bokeh',
               'bokeh'),
          (
               pypath + 'Lib\\site-packages\\panel',
               'panel'),

          # For this module copying all file does not solve the ModuleNotFoundError
          (
               pypath + 'Lib\\site-packages\\markdown',
               'markdown'),
          ],
     hiddenimports=hiddenimports_markdown,
     hookspath=[],
     runtime_hooks=[],
     excludes=[],
     win_no_prefer_redirects=False,
     win_private_assemblies=False,
     cipher=block_cipher,
     noarchive=False)

pyz = PYZ(
     a.pure,
     a.zipped_data,
     cipher=block_cipher)

exe = EXE(
     pyz,
     a.scripts,
     [],
     exclude_binaries=True,
     name='paneltest',
     debug=False,
     bootloader_ignore_signals=False,
     strip=False,
     upx=True,
     console=True )

coll = COLLECT(
     exe,
     a.binaries,
     a.zipfiles,
     a.datas,
     strip=False,
     upx=True,
     upx_exclude=[],
     name='paneltest')


C) Traceback when starting the application "paneltest.exe" in a terminal
Panel Test with Markdown
Launching server at http://localhost:64653
ERROR:tornado.application:Uncaught exception GET / (::1)
HTTPServerRequest(protocol='http', host='localhost:64653', method='GET', uri='/', version='HTTP/1.1', remote_ip='::1')
Traceback (most recent call last):
[...]
  File "panel\pane\markup.py", line 41, in _get_model
    model = self._bokeh_model(**self._get_properties())
  File "panel\pane\markup.py", line 296, in _get_properties
    html = markdown.markdown(data, extensions=self.extensions,
  File "markdown\core.py", line 386, in markdown
    md = Markdown(**kwargs)
  File "markdown\core.py", line 96, in __init__
    self.registerExtensions(extensions=kwargs.get('extensions', []),
  File "markdown\core.py", line 123, in registerExtensions
    ext = self.build_extension(ext, configs.get(ext, {}))
  File "markdown\core.py", line 162, in build_extension
    module = importlib.import_module(ext_name)
  File "importlib\__init__.py", line 127, in import_module
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 984, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'extra'
ERROR:tornado.access:500 GET / (::1) 160.90ms
WARNING:tornado.access:404 GET /favicon.ico (::1) 1.00ms



mdk

unread,
Apr 13, 2022, 7:33:04 AM4/13/22
to PyInstaller
I found a solution using hooks, as template I used this answer on stackoverflow:

In a subfolder 'hooks' I have now a file 'hook-markdown.py':
# copied from
# and modified

from PyInstaller.utils.hooks import collect_all

def hook(hook_api):
    packages = [
        'markdown'
    ]

    for package in packages:
        datas, binaries, hiddenimports = collect_all(package)
        hook_api.add_datas(datas)
        hook_api.add_binaries(binaries)
        hook_api.add_imports(*hiddenimports)

And in 'paneltest.spec' I removed everything related to hiddenimports, the Analysis part looks now like this:
a = Analysis(
     ['paneltest.py'],
     pathex=[
          'C:\\Users\\mdk\\Documents\\Buero\\lum\\lumilab'],

     datas=[
          # some html and js files are needed, for simplicity all files are copied
          # for these modules this approach worked solving issues

          (
               pypath + 'Lib\\site-packages\\pyviz_comms',
               'pyviz_comms'),
          (
               pypath + 'Lib\\site-packages\\bokeh',
               'bokeh'),
          (
               pypath + 'Lib\\site-packages\\panel',
               'panel'),
          ],
     hiddenimports=[],
     hookspath=['.\\hooks\\'],

     runtime_hooks=[],
     excludes=[],
     win_no_prefer_redirects=False,
     win_private_assemblies=False,
     cipher=block_cipher,
     noarchive=False)


I do not really understand why this hook is working, and the hiddenimport not, but anyway: I am glad it works now...
Reply all
Reply to author
Forward
0 new messages