Archive

Tag Archives: Flask

So I use Vagrant/virtual machines in my daily development and with that comes annoyances that my host-machine-only friends don’t experience.

I have my Flask app set up to detect changes and reload whenever static files change.

However, Werkzeug updated and my Flask’s auto reload stopped working.

Turns out it was using inotify and since I’m on a virtual machine, (using the /vagrant/ directory), inotify can’t detect changes on a mounted filesystem.

The solution was to use stat.

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(extra_files=my_static_files, reloader_type='stat')

Of course, there’s some disadvantages to stat, it might technically be a watchdog issue, and Werkzeug technically updated a long time ago.

Anyhoo, here’s my quick and dirty solution. I’m posting it ’cause it was hard to search for.

I want to re-compile static assets (SASS to CSS and Coffeescript to JS) whenever there’s change in my Flask app.

I also want to optionally set a flag to toggle whether that compilation happens or not.

I’m using Flask-Assets, and it only seems to trigger the compilation whenever the jinja template with the corresponding assets extension is loaded.

For example, js_all.js will only be created whenever the jinja template with the following is loaded.

{% assets "js_all" %}
    <script type="text/javascript" src="{{ ASSET_URL }}"></script>
{% endassets %}

Bizarrely, triggering the build manually was rather hard to search for.

Here’s my solution.

****Update****
You can use bundle.build() instead of asserts[‘js_all’].urls()

if reload_flag:
  assets = Environment(app)

  # Don't cache otherwise it won't build every time
  assets.cache = False
  assets.manifest = False

  js = Bundle('jquery.js', 'base.js', 'widgets.js',
              filters='jsmin', output='gen/packed.js')
  assets.register('js_all', js)

  js.build()

****

You can build bundles manually with .urls().

if reload_flag:
  assets = Environment(app)

  js = Bundle('jquery.js', 'base.js', 'widgets.js',
              filters='jsmin', output='gen/packed.js')
  assets.register('js_all', js)

  assets['js_all'].urls()

In the template:

<script type="text/javascript" src="/static/gen/js_all.js"></script>

It’s a lot less robust than using assets to automatically inject the resource url, but for me, I don’t want compilation to happen on production (I don’t even want the compilation tools on the production machines).

Hope this helps folks.
Let me know if there’s a better answer.

Oh man, maybe ’cause I’m newer to Flask but this was a feature that I wrestled with for hours.

Turns out if you run the Flask app from not within the application directory, it won’t serve up your static assets (JS, CSS, etc.).

python app_directory/app.py

I guess you must always run it from the app directory???

cd app_directory
python app.py

Bananas

@______@