Flask: Issue using Flask CLI with module layout recommended in Large Applications

Created on 2 Jun 2016  Â·  16Comments  Â·  Source: pallets/flask

Example project that shows issue is available here: https://github.com/sean-lynch/flask-cli-issue . I'm not sure if this is a flask cli issue or an issue with documentation. Happy to correct the docs if it's the latter.

I'm attempting to use the large app structure seen in the Flask Larger Applications documentation

First, set up a virutal environment and install flask 0.11 into that environment (requirements.txt
has all that for you).

Can successfully launch app using old app.run() mechanism found in run.py and old_launch.sh

$ python run.py

But can't seem to get to work with flask-cli. You can see both of the methods in new_launch.sh.

This throws ImportError - No module named server:

$ FLASK_APP=server FLASK_DEBUG=1 flask run

This loads, but doesn't register any of the views even though the Loading views... print output makes it to the console.

$ FLASK_APP=server/__init__.py FLASK_DEBUG=1 flask run

How should I be loading a module with flask-cli? Or alternatively, how should I be changing the module structure to support it properly?

cli docs

Most helpful comment

Strongly disagree that we should encourage modifying sys.path or PYTHONPATH manually. This can be solved with better detection and documentation.

All 16 comments

That's because you did not actually install your app.

A few options:

  • export PYTHONPATH=/path/containing/app
  • pip install --editable . (assuming you have a setup.py, did not look if you have)

An argument can be made that this behavior should be improved. I'm up for that.

Ah, hmm. Is installing an app in development a common pattern? I haven't run into it yet but admittedly, all my flask apps have been deployed by me rather than being open sourced for distribution. I was making this change based on the recommended guidance in the release notes to abandon app.run() in favor of the cli.

While export PYTHONPATH=pwd didn't seem to help, reading the documentation again, I found that python -m flask run fixed the short term problem for me. My final command:

FLASK_APP=server FLASK_DEBUG=1 python -m flask run

This works fine. Only feel like I'm not really using any of the benefits of the new cli feature now 😄

Is installing an app in development a common pattern?

Yes! Without pip install --editable . you will not get any meta information about your package. Functionality we should make sure that python -m flask and flask behave the same WRT to the Python path.

Looking into this as part of the PyCon sprints.

We just hit the same thing.

The issue with doing e.g. FLASK_APP=foo/__init__.py is that, when you do e.g. from . import app from your route definition, you get e.g. foo rather than foo/__init__.py – i.e. the module loader treats it as a separate module, and your routes get registered to the wrong Flask app.

It seems a little odd to me to have to have a stub setup.py for an application to get this to work nicely.

I think this issue should be closed as fixed by https://github.com/pallets/flask/pull/1872.

Okay!

I understand #1872 solves the bug with __init__.py not being used properly to infer path, and render the use of FLASK_APP=app/__init__.py viable, but this does not solve the issue that @mitsuhiko raised:

Functionality we should make sure that python -m flask and flask behave the same WRT to the Python path.

Right now, using FLASK_APP=app doesn't work for large apps with the structure you advise unless it is installed as a dev module. Since the installation in editable mode is not a common pattern nor mentioned in the docs (right?), it would be nice to:

  • mention this issue as a note in the current stable Flask doc, for the cli chapter
  • change the behavior to add the current path or detect automatically if the path of the module has to be added.

It would avoid people trying to switch from python manage.py ... to the cli to be left scratching their heads :-).

pip install -e . seems pretty reasonable as a dev-mode thing. In production you'd be using uWSGI anyway – i.e. flask run doesn't matter in that case.

Wow @untitaker - that was fast.
@taion: Well, for one thing the flask cli is designed to be used for any arbitrary task that could be run in prod (starting with db mgt with Flask-Alembic...). It's supposed to be a saner replacement for the deprecated manager of Flask-Script, and limiting its usage to dev environments seems sad to me. For two, even if pip install -e . is 'reasonable', it's just not documented - hence my remark.

Unless we just make python -m flask the recommended way to go?

I've been looking around, and:

  1. #1950 helps a lot by giving better error message than a plain ImportError. (but it's not released yet)
  2. Importing an arbitrary path (eg, the current one) seems like recipe for disaster, while having the user chose between installing the app in editable mode and add by hand the module path to PYTHONPATH is reasonable.
  3. The remaining bit: Do we want the docs to reflect this? I'd add a sentence like:

If your app is structured as a package and is not installed in editable mode, you will need to add by hand the path where your app module resides to the python path: export PYTHONPATH='/your/module/parent/directory/':PYTHONPATH

... but I don't know how to get about editing the current doc.

Strongly disagree that we should encourage modifying sys.path or PYTHONPATH manually. This can be solved with better detection and documentation.

Yep, definitely something that should be built into flask cli... hopefully next minor version adds cwd to the python path automatically?

I agree, it should not be a requirement to modify sys.path or any environment variables to access the cli via the flask command. It should also not be a requirement that your flask app is installed with setuptools for this to work in a nice way.

If nobody is working on this, I would be interested in investigating writing a patch for it.

It is strongly encouraged to make your app a package and that isn't going to
change.

On Tue, Apr 04, 2017 at 11:41:39AM -0700, Leslie Luyt wrote:

I agree, it should not be a requirement to modify sys.path or any environment variables to access the cli via the flask command. It should also not be a requirement that your flask app is installed with setuptools for this to work in a nice way.

If nobody is working on this, I would be interested in investigating writing a patch for it.

--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
https://github.com/pallets/flask/issues/1847#issuecomment-291594105

With #2297, #2319, and #2326, FLASK_APP can detect or specify app factories. With #2414, FLASK_APP can specify packages that are not installed in develop mode (pip install -e), although installing in develop mode is still recommended.

I verified that both FLASK_APP=server flask run and FLASK_APP=server python -m flask run work as expected with the original example.

Was this page helpful?
0 / 5 - 0 ratings