src/globals.py
globals.py
Official Document
Define all the global objects that are proxies to the current active context.
Overview
This is a simple module which utilize the concept of proxy objects. Click here to find a useful blog which explains how it works.
Details
Two Stacks
_request_ctx_stack
and _app_ctx_stack
are instances of werkzeug.local.LocalStack
, and now we can treat them as normal stacks named request stack and app stack, respectively.
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
Three Methods
_lookup_req_object(name)
, _lookup_app_object(name)
and _find_app()
are helper methods which are used to access attributes of top elements.
Calling _find_app()
means to get app
attribute of the top element in the app stack.
def _find_app():
top = _app_ctx_stack.top
if top is None:
raise RuntimeError(_app_ctx_err_msg)
return top.app
Calling _lookup_req_object(name)
means to get {name}
attribute of the top element in the request stack. Calling _lookup_app_object(name)
is almost as same as calling _lookup_req_object(name)
, and the only difference is that the top element is from app stack.
def _lookup_req_object(name):
top = _request_ctx_stack.top
if top is None:
raise RuntimeError(_request_ctx_err_msg)
return getattr(top, name)
def _lookup_app_object(name):
top = _app_ctx_stack.top
if top is None:
raise RuntimeError(_app_ctx_err_msg)
return getattr(top, name)
Exposed Objects
There are four exposed proxy objects in this module: current_app
, request
, session
and g
.
When accessing current_app
, _find_app()
is called. LocalProxy
ensures that current_app
always has the latest value.
current_app = LocalProxy(_find_app)
When accessing request
and session
, _lookup_req_object('request')
and _lookup_req_object('session')
are called. Note that partial
is a functionality of high-order function in Python, and we can treat is as fixing parameters of methods.
request = LocalProxy(partial(_lookup_req_object, "request"))
session = LocalProxy(partial(_lookup_req_object, "session"))
When accessing g
, _lookup_app_object('g')
is called so that we can always get the latest g
attribute of app stack’s top element.
g = LocalProxy(partial(_lookup_app_object, "g"))
Note
This is almost the simplest module in Flask project, and I think it could be a good start to analyze its source code.
Source Code
# -*- coding: utf-8 -*-
"""
flask.globals
~~~~~~~~~~~~~
Defines all the global objects that are proxies to the current
active context.
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
from functools import partial
from werkzeug.local import LocalProxy
from werkzeug.local import LocalStack
_request_ctx_err_msg = """\
Working outside of request context.
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem.\
"""
_app_ctx_err_msg = """\
Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.\
"""
def _lookup_req_object(name):
top = _request_ctx_stack.top
if top is None:
raise RuntimeError(_request_ctx_err_msg)
return getattr(top, name)
def _lookup_app_object(name):
top = _app_ctx_stack.top
if top is None:
raise RuntimeError(_app_ctx_err_msg)
return getattr(top, name)
def _find_app():
top = _app_ctx_stack.top
if top is None:
raise RuntimeError(_app_ctx_err_msg)
return top.app
# context locals
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
current_app = LocalProxy(_find_app)
request = LocalProxy(partial(_lookup_req_object, "request"))
session = LocalProxy(partial(_lookup_req_object, "session"))
g = LocalProxy(partial(_lookup_app_object, "g"))