Skip to content

Instantly share code, notes, and snippets.

@simon-weber
Last active July 31, 2018 13:58
Show Gist options
  • Save simon-weber/7755289 to your computer and use it in GitHub Desktop.
Save simon-weber/7755289 to your computer and use it in GitHub Desktop.
An example of using a StackContext to store request data globally in Tornado. See https://groups.google.com/d/msg/python-tornado/8izNLhYjyHw/TNKGa9fgvpUJ for motivation and further discussion.
import tornado
class RequestContextHandler(tornado.web.RequestHandler):
def _execute(self, transforms, *args, **kwargs):
# following the example of:
# https://github.com/bdarnell/tornado_tracing/blob/master/tornado_tracing/recording.py
global_data = {} # add whatever here, e.g. self.request
with tornado.stack_context.StackContext(functools.partial(ThreadRequestContext, **global_data)):
super(RequestContextHandler, self)._execute(transforms, *args, **kwargs)
# elsewhere, use ThreadRequestContext.data => a dict
import threading
class ThreadRequestContext(object):
"""A context manager that saves some per-thread state globally.
Intended for use with Tornado's StackContext.
Provide arbitrary data as kwargs upon creation,
then use ThreadRequestContext.data to access it.
"""
_state = threading.local()
_state.data = {}
class __metaclass__(type):
# property() doesn't work on classmethods,
# see http://stackoverflow.com/q/128573/1231454
@property
def data(cls):
if not hasattr(cls._state, 'data'):
return {}
return cls._state.data
def __init__(self, **data):
self._data = data
def __enter__(self):
self._prev_data = self.__class__.data
self.__class__._state.data = self._data
def __exit__(self, *exc):
self.__class__._state.data = self._prev_data
del self._prev_data
return False
@eddyzhou
Copy link

Not work well with coroutine

@virtuald
Copy link

Those who come by here may want to try https://gist.github.com/virtuald/50bf7cacdc8cfb05e323f350539f0efa instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment