user783836
user783836

Reputation: 3499

Flask not finding routes in imported modules

I'm having a problem with Flask wherein routes declared in imported modules are not be registered and always result in a 404. I am running the latest version Flask on Python 2.7.

I have the following directory structure: enter image description here run.py has the following code: from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World!'

import views.home

if __name__ == '__main__':
    app.run()

home.py has the following code:

from run import app


@app.route('/test')
def test():
    return "test"

When I run run.py the route declared in home.py (http://localhost:5000/test) always returns a 404 even though run.py imports views.home. The root view (http://localhost:5000) declared in run.py works fine.

I have written a function that prints out all the registered routes and /test is not in there (get a list of all routes defined in the app).

Any idea why?

Upvotes: 1

Views: 10029

Answers (2)

user783836
user783836

Reputation: 3499

I have discovered that switching the import statement in run.py from

import views.home

to

from views.home import *

makes everything work, which gave me the clue as to why the modules are not being registered using import views.home.

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

Then when I import app from run.py in views.home.py a new instance of run.py is registered in sys.modules with the name run. As this point, the reference to app in run.py and views.home.py are two different references hence the routes not being registered.

The solution was to move the creation of the app variable out of run.py and in to a separate python file (I called it web_app.py) that is imported into run.py. This guarantees that the Flask app variable declared inside web_app.py is the always referenced correctly wherever web_app.py is imported.

So run.py now looks like this:

from web_app import app

if __name__ == '__main__':
    app.run()

and web_app.py looks like this:

from flask import Flask

app = Flask(__name__)

import view.home

Upvotes: 10

hrust
hrust

Reputation: 742

You can do it by reorganizing your code as it is described here Larger Applications, but it is more recommended to divide them into smaller groups where each group is implemented with the help of a blueprint. For a gentle introduction into this topic refer to the Modular Applications with Blueprints chapter of the documentation.

Upvotes: 0

Related Questions