68

I am using flask and trying to the following.

I have defined a main.py file through which I want to run my app ie python main.py -

from flask import Flask
from view import tags

app = Flask(__name__)

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

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

I have defined a package named view in which I will be declaring my different view modules, each having its own routes. view.tags.py -

from flask import Flask
app = Flask(__name__)

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

So I need to have the global app object in my main.py for running the server, as well as in the view classes of my package for registering the routes. So how do I create the global app object and share it between all classes ?

Thanks, Murtaza

murtaza52
  • 46,887
  • 28
  • 84
  • 120

6 Answers6

114

You can import current_app from flask. It stores a reference to the global application object.

from flask import current_app as app

def home():
    return render_template('base.html', name=app.name)
Juan Odicio
  • 1,269
  • 2
  • 8
  • 4
  • 16
    Why do i run Flask-Admin by using `Admin(current_app, name='admin', template_mode='bootstrap3')` gets `Working outside of application context.` – TomSawyer Sep 16 '17 at 20:57
  • 5
    This is a great, simple answer that I wished I came across a long time ago. This is useful to avoid twisting the brain in order to think of what order to load views, how and where to create app etc. – Thomas Fauskanger Aug 26 '18 at 22:27
  • Ty for `from flask import current_app as app` – Milovan Tomašević Oct 28 '21 at 15:21
  • 1
    Important! there's a missing piece here described at: https://flask.palletsprojects.com/en/2.1.x/appcontext/ it is required to provide context for initialising modules that rely on app objects at module top level like so: with app.app_context(): init_db() – rubmz Jul 02 '22 at 06:45
  • @rubmz But how do I use the app_context if the file I want to use doesn't contain functions but a app.route functions only ? I get the error even before I call any function. Is it ok to use with app.app_context(): import routes ? – user2396640 Jul 18 '22 at 09:49
30

First, I would suggest to take a look at Blueprints http://flask.pocoo.org/docs/blueprints/ This will help to organize the app easily.

Also take a look at http://flask.pocoo.org/docs/api/#flask.current_app flask.current_app, the way how to get your app instance in other modules.

This link also could be helpful on how to organize and build flask app (it is not ideal for sure, but can give you some ideas) - Large-app-how-to.md

Have fun :)

Ignas Butėnas
  • 6,061
  • 5
  • 32
  • 47
  • 1
    +1 Blueprints is the correct way to do this using pure Flask. – apiguy Nov 14 '12 at 19:07
  • 1
    I looked at the blueprints page but I didn't find the answer intuitive. Can you show a code example of how the app object can be made global using blueprints? – Kvass May 21 '13 at 00:13
  • Have you looked in to mentioned thing about flask.current_app? This is how you can get your app inside the blueprint. – Ignas Butėnas May 29 '13 at 09:29
20

One way is to create an overall package and adding a __init__.py file under that where you declare all global variables. In your case for example, you can create something like:

myapplication/
    *        __init__.py
    *        myviews/
        *         __init__.py
        *         view.py
        *         tags.py

etc

Now you add the following code in the __init__.py file:

app = Flask(__name__)

You can now use this app variable anywhere as long as you import the package myapplication.

import myapplication.myviews.view
codegeek
  • 32,236
  • 12
  • 63
  • 63
  • I have opened the views.py file from above in ipython. When I type import myapplication at the prompt, I get this error - ImportError: No module named myapplication. What am I doing wrong ? – murtaza52 Nov 09 '12 at 14:27
  • 1
    This seems an elegant way to do it, thank you! @murtaza52: you probably haven't added the package to the search path yet. Read [this section](https://docs.python.org/2/tutorial/modules.html#the-module-search-path) in the docs for a good explanation. –  Feb 07 '15 at 17:44
  • 1
    what if i have run.py file at top level, app folder with __init__.py, inside it is a create_app function, i see many example does it, how do i share app object in this case? – TomSawyer Sep 17 '17 at 05:06
15

Just import it from your other files. Perhaps the best way to do this is to put your app object in one single file and have everything else import from it.

For example, your main.py could still have:

from flask import Flask
from view import tags

app = Flask(__name__)

And then in other files, you could do:

from .main import app

or, if outside your package, just use the complete string

from mypackagename.main import app

One thing to be careful of is circular imports. The easiest way to handle this issue is to create your app first and then import whatever else you need to from your base file after you create it.

So for example:

from flask import Flask
app = Flask(__name__)

# do some stuff with app
from .views import view1, view2
from .server import run

So long as you put the imports after you've created app, like the above, you shouldn't have an issue with circular imports.

Jeff Tratner
  • 16,270
  • 4
  • 47
  • 67
  • 6
    If app is inside a method like `create_app` , how do i import it? Does `create_app` create other app object again? I see many example using create_app function – TomSawyer Sep 17 '17 at 05:09
  • I think you would need to use current_app in the other files to register routes. And in the factory you will need to push the app context and import the other files. – variable Nov 17 '19 at 18:58
4

Regarding import and use of current_app from flask in a "helper" python function in a separate source file, this works as long as a current app context has already been set up (E.g. web request received). I have a case where, during application initialization (app.run not yet invoked), app.logger is invoked in the helper function.

Before I fixed it (see below), I got a stack trace punctuated by "RuntimeError: Working outside of application context".

Sample solution:
main.py:

import helper
...
app = Flask(__name__.split('.')[0],
        template_folder="templates",
        static_folder="static")
... 
# Fix: Create an app context
with app.app_context():
    helper.dbopen(...)
...
app.run(...)

helper.py:

from flask import current_app as app
...
def dbopen():
    app.logger.info(...)
    ...
Richard Elkins
  • 317
  • 2
  • 7
1

If you have a file AppName.py in which you define app, and then you have another file Foobar.py that needs it, you can always say in AppName.py:

import Foobar
Foobar.app = app

Then in Foobar.py you should be able to use app in your functions. One thing you want to be careful of is that you can't have code in Foobar.py that runs immediately when the file is called the depends on the app variable which is passed in after the import.

Kvass
  • 8,294
  • 12
  • 65
  • 108