1

As stated in Flask not finding routes in imported modules I have a very simple Flask application in Python 2.7 that wasn't working when my routes were defined in a different module.

To recap, I have run.py at the top-level, which declares the Flask app variable and then imports the views.home module where the views are defined.

I have discovered that if I switch the import statement in run.py from:

import views.home

to

from views.home import *

everything works.

Why is that? As far as I can tell (https://softwareengineering.stackexchange.com/questions/187403/import-module-vs-from-module-import-function) there isn't any functional different between the two imports that should impact the behaviour of Flask?

Community
  • 1
  • 1
user783836
  • 3,099
  • 2
  • 29
  • 34

2 Answers2

0

When importing with import views.home, in the place where you are using the views, are you using

views.home.somefunction()

or are you using:

somefunction()

?

The second one will only work when doing from views.home import *, as this will place all the stuff on views.home on the global namespace.

elelias
  • 4,552
  • 5
  • 30
  • 45
  • No, I'm not using `views.home.somefunction()` or `somefunction()`. `view.home` has a whole bunch of functions marked up with with `@app.route` Flask attribute and Flask does not seem to process these when I use `import views.home`. I would have thought they would be processed as the action of importing the module results in in being processed – user783836 Oct 01 '15 at 10:35
  • I finally worked out why I was seeing this behaviour. See http://stackoverflow.com/questions/32874629/flask-not-finding-routes-in-imported-modules/32882527#32882527 – user783836 Oct 01 '15 at 11:43
  • awesome, the issue was a lot more complex than I initially though, but good learnings there, thanks for posting – elelias Oct 01 '15 at 12:56
0

I have managed to work out what is going on (as per Flask not finding routes in imported modules)

Basically, when run.py is run as a script it is given the name __main__ and it is registered in sys.modules as __main__ (as per Importing modules: __main__ vs import as module)

Then when I import app from run.py in views.home.py, python fails to find the run module in sys.modules (because it is called __main__) and creates a new instance of run.py and registers it in sys.modules with the name run.

At this point there are two instances of the run module in sys.modules and, as a result, two instances of the app variable.

views.home.py registers its routes with one instance of app and run.py starts the other instance of app, so views.home.py's routes are never used.

The reason that

from views.home import *

works is because it creates references to all of the views.home functions in the __main__ module (as per `from ... import` vs `import .`) which results in views.home.py's routes being registered with the instance of the app variable thatr run.py starts.

Community
  • 1
  • 1
user783836
  • 3,099
  • 2
  • 29
  • 34