The Selectors
module provides classes (although currently only
one class is supplied) which act as standard WebStack resources, but which
attempt to "select" other resources, dispatch each request to those resources,
and to cause various side-effects, mostly on the attributes stored on the
transaction object. These "selector" classes behave those in the
ResourceMap
module, but aspire to be more generally
applicable.
In non-trivial applications, it is often desirable to know the path or URL
to a particular resource, especially the "root" resource under which the
application or one of its components may reside. The PathSelector
class can be instantiated and be made to refer to a resource, recording such
path or URL details in an attribute for later inspection.
The PathSelector
class (found in the
WebStack.Resources.Selectors
module) wraps resource objects whose
location (as indicated by a path or URL) should be recorded as an attribute on
the current transaction. The most common use of the class is to record the
"root" resource's location, and this would be done as follows:
def get_site_map(): return PathSelector(MyResource())
Here, the get_site_map
function (as described in the "Deploying a WebStack Application" document) would
provide a PathSelector
object instead of an instance of the
MyResource
class. However, the side-effect of combining these two
resources would be the availability of an attribute named root
on
the transaction object. Thus, the "root" MyResource
object and,
indeed, all resource objects visited after this side-effect has occurred will
have access to the "root" path or URL information.
The API
documentation for the PathSelector
class provides additional
information.
One frequently bothersome aspect of writing Web applications involves the
processing and production of text in different encodings. Whilst the WebStack
API lets applications explicitly state the character encoding for various
operations, one often wants to be able to ignore such details since they start
to clutter up application code. The EncodingSelector
class offers
a basic solution which is compatible with the mechanisms in transaction
objects: by wrapping WebStack resources with instances of
EncodingSelector
, an application-wide default encoding (or
character set) will be defined; this will result in request information being
processed according to the stated encoding and response information being
produced according to that encoding (see below for more details of the latter
activity).
The EncodingSelector
class (found in the
WebStack.Resources.Selectors
module) wraps resource
objects whilst changing the default encoding of the current transaction
object. The class can be applied like this:
def get_site_map(): return EncodingSelector(MyResource(), "utf-8")
Here, the get_site_map
function (as described in the "Deploying a WebStack Application" document) would
provide a EncodingSelector
object instead of an instance of the
MyResource
class. However, the EncodingSelector
will
forward requests on to MyResource
(since it "selects" that
resource), whilst setting the default encoding to be "utf-8"
.
Although a default encoding affects the processing of request parameters,
direct access to the request stream using the get_request_stream
method will only produce plain strings. This behaviour is justified by the
observation that, if conversion from an encoding to Unicode were to take place,
the resulting character values may be unsuitable substitutes for the original
byte values in applications intending to make use of the raw incoming (possibly
binary) data. A recipe for making a Unicode stream is provided in the "Character Encodings" document.
Although EncodingSelector
sets a default encoding, responses
will generally be written in that encoding, at least if textual data is written
to the response stream as Unicode objects. However, the content type must
typically be set either to match the encoding in use or to not specify an
encoding. It may become necessary to find out what the response stream encoding
is when creating a ContentType
object. For this and other
purposes, the get_response_stream_encoding
method is available on
the transaction object:
from WebStack.Generic import ContentType def respond(self, trans): # Some code... trans.set_content_type(ContentType("text/html", trans.get_response_stream_encoding())) out = trans.get_response_stream() out.write(some_unicode_object)
However, it is completely acceptable to omit the encoding information where a default encoding has been set:
trans.set_content_type(ContentType("text/html")) # no encoding/charset specified
For some activities, such as making a Unicode stream from the request
stream, it is desirable to find out the encoding set by the selector. This
information is made available on transaction objects as the
default_charset
attribute.
The API
documentation for the EncodingSelector
class provides
additional information, along with the "Responses and
Presentation" document.
Web applications must often employ external resources such as database
systems, leading developers to consider effective mechanisms to manage such
resources. Although an application can initially open a database connection
and make it available to resources, it is essential that such resources access
the connection in a way that does not cause problems over time. The
StoreSelector
class offers an elementary solution for resources
employing database connections by storing a connection object in an attribute
on the transaction object, such that resources may obtain the connection
merely by accessing the appropriate attribute. Moreover, the
StoreSelector
also ensures that database transactions are
terminated in a timely fashion by calling the rollback
method on
the connection when a resource (or potentially many resources) have completed
their work.
The StoreSelector
class (found in the
WebStack.Resources.Selectors
module) wraps resource
objects whilst maintaining a reference to a database connection or store
object as an attribute on a WebStack transaction object. The class can be
applied like this:
def get_site_map(connection): return StoreSelector(MyResource(), connection)
Here, the get_site_map
function (as described in the "Deploying a WebStack Application" document) would
provide a StoreSelector
object instead of an instance of the
MyResource
class. However, the StoreSelector
will
forward requests on to MyResource
(since it "selects" that
resource), whilst maintaining a reference to the connection
provided.
Resources wishing to access the database connection would use code like the following:
def respond(self, trans): # Some code... connection = trans.get_attributes()["store"]
Should an alternative attribute name be required, such a name may be
provided as an additional argument when initialising the
StoreSelector
; for example:
def get_site_map(connection): return StoreSelector(MyResource(), connection, "connection")
The API
documentation for the StoreSelector
class provides
additional information, and the "Integrating with
Other Systems" document describes related topics.