flask-assetswebassets

flask-assets append_path() catch-22


I have a package which contains static files I want to reuse among applications. Based on https://webassets.readthedocs.io/en/latest/environment.html#webassets.env.Environment.load_path I came up with the following code snippet, to be used in each application's __init__.py (the shared package is loutilities):

with app.app_context():
    # js/css files
    asset_env.append_path(app.static_folder)
    # os.path.split to get package directory
    asset_env.append_path(os.path.join(os.path.split(loutilities.__file__)[0], 'tables-assets', 'static'))

but when ASSETS_DEBUG = False, this causes a ValueError exception for one of the files found in the package. (See https://github.com/louking/rrwebapp/issues/366 for detailed traceback -- this is possibly related to https://github.com/miracle2k/webassets/issues/387).

ValueError: Cannot determine url for /var/www/sandbox.scoretility.com/rrwebapp/lib/python2.7/site-packages/loutilities/tables-assets/static/branding.css

Changed code to use a url parameter which now works fine for ASSETS_DEBUG = False

    asset_env.append_path(os.path.join(os.path.split(loutilities.__file__)[0], 'tables-assets', 'static'), '/loutilities')

however now when ASSETS_DEBUG = True, I see that the file failed to load in the javascript console

Failed to load resource: the server responded with a status of 404 (NOT FOUND) branding.css

Have worked around the Catch-22 using the inelegant code as follows, but wondering how to choose the append_path() url parameter which will work for both ASSETS_DEBUG = True or False.

with app.app_context():
    # js/css files
    asset_env.append_path(app.static_folder)
    # os.path.split to get package directory
    loutilitiespath = os.path.split(loutilities.__file__)[0]
    # kludge: seems like assets debug doesn't like url and no debug insists on it
    if app.config['ASSETS_DEBUG']:
        url = None
    else:
        url = '/loutilities'
    asset_env.append_path(os.path.join(loutilitiespath, 'tables-assets', 'static'), url)

Solution

  • One solution is to create a route for /loutilities/static, thus

    # add loutilities tables-assets for js/css/template loading
    # see https://adambard.com/blog/fresh-flask-setup/
    #     and https://webassets.readthedocs.io/en/latest/environment.html#webassets.env.Environment.load_path
    # loutilities.__file__ is __init__.py file inside loutilities; os.path.split gets package directory
    loutilitiespath = os.path.join(os.path.split(loutilities.__file__)[0], 'tables-assets', 'static')
    
    @app.route('/loutilities/static/<path:filename>')
    def loutilities_static(filename):
        return send_from_directory(loutilitiespath, filename)
    
    with app.app_context():
        # js/css files
        asset_env.append_path(app.static_folder)
        asset_env.append_path(loutilitiespath, '/loutilities/static')