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

mkdocs serve command fails can't find module specified in :module: attribute #46

Open
prowler0305 opened this issue Nov 20, 2021 · 6 comments

Comments

@prowler0305
Copy link

Description

I am getting a ModuleNotFoundError exception thrown when trying to start the mkdocs serve development server and even trying to do mkdocs build.

I'm not sure why it can't find my module called open_bandage as I understand it uses relative path finding and I'm executing the mkdocs serve command from my overall Intellij directory. (i.e. same level as my docs, mkdocs.yml, etc.)

ERROR   -  Error reading page 'index.md': No module named 'open_bandage'
Traceback (most recent call last):
  File "/home/aspea002/miniconda3/envs/open_bandage/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs/__main__.py", line 136, in serve_command
    **kwargs
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs/commands/serve.py", line 141, in serve
    config = builder()
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs/commands/serve.py", line 136, in builder
    build(config, live_server=live_server, dirty=dirty)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs/commands/build.py", line 271, in build
    _populate_page(file.page, config, files, dirty)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs/commands/build.py", line 171, in _populate_page
    page.render(config, files)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs/structure/pages.py", line 175, in render
    self.content = md.convert(self.markdown)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/markdown/core.py", line 261, in convert
    self.lines = prep.run(self.lines)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs_click/_extension.py", line 46, in run
    replace=lambda **options: replace_command_docs(has_attr_list=self._has_attr_list, **options),
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs_click/_processing.py", line 35, in replace_blocks
    yield from replace(**options)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs_click/_extension.py", line 46, in <lambda>
    replace=lambda **options: replace_command_docs(has_attr_list=self._has_attr_list, **options),
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs_click/_extension.py", line 27, in replace_command_docs
    command_obj = load_command(module, command)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs_click/_loader.py", line 15, in load_command
    command = _load_obj(module, attribute)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/site-packages/mkdocs_click/_loader.py", line 25, in _load_obj
    mod = importlib.import_module(module)
  File "/home/aspea002/miniconda3/envs/open_bandage/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 965, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'open_bandage'

mkdocs.yml

site_name: Open Bandage
site_author: 'Andrew Spear'
site_url: 'https://xxxxxxxxxxxxxxxxxxxx'
theme:
  name: 'material'
  palette:
    # Light mode
    - media: "(prefers-color-scheme: light)"
      scheme: default
      primary: light green
      accent: deep orange
      toggle:
        icon: material/weather-night
        name: Switch to dark mode
    # Dark Mode
    - media: "(prefers-color-scheme: dark)"
      scheme: slate
      primary: deep orange
      accent: lime
      toggle:
        icon: material/weather-sunny
        name: Switch to light mode
  icon:
    logo: material/bandage
  favicon: images/uscc_logo.png
  features:
    - navigation.tabs
    - navigation.sections
    - navigation.top
#    - toc.integrate
markdown_extensions:
  - admonition
  - pymdownx.highlight:
      linenums: true
  - pymdownx.inlinehilite
  - pymdownx.superfences
  - pymdownx.smartsymbols
  - pymdownx.details
  - pymdownx.caret
  - pymdownx.mark
  - pymdownx.tilde
  - pymdownx.betterem:
      smart_enable: all
  - def_list
  - pymdownx.emoji:
      emoji_index: !!python/name:materialx.emoji.twemoji
      emoji_generator: !!python/name:materialx.emoji.to_svg
  - pymdownx.tabbed
  - attr_list
  - mkdocs-click
  - toc:
      toc_depth: 4
nav:
  - Home: index.md
  - Developer Info: development.md

index.md

::: mkdocs-click
    :module: open_bandage.scripts.cli
    :command: cli
    :prog_name: openbandage
    :depth: 2
    :style: table

Project Directory structure

image

@fernandascovino
Copy link

fernandascovino commented Nov 26, 2021

Hi! Same issue here, from project basedosdados:

project structure:

python-package:
  - basedosdados
    - cli
       - cli.py
docs:
  - reference_api_cli.md

reference_api_cli.md

# Linha de comando (CLI)

::: mkdocs-click
    :module: python-package.basedosdados.cli.cli
    :command: dataset

$ mkdocs serve:

ERROR    -  Error reading page 'reference_api_cli.md': No module named 'python-package'
Traceback (most recent call last):
  File "/Users/fernandascovino/Projects/mais/.mais/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/click/core.py", line 1128, in __call__
    return self.main(*args, **kwargs)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/click/core.py", line 1053, in main
    rv = self.invoke(ctx)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/click/core.py", line 1659, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/click/core.py", line 1395, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/click/core.py", line 754, in invoke
    return __callback(*args, **kwargs)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs/__main__.py", line 177, in serve_command
    serve.serve(dev_addr=dev_addr, livereload=livereload, **kwargs)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs/commands/serve.py", line 54, in serve
    config = builder()
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs/commands/serve.py", line 49, in builder
    build(config, live_server=live_server, dirty=dirty)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs/commands/build.py", line 292, in build
    _populate_page(file.page, config, files, dirty)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs/commands/build.py", line 174, in _populate_page
    page.render(config, files)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs/structure/pages.py", line 174, in render
    self.content = md.convert(self.markdown)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/markdown/core.py", line 261, in convert
    self.lines = prep.run(self.lines)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs_click/_extension.py", line 48, in run
    return list(
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs_click/_processing.py", line 35, in replace_blocks
    yield from replace(**options)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs_click/_extension.py", line 52, in <lambda>
    replace=lambda **options: replace_command_docs(has_attr_list=self._has_attr_list, **options),
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs_click/_extension.py", line 28, in replace_command_docs
    command_obj = load_command(module, command)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs_click/_loader.py", line 15, in load_command
    command = _load_obj(module, attribute)
  File "/Users/fernandascovino/Projects/mais/.mais/lib/python3.9/site-packages/mkdocs_click/_loader.py", line 25, in _load_obj
    mod = importlib.import_module(module)
  File "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  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 'python-package'

Additionally, when I tried #37 solution (change from mkdocs-click to mkdocs_click) it doesn't give any error but also nothing shows up.

image

@ofek
Copy link
Collaborator

ofek commented Nov 29, 2021

Hello! Have you both installed your package into the same environment as mkdocs?

@NBStephens
Copy link

I have the same error and I can't even get the example to run properly with fresh environments containing only the needed libraries.

I have tried it on Windows, and Ubuntu with Python 3.8 and 3.9.

Some strange behavior occurs if I paste in the examples to new Scripts I will get a page with no information beyond the Markdown references:

INFO     -  Building documentation...
INFO     -  [10:54:08] Reloading browsers
INFO     -  [10:54:08] Browser connected: http://127.0.0.1:8000/cli/
INFO     -  [10:54:08] Browser connected: http://127.0.0.1:8000/cli/
INFO     -  [10:54:08] Browser connected: http://127.0.0.1:8000/cli/
INFO     -  [10:55:38] Browser connected: http://127.0.0.1:8000/cli/
WARNING  -  [10:55:40] "GET / HTTP/1.1" code 404
INFO     -  [10:55:41] Browser connected: http://127.0.0.1:8000/cli/

But, if I hit return and save the cli.md it will crash and give the No module named 'app' error:

    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'app'

@fernandascovino
Copy link

fernandascovino commented Feb 23, 2022

SOLVED! 🎉

Tricky one. I was passing the group name as the command value, so it didn't recognized it.

After changing it to the [name].command() it worked.

To illustrate:

cli.py

@click.group(name="dataset") ==> I was using "dataset" on :command: 
@click.pass_context
def cli_dataset(ctx):
    pass

@cli_dataset.command(name="init", help="...") ==> But I actually needed to pass "cli_dataset"
@click.argument("dataset_id")
@click.option(
    "--replace",
    is_flag=True,
    help="Whether to replace current metadata files",
)

.md

# Linha de comando (CLI)

::: mkdocs_click
    :module: basedosdados.cli.cli ==> I also removed the `python-package`path here and put it on the .yml
    :command: cli_dataset
    :depth: 1

PS: I also changed mkdocs-click to mkdocs_click on mkdocs.yml and requirements.txt

All the changes made are here: https://github.com/basedosdados/mais/pull/1134/files

@miketheartguy
Copy link

miketheartguy commented May 12, 2022

I was able to resolve only by setting PYTHONPATH: PYTHONPATH=$PWD mkdocs build

Without setting it, I'll get ModuleNotFoundError: No module named 'app'

I've been able to replicate on a new python project:

.
├── app.py
├── docs
│   └── index.md
└── mkdocs.yml

mkdocs.yml:

site_name: My Docs

markdown_extensions:
    - mkdocs-click

app.py

import click

@click.group()
def cli():
    """Main entrypoint."""
    pass

@cli.command()
@click.option("-d", "--debug", help="Include debug output.")
def build(debug):
    """Build production assets."""
    pass

docs\index.md

::: mkdocs-click
    :module: app
    :command: cli

@jackblk
Copy link

jackblk commented Oct 12, 2022

Setting PYTHONPATH helps, but if I don't use relative import then it will cause ModuleNotFoundError as well.

For example:

Structure

.
├── app.py
├── config.py
│   └── docs
│       └── index.md
└── mkdocs.yml

app.py

import click
from config import Config

@click.group()
def cli():
    """Main entrypoint."""
    Config.get_env()
    pass

@cli.command()
@click.option("-d", "--debug", help="Include debug output.")
def build(debug):
    """Build production assets."""
    pass

If I do from .config import Config then it will be okay. Is there any way to fix this?

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

6 participants