librelist archives

« back to archive

Chicken and the app

Chicken and the app

From:
Date:
2013-06-23 @ 23:32
Hi,

I'm trying to organize a larger app, but I'm running into a 
chicken-and-the-egg problem. My app will be run served via uwsgi and 
straight from the command line (i.e. debug mode). I'm following this 
roughly:

http://flask.pocoo.org/docs/patterns/packages/

run_app.py
/myapp
/myapp/__init__.py
/myapp/controller1.py
/myapp/controller2.py

I have a fair amount of setup to do before calling app.run() (e.g. reading
config files chosen at runtime, database setup, etc.), but I need to 
access app.config and app.debug before doing so. I'm running into 
"RuntimeError: working outside of application context" errors. I have 
something like this now:

run.app
-------
<argparse that reads debug flag>
import myapp
app = create_app(debug=args.debug)
myapp.setup_app1(app=app)
myapp.setup_app1(app=app)
myapp.load_routes()

if app.debug:
    app.run(...)
else:
    app.run(...)

---

I pass "app" to the setup routines to access the debug and config 
properties - easy enough as they are called just the once.

---

myapp/__init__.py
-----------------
_app = None

def create_app(debug=False):
    # creates the app instance using the name of the module
    from flask import Flask
    _app = Flask(__name__)
    _app.debug = True
    return _app

# this is so I can do "from myapp import app"
@property
def app():
    return _app 

def setup_app1(app=None):
    ...

def setup_app2(app=None):
    ...

def load_routes():
    from myapp.routes import route1
    from myapp.routes import route2
    ...


I'm beginning to feel this is more convoluted than intended, though I've 
seen similar patterns in some skeletons on GitHub. The problem is that the
code in "route1" needs to access things like app.config and app.debug, and
that's where I'm getting the error above. I've tried both:

from flask import current_app
and
from flask import app

I've also tried:

from myapp import app
@app.route("/route1", methods=['GET', 'POST'])
def route1():
    ...

but get a "'property' object has no attribute 'route'" error.

My understanding is that the run.app script above shouldn't directly 
contain setup code - am I on the right track at least?

Cheers,
Demitri




Re: [flask] Chicken and the app

From:
Date:
2013-06-24 @ 06:46
Hey Demitri,

Flask is cacable of providing a WSGI context e.g. for Unittest or other
stuff. Maybe look at

http://flask.pocoo.org/docs/testing/#other-testing-tricks
http://flask.pocoo.org/docs/api/#flask.Flask.test_request_context
http://werkzeug.pocoo.org/docs/test/#environment-building
Cheers,
Lukas


2013/6/24 <thatsanicehatyouhave@me.com>

> Hi,
>
> I'm trying to organize a larger app, but I'm running into a
> chicken-and-the-egg problem. My app will be run served via uwsgi and
> straight from the command line (i.e. debug mode). I'm following this
> roughly:
>
> http://flask.pocoo.org/docs/patterns/packages/
>
> run_app.py
> /myapp
> /myapp/__init__.py
> /myapp/controller1.py
> /myapp/controller2.py
>
> I have a fair amount of setup to do before calling app.run() (e.g. reading
> config files chosen at runtime, database setup, etc.), but I need to access
> app.config and app.debug before doing so. I'm running into "RuntimeError:
> working outside of application context" errors. I have something like this
> now:
>
> run.app
> -------
> <argparse that reads debug flag>
> import myapp
> app = create_app (debug=args.debug)
> myapp.setup_app1(app=app)
> myapp.setup_app1(app=app)
> myapp.load_routes()
>
> if app.debug:
>     app.run(...)
> else:
>     app.run(...)
>
> ---
>
> I pass "app" to the setup routines to access the debug and config
> properties - easy enough as they are called just the once.
>
> ---
>
> myapp/__init__.py
> -----------------
> _app = None
>
> def create_app(debug=False):
>     # creates the app instance using the name of the module
>     from flask import Flask
>     _app = Flask(__name__)
>     _app.debug = True
>     return _app
>
> # this is so I can do "from myapp import app"
> @property
> def a pp():
>     return _app
>
> def setup_app1(app=None):
>     ...
>
> def setup_app2(app=None):
>     ...
>
> def load_routes():
>     from myapp.routes import route1
>     from myapp.routes import rou te2
>     ...
>
>
> I'm beginning to feel this is more convoluted than intended, though I've
> seen similar patterns in some skeletons on GitHub. The problem is that the
> code in "route1" needs to access things like app.config and app.debug, and
> that's where I'm getting the error above. I've tried both:
>
> from flask import current_app
> and
> from flask import app
>
> I've also tried:
>
> from myapp import app
> @app.route("/route1", methods=['GET', 'POST'])
> def route1():
>     ...
>
> but get a "'property' object has no attribute 'route'" error.
>
> My understanding is that the run.app script above shouldn't directly
> contain setup code - am I on the right track at least?
>
> Cheers,
> Demitri
>
>
>
>
>
>

Re: [flask] Chicken and the app

From:
Nguyễn Hồng Quân
Date:
2013-06-24 @ 11:12
2013/6/24 <thatsanicehatyouhave@me.com>

>
> I've also tried:
>
> from myapp import app
> @app.route("/route1", methods=['GET', 'POST'])
> def route1():
>     ...
>
> but get a "'property' object has no attribute 'route'" error.
>


You misused the
@property
decorator.

It is used to create a attribute (in Python meaning, or "property" in Java
meaning) for an "object" (instance of a class),  not to create a member of
a module.



-- 
***********************************************
* Nguyễn Hồng Quân                            *
* Y!M: ng_hquan_vn                            *
* Identi.ca: hongquan                         *
***********************************************

Re: [flask] Chicken and the app

From:
Date:
2013-06-24 @ 13:43
On 24 Jun 2013, at 7:12 AM, Nguyễn Hồng Quân <ng.hong.quan@gmail.com> wrote:

> You misused the
> @property
> decorator.
> 
> It is used to create a attribute (in Python meaning, or "property" in 
Java meaning) for an "object" (instance of a class),  not to create a 
member of a module.

Oh yes, this was a gross hack to make things work (which is didn't). 
That's why I'm asking for help! :)

Demitri