Navigation

A thread local variable is a variable that appears to be a
"global" variable to an application which uses it. However, unlike a
true global variable, one thread or process serving the application
may receive a different value than another thread or process when that
variable is "thread local".

When a request is processed, Pyramid makes two thread
local variables available to the application: a "registry" and a
"request".

How are thread locals beneficial to Pyramid and application
developers who use Pyramid? Well, usually they're decidedly
not. Using a global or a thread local variable in any application
usually makes it a lot harder to understand for a casual reader. Use
of a thread local or a global is usually just a way to avoid passing
some value around between functions, which is itself usually a very
bad idea, at least if code readability counts as an important concern.

For historical reasons, however, thread local variables are indeed consulted by
various Pyramid API functions. For example, the implementation of the
pyramid.security function named
authenticated_userid() (deprecated as of 1.5) retrieves
the thread local application registry as a matter of course to find an
authentication policy. It uses the
pyramid.threadlocal.get_current_registry() function to retrieve the
application registry, from which it looks up the authentication policy; it then
uses the authentication policy to retrieve the authenticated user id. This is
how Pyramid allows arbitrary authentication policies to be "plugged in".

These values are thread locals rather than true globals because one
Python process may be handling multiple simultaneous requests or even
multiple Pyramid applications. If they were true globals,
Pyramid could not handle multiple simultaneous requests or
allow more than one Pyramid application instance to exist in
a single Python process.

Because one Pyramid application is permitted to call
anotherPyramid application from its own view code
(perhaps as a WSGI app with help from the
pyramid.wsgi.wsgiapp2() decorator), these variables are
managed in a stack during normal system operations. The stack
instance itself is a threading.local.

During normal operations, the thread locals stack is managed by a
Router object. At the beginning of a request, the Router
pushes the application's registry and the request on to the stack. At
the end of a request, the stack is popped. The topmost request and
registry on the stack are considered "current". Therefore, when the
system is operating normally, the very definition of "current" is
defined entirely by the behavior of a pyramid Router.

Scripts which use Pyramid machinery but never actually start
a WSGI server or receive requests via HTTP such as scripts which use
the pyramid.scripting API will never cause any Router code
to be executed. However, the pyramid.scripting APIs also
push some values on to the thread locals stack as a matter of course.
Such scripts should expect the
get_current_request() function to always
return None, and should expect the
get_current_registry() function to return
exactly the same application registry for every request.

You probably should almost never use the
get_current_request() or
get_current_registry() functions, except
perhaps in tests. In particular, it's almost always a mistake to use
get_current_request or get_current_registry in application
code because its usage makes it possible to write code that can be
neither easily tested nor scripted. Inappropriate usage is defined as
follows:

get_current_request should never be called within the body of a
view callable, or within code called by a view callable.
View callables already have access to the request (it's passed in to
each as request).

get_current_request should never be called in resource code.
If a resource needs access to the request, it should be passed the request
by a view callable.

get_current_request function should never be called because it's
"easier" or "more elegant" to think about calling it than to pass a
request through a series of function calls when creating some API
design. Your application should instead almost certainly pass data
derived from the request around rather than relying on being able to
call this function to obtain the request in places that actually
have no business knowing about it. Parameters are meant to be
passed around as function arguments, this is why they exist. Don't
try to "save typing" or create "nicer APIs" by using this function
in the place where a request is required; this will only lead to
sadness later.

Neither get_current_request nor get_current_registry should
ever be called within application-specific forks of third-party
library code. The library you've forked almost certainly has
nothing to do with Pyramid, and making it dependent on
Pyramid (rather than making your pyramid
application depend upon it) means you're forming a dependency in the
wrong direction.

Use of the get_current_request() function
in application code is still useful in very limited circumstances.
As a rule of thumb, usage of get_current_request is useful
within code which is meant to eventually be removed. For
instance, you may find yourself wanting to deprecate some API that
expects to be passed a request object in favor of one that does not
expect to be passed a request object. But you need to keep
implementations of the old API working for some period of time while
you deprecate the older API. So you write a "facade" implementation
of the new API which calls into the code which implements the older
API. Since the new API does not require the request, your facade
implementation doesn't have local access to the request when it needs
to pass it into the older API implementation. After some period of
time, the older implementation code is disused and the hack that uses
get_current_request is removed. This would be an appropriate
place to use the get_current_request.