Ranjith Ramachandra
Ranjith Ramachandra

Reputation: 10764

How to collect the static files for flask admin when using pyinstaller?

I have a flask project that uses flask admin.

I am packaging it using pyinstaller. I am doing the following to create my pyinstaller script

mkdir ./src/static
cp -r ./venv/lib/python3.8/site-packages/flasgger/ui2/templates/. ./src/templates
cp -r ./venv/lib/python3.8/site-packages/flask_admin/templates/. ./src/templates
cp -r ./venv/lib/python3.8/site-packages/flasgger/ui2/static/. ./src/static
cp -r ./venv/lib/python3.8/site-packages/flask_admin/static/. ./src/static
pyinstaller \
    --onefile \
    --add-data "./src/templates:templates" \
    --add-data "./src/static:static" \
    --add-data "./src/swagger:swagger" \
    --paths ".:./src/:./test:./venv" \
    ./src/app.py

my app.py does the following

    if getattr(sys, 'frozen', False):
        template_folder = os.path.join(sys._MEIPASS, 'templates')
        static_folder = os.path.join(sys._MEIPASS, 'static')
        app = Flask(__name__, template_folder=template_folder, static_folder=static_folder)
    else:
        app = Flask(__name__)

I see that the flasgger view and its static files are being served okay. However flask_admin static files are not getting served and are giving a 404 error.

What could be the reason?

Upvotes: 0

Views: 847

Answers (2)

Ajeeth B
Ajeeth B

Reputation: 3

When pyinstaller builds the application, It generally includes the files that are actually called.

In flask_admin, the static files are accessed from HTML file, in which pyinstaller recognize static files as unused file and it does not include it in the build file.

In such cases, you cannot import packages from site-packages.

you have to place the flask_admin package from where you run the application and import flask_admin from local.

For example: consider this app structure

project
   |--- app
         |--- __init__.py
         |--- ... (other files)
   |--- flask_admin
   |--- run.py

init.py

from flask import Flask
from flask_admin import Admin

def create_app():
    app = Flask(__name__)
    admin = Admin(app)
    ...
    ...
    return app

run.py

from app import creare_app

if __name__ == "__main__":
    app = create_app()
    app.run()

here:

  • The flask_admin should not be installed in the environment.
  • The flask_admin package should be placed where you run the app. (download flask_admin from git).
  • The entire flask_admin package should also be added while building the application using pyinstaller.

sample command :

pyinstaller --onedir --add-data "/dir/app;app/" --add-data "/dir/flask_admin;flask_admin/" run.py

You can find an example here

Upvotes: 0

user27678773
user27678773

Reputation: 1

Non technical oneliner that works on Windows with Python3.11:

pyinstaller --onefile --noconsole --collect-all flasgger your_app.py

Collects all of flasgger's dependencies which was causing me headaches.

Upvotes: 0

Related Questions