luolingchun / flask-openapi3

Generate REST API and OpenAPI documentation for your Flask project.
https://luolingchun.github.io/flask-openapi3/
MIT License
203 stars 33 forks source link

Pyinstller build breaks docs #147

Closed cwilvx closed 8 months ago

cwilvx commented 8 months ago

Hello :wave:

I'm using flask-openapi3 to document api routes of a flask app which is distributed as a binary created by Pyinstaller. Pyinstaller bundles a Python application and all its dependencies into a single package.

When I run the application via python [...].py the docs work fine, but when I build the binary and go to the docs page, I get a broken page:

I don't know how the docs are generated, so I can't tell where the problem is.

Side thought

Pyinstaller compiles the python code into static library files (.so). If the docs generation happens by parsing python files, this might cause the issue.

Either way, is there a way to compile the docs into a static page? In my case, this would fix my problem as I'd setup a step to compile the docs before pyinstaller build and serve them as static assets in the final pyinstaller binary.

luolingchun commented 8 months ago

Pyinstaller does not copy the static resources of flask-openapi3 during the packaging process, so you need to copy them yourself.

Or use --add-data in Pyinstaller#cmdoption-add-data.

D:\workspace\flask-openapi3\examples\dist\simple_demo>dir /b
simple_demo.exe
_internal
D:\workspace\flask-openapi3\examples\dist\simple_demo>tree
D:.
└─_internal
    ├─flask-2.3.3.dist-info
+    ├─flask_openapi3
+    │  └─templates
+    │      └─static
+    │          ├─css
+    │          ├─images
+    │          └─js
    ├─importlib_metadata-6.8.0.dist-info
    ├─markupsafe
    ├─pydantic_core
    ├─werkzeug-3.0.0.dist-info
    └─yaml
cwilvx commented 8 months ago

Hello @luolingchun

Thanks for the swift reply. The template static files are found in $env-path/lib/python3.x/site-packages/flask_openapi3/templates on Linux.

I was able to get it working by copying the flask_openapi3/templates/static folder into the build using this spaghetti code:

import sys
import PyInstaller.__main__ as bundler

def getFlaskOpenApiPath():
    site_packages_path = [p for p in sys.path if "site-packages" in p][0]

    return f"{site_packages_path}/flask_openapi3"

flask_openapi_path = getFlaskOpenApiPath()
bundler.run(
    [
        "manage.py",
        "--onefile",
        # other stuff here
        f"--add-data={flask_openapi_path}/templates/static:flask_openapi3/templates/static"
    ]
)

[!TIP] You might want to edit the tree in your previous comment. It shows the flask_openapi3 folder is inside the flask dist info folder which had thrown me off at first.