272

My flask application currently consists of a single test.py file with multiple routes and the main() route defined. Is there some way I could create a test2.py file that contains routes that were not handled in test.py?

@app.route('/somepath')
def somehandler():
    # Handler code here

I am concerned that there are too many routes in test.py and would like to make it such that I can run python test.py, which will also pick up the routes on test.py as if it were part of the same file. What changes to I have to make in test.py and/or include in test2.py to get this to work?

8 Answers 8

255

You can use the usual Python package structure to divide your App into multiple modules, see the Flask docs.

However,

Flask uses a concept of blueprints for making application components and supporting common patterns within an application or across applications.

You can create a sub-component of your app as a Blueprint in a separate file:

simple_page = Blueprint('simple_page', __name__, template_folder='templates')
@simple_page.route('/<page>')
def show(page):
    # stuff

And then use it in the main part:

from yourapplication.simple_page import simple_page

app = Flask(__name__)
app.register_blueprint(simple_page)

Blueprints can also bundle specific resources: templates or static files. Please refer to the Flask docs for all the details.

Sign up to request clarification or add additional context in comments.

2 Comments

how can we have the blueprint routes in file other that init of that blueprint ?
if i want to make a secured end points using JWT then how will do that in every route.py files
129

You can use simple trick which is import flask app variable from main inside another file, like:

test_routes.py

from __main__ import app

@app.route('/test', methods=['GET'])
def test():
    return 'it works!'

and in your main files, where you declared flask app, import test-routes, like:

app.py

from flask import Flask, request, abort

app = Flask(__name__)

# import declared routes
import test_routes

It works from my side.

11 Comments

It's just an example, __main__ refers to your entry file, that's it!
Brilliant, many thanks. Blueprint or the package approach above are overkills for small apps.
Here's a link to the docs where this method is explained: https://flask.palletsprojects.com/en/1.1.x/patterns/packages/
@nimeresam It worked for me but I had to learn that the import test-routes cannot be at the top of the app.py file. It crashed gunicorn but then after moving the import to the bottom of the file then it worked. " just ensuring the module is imported and we are doing that at the bottom of the file"
The circular dependency doesn't look to good. stackoverflow.com/a/60441931/6419007 is much better IMHO. It's simple too but much cleaner.
|
72

This task can be accomplished without blueprints and tricky imports using Centralized URL Map

app.py

import views
from flask import Flask

app = Flask(__name__)

app.add_url_rule('/', view_func=views.index)
app.add_url_rule('/other', view_func=views.other)

if __name__ == '__main__':
    app.run(debug=True, use_reloader=True)

views.py

from flask import render_template

def index():
    return render_template('index.html')

def other():
    return render_template('other.html')

3 Comments

Among the listed possibilities to split the app.py into multiple files, I found this approach to be the most simple and straigth forward. It's worth to mention that if you import request and session from flask, you can access the request details and the session in views.py.
Any serious reason to not use this and use Blueprints instead? This looks so easy.
@Banik, It does look easy, but it will most likely become cumbersome, if you'll be adding dozens or more routes. With the Blueprints you'll be just defining a few Blueprint names. Not to mention, that each Blueprint also allows you to specify its own special folders, like static and templates, so you could keep them more organized and separated from each other.
17

I would like to recommend flask-empty at GitHub.

It provides an easy way to understand Blueprints, multiple views and extensions.

Comments

15

If you need split blueprint to separate files you can use snippet:

# app.py

from blueprint_module import blueprint

app = Flask(__name__)
app.register_blueprint(blueprint)
# blueprint_module\__init__.py

from flask import Blueprint

blueprint = Blueprint('my_blueprint', __name__)

from . import page
# blueprint_module\page.py

from . import blueprint

@blueprint.route("/url", methods=['GET'])
def hello():
  return 'hello world'

3 Comments

Note: add text in blueprint_module/__init__.py
This reminds me a lot on how Express for node suggests to organize the service routes. Great answer.
did not work for me. I have to correct the import for app.py from blueprint_module.page import blueprint
7

Dividing the app into blueprints is a great idea. However, if this isn't enough, and if you want to then divide the Blueprint itself into multiple py files, this is also possible using the regular Python module import system, and then looping through all the routes that get imported from the other files.

I created a Gist with the code for doing this:

https://gist.github.com/Jaza/61f879f577bc9d06029e

As far as I'm aware, this is the only feasible way to divide up a Blueprint at the moment. It's not possible to create "sub-blueprints" in Flask, although there's an issue open with a lot of discussion about this:

https://github.com/mitsuhiko/flask/issues/593

Also, even if it were possible (and it's probably do-able using some of the snippets from that issue thread), sub-blueprints may be too restrictive for your use case anyway - e.g. if you don't want all the routes in a sub-module to have the same URL sub-prefix.

Comments

0

I found a simpler alternatives than the current top 3 answers which I ended up not using because:

  1. The Blueprint approach in the first answer is an overkill for small apps.

  2. The package approach in the second answer has an ugly circular import, and import your_module annoyingly cannot be at the top of the app.py file.

  3. The Centralized URL Map is fine but I don't like the fact that centralized routes are separated from their views.

It turns out, there is a simpler fix to #2. Just move the app object into its own module (named app_factory.py, for example), and then have every other modules import that app_factory.py

For example.

app_factory.py

from flask import Flask

app = Flask(__name__)

and in your view files, import app like this:

view1.py

from app_factory import app

@app.route('/test', methods=['GET'])
def test():
    return 'it works!'

and in your main file app.py, import all the building blocks as you normal would, like:

app.py

from app_factory import app
import view1  # This can be put at the beginning of this file

@app.route('/')
def index():
    return 'hello world'

It works from my side.

Comments

-1

The solution is very simple. Make a new file and put app in that file. Then you could import that file anywhere. for example, in A.py app = Flask(name)

in B.py and C.py from A import *

1 Comment

You should avoid from something import * as it makes it difficult to follow what you’re importing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.