backstage / mkdocs-techdocs-core

The core MkDocs plugin used by Backstage's TechDocs as a wrapper around multiple MkDocs plugins and Python Markdown extensions
Apache License 2.0
85 stars 61 forks source link

module 'pyparsing' has no attribute 'downcaseTokens' #43

Closed FilipSwiatczak closed 1 year ago

FilipSwiatczak commented 2 years ago

As of few days ago, my unchanged dockerfile for backstage started failing on all TechDoc page rendering. I have the mkdocs-techdocs-core 0.2.0 as part of my core backstage deployment. It throws:

ERROR    -  Error reading page 'index.md': module 'pyparsing' has no attribute 'downcaseTokens'
Traceback (most recent call last):
  File "/usr/local/bin/mkdocs", line 10, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 1128, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 1053, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 1659, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 1395, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 754, in invoke
    return __callback(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/mkdocs/__main__.py", line 187, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "/usr/local/lib/python3.7/dist-packages/mkdocs/commands/build.py", line 292, in build
    _populate_page(file.page, config, files, dirty)
  File "/usr/local/lib/python3.7/dist-packages/mkdocs/commands/build.py", line 174, in _populate_page
    page.render(config, files)
  File "/usr/local/lib/python3.7/dist-packages/mkdocs/structure/pages.py", line 172, in render
    extension_configs=config['mdx_configs'] or {}
  File "/usr/local/lib/python3.7/dist-packages/markdown/core.py", line 96, in __init__
    configs=kwargs.get('extension_configs', {}))
  File "/usr/local/lib/python3.7/dist-packages/markdown/core.py", line 122, in registerExtensions
    ext = self.build_extension(ext, configs.get(ext, {}))
  File "/usr/local/lib/python3.7/dist-packages/markdown/core.py", line 161, in build_extension
    module = importlib.import_module(ext_name)
  File "/usr/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

My dockerfile:

FROM node:14-buster-slim
WORKDIR /app

RUN apt update && apt install -y python3 python3-pip
RUN pip3 install mkdocs-techdocs-core==0.2.0

COPY yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./
RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz
RUN yarn install --frozen-lockfile --production --network-timeout 300000 && rm -rf "$(yarn cache dir)"
COPY packages/backend/dist/bundle.tar.gz app-config.yaml ./
RUN tar xzf bundle.tar.gz && rm bundle.tar.gz

RUN rm -rf /var/cache/apt/archives
CMD ["node", "packages/backend", "--config", "app-config.yaml"]

Exact same issue as in: #httplib2/httplib2/issues/207

If I pin down pyparsing like:

RUN pip3 install mkdocs-techdocs-core==0.2.0
RUN pip3 install pyparsing==2.4.7

Then it works again - but not for UML plugin, which starts to fail as below:

ERROR    -  Error reading page 'extensions.md': Failed to run plantuml: [Errno 2] No such file or directory: 'plantuml': 'plantuml'
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/plantuml_markdown.py", line 268, in _render_local_uml_image
    p = Popen(cmdline, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=(os.name == 'nt'))
  File "/usr/lib/python3.7/subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.7/subprocess.py", line 1522, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'plantuml': 'plantuml'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/local/bin/mkdocs", line 10, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 1128, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 1053, in main

It seems pyparsing has had this change: https://github.com/httplib2/httplib2/issues/207#issuecomment-951634566 which causes, or contributes to this!

iamEAP commented 2 years ago

Hmm... I'm seeing good luck after pinning pyparsing==2.4.7 as you've done, as long as I've also installed plantuml, e.g.

RUN curl -o plantuml.jar -L http://sourceforge.net/projects/plantuml/files/plantuml.1.2021.4.jar/download && echo "be498123d20eaea95a94b174d770ef94adfdca18  plantuml.jar" | sha1sum -c - && mv plantuml.jar /opt/plantuml.jar
RUN echo '#!/bin/sh\n\njava -jar '/opt/plantuml.jar' ${@}' >> /usr/local/bin/plantuml
iamEAP commented 2 years ago

Also adding notes from discord thread on the subject:

Just ran into this myself. Seems like it might be:

plantuml-markdown==3.4.2

plantuml-markdown, while pinned to a specific version in mkdocs-techdocs-core, plantuml-markdown does not pin their version of plantuml here: https://github.com/mikitex70/plantuml-markdown/blob/master/requirements.txt#L2

And plantuml does not pin a version of httplib2 here: https://github.com/dougn/python-plantuml/blob/master/requirements.txt#L2

Which I think takes us full circle back to that GitHub Issue that linked.

iamEAP commented 2 years ago

Note: if you bump to mkdocs-techdocs-core version 0.2.1, the pyparsing and slugify run-time errors should no longer be a problem.

Hopefully the underlying issue gets resolved and we can unpin pyparsing.

Will leave this open for a little bit in case others come looking for this.

FilipSwiatczak commented 2 years ago

hi @iamEAP thanks for that, can confirm 0.2.1 fixed the non-uml part again: RUN pip3 install mkdocs-techdocs-core==0.2.1 is all that's required again. Shame about the plantuml for the time being, plantuml-markdown doesn't seem to pick up despite being part of the mkdocs-techdocs-core.