[Zope-CVS] CVS: Products/Sessions/help - SessionInterfaces.py:1.1 session-admin.stx:1.1 sessionapi-prog.stx:1.1 Sessions.stx:1.2

Matthew T. Kromer matt@zope.com
Mon, 5 Nov 2001 15:48:18 -0500

Update of /cvs-repository/Products/Sessions/help
In directory cvs.zope.org:/tmp/cvs-serv13452

Modified Files:
Added Files:
	SessionInterfaces.py session-admin.stx sessionapi-prog.stx 
Log Message:
Updated Session documentation

=== Added File Products/Sessions/help/SessionInterfaces.py ===

Session API

  See Also

    - "Programming with the Session API":sessionapi-prog.stx

    - "Transient Object API":../../Transience/Help/TransienceInterfaces.py


import Interface

class BrowserIdManagerInterface(
    Zope Browser Id Manager interface.

    A Zope Browser Id Manager is responsible for assigning ids to site
    visitors, and for servicing requests from Session Data Managers
    related to the browser token.
    def encodeUrl(self, url):
        Encodes a provided URL with the current request's browser token
        and returns the result.  For example, the call
        encodeUrl('http://foo.com/amethod') might return

        Permission required: Access contents information

        Raises:  BrowserIdManagerErr.  If there is no current session token.

    def getTokenKey(self):
        Returns a string with the name of the cookie/form variable which is
        used by the current browser id manager as the name to look up when
        attempting to obtain the browser token value.  For example, '_ZopeId'.

        Permission required: Access contents information

    def getToken(self, create=1):
        If create=0, returns a the current browser token or None if there
        is no browser token associated with the current request.  If create=1,
        returns the current browser token or a newly-created browser token if
        there is no browser token associated with the current request.  This
        method is useful in conjunction with getTokenKey if you wish to embed
        the token-key/token combination as a hidden value in a POST-based
        form.  The browser token is opaque, has no business meaning, and its
        length, type, and composition are subject to change.

        Permission required: Access contents information

        Raises:  BrowserIdManagerErr.  If ill-formed browser token
        is found in REQUEST.

    def hasToken(self):
        Returns true if there is a browser token for this request.

        Permission required: Access contents information

    def isTokenNew(self):
        Returns true if browser token is 'new'.  A browser token is 'new'
        when it is first created and the client has therefore not sent it
        back to the server in any request.  

        Permission required: Access contents information

        Raises:  BrowserIdManagerErr.  If there is no current browser token.

    def isTokenFromForm(self):
        Returns true if browser token comes from a form variable (query
        string or post).

        Permission required: Access contents information

        Raises:  BrowserIdManagerErr.  If there is no current browser token.

    def isTokenFromCookie(self):
        Returns true if browser token comes from a cookie.

        Permission required: Access contents information

        Raises:  BrowserIdManagerErr.  If there is no current browser token.

    def flushTokenCookie(self):
        Deletes the token cookie from the client browser, iff the
        'cookies' token key namespace is being used.
        Permission required: Access contents information

        Raises:  BrowserIdManagerErr.  If the 'cookies' namespace isn't
        a token key namespace at the time of the call.

class SessionDataManagerInterface(
    Zope Session Data Manager interface.

    A Zope Session Data Manager is responsible for maintaining Session
    Data Objects, and for servicing requests from application code
    related to Session Data Objects.  It also communicates with a Browser
    Id Manager to provide information about browser tokens.
    def getBrowserIdManager(self):
        Returns the nearest acquirable browser id manager.

        Raises SessionDataManagerErr if no browser id manager can be found.

        Permission required: Access session data

    def getSessionData(self, create=1):
        Returns a Session Data Object associated with the current
        browser token.  If there is no current token, and create is true,
        returns a new Session Data Object.  If there is no current
        token and create is false, returns None.

        Permission required: Access session data

    def hasSessionData(self):
        Returns true if a Session Data Object associated with the
        current browser token is found in the Session Data Container.  Does
        not create a Session Data Object if one does not exist.

        Permission required: Access session data

    def getSessionDataByKey(self, key):
        Returns a Session Data Object associated with 'key'.  If there is
        no Session Data Object associated with 'key' return None.

        Permission required: Access arbitrary user session data

=== Added File Products/Sessions/help/session-admin.stx ===
Session Administration

  Session Data Object Expiration

    Session data objects expire after the period between their last
    access and "now" exceeds the timeout value provided to the
    transient object container which hold them.  No special action need
    be taken to expire session data objects.![1]

      ![1] See "Session Data Object Expiration Considerations" in the
      Concepts and Caveats section below for details on session data

  Importing And Exporting Session Data Objects

    In some circumstances, it is useful to be able to "export" all
    the session data from a specific transient object container in order
    to "import" it to another.  This may be necessary when migrating
    data between containers or when upgrading the session tracking
    implementation to a more recent version.

    You can export data from a transient object container by visiting
    its "Advanced" tab, and choosing "Export Session Data".  A file
    will be written to the hard disk of the Zope server you're
    talking to in the 'var' directory of the Zope instance named

    To import exported session data, choose "Import Session Data"
    from the Advanced tab of the transient object container you're
    migrating to.  The "sessiondata.zexp" file containing the
    exported session data will be read from disk and placed into the
    transient object container.

    The contents of RAM-based (internal) transient object containers
    cannot be exported, and you may not import session data into an
    internal transient object container.

Concepts and Caveats

  Session Id (Non-)Expiration

    Unlike many other sessioning implementations, core session
    tracking session tokens (ids) do not actually themselves expire.
    They persist for as long as their conveyance mechanism allows.
    For example, a session token will last for as long as the session
    token cookie persists on the client, or for as long as someone
    uses a bookmarked URL with a session token in it.  The same id
    will be obtained by a browser id manager on every visit by that
    client to a site - potentially indefinitely depending on which
    conveyance mechanisms you use and your configuration for cookie
    persistence.  It may be useful to think of a Zope browser id as
    a "browser id" for this reason.

    In lieu of exipry of browser ids, the transient object container
    which holds session data objects implements a policy for data
    object expiration.  If asked for a session data object related
    to a particular browser id which has been expired by a transient
    object container, a session data manager will a return a new
    session data object.

  Session Data Object Expiration Considerations

    Because Zope has no scheduling facility, the sessioning
    machinery depends on the continual exercising of itself to
    expire session data objects.  If the sessioning machinery is not
    exercised continually, it's possible that session data
    objects will stick around longer than the time specified by
    their transient object container timeout value.  For example:

      - User A exercises application machinery that generates a
      session data object.  It is inserted into a transient object
      container which advertises a 20-minute timeout.

      - User A "leaves" the site.

      - 40 minutes go by with no visitors to the site.

      - User B visits 60 minutes after User A first generated his
      session data object, and exercises app code which hands out
      session data objects.  *User A's session is expired at this
      point, 40 minutes "late".*

  Sessioning and Transactions

    The existing transient object container implementations interact
    with Zope's transaction system.  If a transaction is aborted,
    the changes made to session data objects during the transaction
    will be rolled back.

  Acquisition-Wrapped Objects

    The sessioning machinery unwraps acquisition-wrapped objects
    before storing them during a session_data_object.set or
    session_data_object.__setitem__ operation.  Practically, this
    means you can safely pass acquisition-wrapped objects in to the
    sessioning machinery (for example, a DTML Document obtained via
    traversal) as values within a session data object.  The stored
    reference will be to the bare unwrapped object. (new in 0.9)

  Mutable Data Stored Within Session Data Objects

    If you mutate an object stored as a value within a session data
    object, you'll need to notify the sessioning machinery that the
    object has changed by calling 'set' or '__setitem__' on the
    session data object with the new object value.  For example::

       session = self.session_data_mgr.getSessionData()
       foo = {}
       foo['before'] = 1
       session.set('foo', foo)

	 # mutate the dictionary

       foo['after'] = 1

	 # performing session.get('foo') 10 minutes from now will likely
       # return a dict with only 'before' within!

    You'll need to treat mutable objects immutably, instead.  Here's
    an example that makes the intent of the last example work by
    doing so::

       session = self.session_data_mgr.getSessionData()
       foo = {}
       foo['before'] = 1
       session.set('foo', foo)

	 # mutate the dictionary
       foo['after'] = 1

	 # tickle the persistence machinery
	 session.set('foo', foo)

    An easy-to-remember rule for manipulating data objects in
    session storage: always explicitly place an object back into
    session storage whenever you change it.  For further reference,
    see the "Persistent Components" chapter of the Zope Developer's
    Guide at http://www.zope.org/Documentation/ZDG.

  Session Data Object Keys

    A session data object has essentially the same restrictions as a
    Python dictionary.  Keys within a session data object must be
    hashable (strings, tuples, and other immutable basic Python
    types; or instances which have a __hash__ method).  This is a
    requirement of all Python objects that are to be used as keys to
    a dictionary.  For more information, see the associated Python
    documentation at
    http://www.python.org/doc/current/ref/types.html (Mappings ->

  In-Memory Session Data Container RAM Utilization

    Each session data object which is added to an "internal"
    (RAM-based) transient object container will consume at least 2K of

  Mounted Database-Based Session Data Container/Internal Session
  Data Container Caveats

    Persistent objects which have references to other persistent
    objects in the same database cannot be committed into a mounted
    database because the ZODB does not currently handle
    cross-database references.

    "Internal" (RAM-based) transient object containers are currently
    implemented as objects within (automatically) mounted ZODB
    databases.  For this reason, they are equivalent in operation to
    external transient object containers which are placed in a manually
    mounted database.

    If you use an internal transient object container or an external
    transient object container that is accessed via a "mounted"
    database, you cannot store persistent object instances which
    have already been stored in the "main" database as keys or
    values in a session data object.  If you try to do so, it is
    likely that an 'InvalidObjectReference' exception will be raised
    by the ZODB when the transaction involving the object attempts
    to commit.  As a result, the transaction will fail and the
    session data object (and other objects touched in the same
    transaction) will fail to be committed to storage.

    If your "main" ZODB database is backed by a nonundoing storage,
    you can avoid this condition by storing session data objects in
    an external data container instantiated within the "main" ZODB
    database.  If this is not an option, you should ensure that
    objects you store as values or keys in a session data object
    held in a mounted transient object container are instantiated "from
    scratch" (via their constructors), as opposed to being "pulled
    out" of the main ZODB.

  Conflict Errors

    This session tracking software stores all session state in
    Zope's ZODB.  The ZODB uses an optimistic concurrency strategy
    to maintain transactional integrity for simultaneous writes.
    This means that if two objects in the ZODB are changed at the
    same time by two different connections (site visitors) that a
    "ConflictError" will be raised.  Zope retries requests that
    raise a ConflictError at most 3 times.  If your site is
    extremely busy, you may notice ConflictErrors in the Zope debug
    log (or they may be printed to the console from which you run
    Zope).  An example of one of these errors is as follows::

     2001-01-16T04:26:58 INFO(0) Z2 CONFLICT Competing writes at, /getData
     Traceback (innermost last):
     File /zope/lib/python/ZPublisher/Publish.py, line 175, in publish
     File /zope/lib/python/Zope/__init__.py, line 235, in commit
     File /zope/lib/python/ZODB/Transaction.py, line 251, in commit
     File /zope/lib/python/ZODB/Connection.py, line 268, in commit
     ConflictError: '\000\000\000\000\000\000\002/'

    Errors like this in your debug log (or console if you've not
    redirected debug logging to a file) are normal to an extent.  If
    your site is undergoing heavy load, you can expect to see a
    ConflictError perhaps every 20 to 30 seconds.  The requests
    which experience conflict errors will be retried automatically
    by Zope, and the end user should *never* see one.  Generally,
    session data objects attempt to provide application-level
    conflict resolution to reduce the limitations imposed by
    conflict errors NOTE: to take advantage of this feature, you
    must be running Zope 2.3.1 or better, and you must be using it
    with a storage such as FileStorage or SessionStorage which
    supports application-level conflict resolution.

Zope Versions and Sessioning

    Zope Versions are not particularly useful in combination with
    sessioning.  Particularly, if you change the properties of a
    session data manager or browser id manager while working in a
    Version on a "production" site, it may cause the sessioning
    machinery to stop working for unversioned visitors to the site
    due to the "locking" nature of versions.  To work around this
    problem, do not lock any sessioning-related objects while in a
    Version.  Alternately, do not use Versions.

Extending The Session Tracking Product

  Implementing Alternate Session Data Managers and Data Containers

    Alternate session data managers and data containers (perhaps
    using a SQL database as a persistence mechanism) may be
    implemented if they adhere to the interfaces outlined in the
    SessioningInterfaces.py documentation which ships with this

=== Added File Products/Sessions/help/sessionapi-prog.stx ===
Session API Programming


    Developers generally interact with a Session Data Manager
    instance in order to make use of sessioning in Zope.  Methods
    named in this section are those of session data managers unless
    otherwise specified.

    All of the methods implemented by Session Data Managers, Session
    Id Managers and Session Data objects are fully documented in the
    "SessioningInterfaces.py" file accompanying this software.
    This section of the documentation will concentrate on explaining
    common operations having to do with session-tracking and why
    they might be important to you.


    Here's a mini-glossary of terminology used by the session
    tracking product:

      token (aka 'token value') -- the string or integer used to
      represent a single anonymous visitor to the part of the Zope
      site managed by a single session id manager.
      E.g. "12083789728".

      token key namespaces -- the session token key/value pair will
      be found in one of these namespaces.  They refer to namespaces
      codified in the Zope REQUEST object.  E.g. "cookies" or

      token key -- the key which is looked for in the REQUEST
      namespaces enumerated by the token key namespaces configured.
      This references the token as its value.  E.g. "_ZopeId".

      session data object -- an instance of the session data object
      class that is found by asking a transient object container for the
      item with a key that is a token value.

  Obtaining the Token Value

    You can obtain the token value associated with the current
    request from a session data manager::

      <dtml-var "sessiondatamanager.getToken()">

    This snippet will print the token value to the remote browser.
    If no token exists for the current request, a new token is
    created implicitly and returned.

    If you wish to obtain the current token value without implicitly
    creating a new token for the current request, you can use the
    'create' argument to the 'getToken()' method to suppress this

      <dtml-var "sessiondatamanager.getToken(create=0)">

    This snippet will print a representation of the None value if
    there isn't a session token associated with the current request,
    or it will print the token value if there is one associated with
    the current request.  Using 'create=0' is useful if you do not
    wish to cause the sessioning machinery to attach a new session
    token to the current request, perhaps if you do not wish a
    session cookie to be set.

    The token value *is not* the session data.  The token value
    represents the key by which the 'getSessionData' method obtains
    a session data object representing the visitor marked by the
    token.  The token value is either a string or an integer and has
    no business meaning.  In your code, you should not rely on the
    session token composition, length, or type as a result, as it is
    subject to change.

  Determining Which Token Key Namespace Holds The Session Token

    For some applications, it is advantageous to know from which
    token key namespace (currently either 'cookies' or 'form') the
    token has been gathered.  There are two methods of session data
    managers which allow you to accomplish this,
    'isTokenFromCookie()', and 'isTokenFromForm()'::

      <dtml-if "sessiondatamanager.isTokenFromCookie()">
        The token came from a cookie.

      <dtml-if "sessiondatamanager.isTokenFromForm()">
        The token came from a form.

    The 'isTokenFromCookie()' method will return true if the token
    in the current request comes from the 'REQUEST.cookies'
    namespace.  This is true if the token was sent to the Zope
    server as a cookie.

    The 'isTokenFromForm()' method will return true if the token in
    the current request comes from the 'REQUEST.form' namespace.
    This is true if the token key/value pair was sent to the Zope
    server encoded in a URL or as part of a form element.

    If a token doesn't actually exist in the current request when
    one of these methods is called, an error will be raised.

    During typical operations, you shouldn't need to use these
    methods, as you shouldn't care from which REQUEST namespace the
    token key/value pair was obtained.  However, for highly
    customized applications, this pair of methods may be useful.

  Obtaining the Token Key/Value Pair and Embedding It Into A Form

    You can obtain the "token key" from a session data manager
    instance.  The token key is the name which is looked for in
    token key namespaces by a session id manager.  We've already
    determined how to obtain the token value.  It is useful to
    obtain the token key/value pair if you wish to embed a session
    token key/value pair as a hidden form field for use in POST

      <form action="thenextmethod">
      <input type=submit name="submit" value=" GO ">
      <input type=hidden name="<dtml-var "sessiondatamanager.getTokenKey()">"
       value="<dtml-var "sessiondatamanager.getToken()">">

  Determining Whether A Session Token is "New"

    A session token is "new" if it has been set in the current
    request but has not yet been acknowledged by the client --
    meaning it has not been sent back by the client in a request.
    This is the case when a new session token is created by the
    sessioning machinery due to a call to 'getSessionData()' or
    similar as opposed to being received by the sessioning machinery
    in a token key namespace.  You can use the 'isTokenNew()' method
    of session data managers to determine whether the session is

      <dtml-if "sessiondatamanager.isTokenNew()">
        Token is new.
        Token is not new.

    This method may be useful in cases where applications wish to
    prevent or detect the regeneration of new tokens when the same
    client visits repeatedly without sending back a token in the
    request (such as may be the case when a visitor has cookies
    "turned off" in their browser and the session id manager only
    uses cookies).

    If there is no session token associated with the current
    request, this method will raise an error.

    You shouldn't need to use this method during typical operations,
    but it may be useful in advanced applications.

  Determining Whether A Session Data Object Exists For The Token Associated
    With This Request

    If you wish to determine whether a session data object with a
    key that is the current request's token exists in the data
    manager's associated transient object container, you can use the
    'hasSessionData()' method of the session data manager.  This
    method returns true if there is session data associated with the
    current session token::

      <dtml-if "sessiondatamanager.hasSessionData()">
         The sessiondatamanager object has session data for the token
         associated with this request.
         The sessiondatamanager object does not have session data for
         the token associated with this request.

    The 'hasSessionData()' method is useful in highly customized
    applications, but is probably less useful otherwise.  It is
    recommended that you use 'getSessionData()' instead, allowing
    the session data manager to determine whether or not to create a
    new data object for the current request.

  Embedding A Session Token Into An HTML Link

    You can embed the token key/value pair into an HTML link for use
    during HTTP GET requests.  When a user clicks on a link with a
    URL encoded with the session token, the token will be passed
    back to the server in the REQUEST.form namespace.  If you wish
    to use formvar-based session tracking, you will need to encode
    all of your "public" HTML links this way.  You can use the
    'encodeUrl()' method of session data managers in order to
    perform this encoding::

      <a href="<dtml-var "sessiondatamgr.encodeUrl('/amethod')">">Here</a>
       is a link.

    The above dtml snippet will encode the URL "/amethod" (the
    target of the word "Here") with the session token key/value pair
    appended as a query string.  You can additionally pass URLs
    which already contain query strings to the 'encodeUrl()' method

  Obtaining A Session Data Object

    Use the 'getSessionData()' method of session data managers to
    obtain the session data object associated with the session token
    in the current request::

      <dtml-let data="sessiondatamanager.getSessionData()">
        The 'data' name now refers to a new or existing session data object.

    The 'getSessionData()' method implicitly creates a new session
    token and data object if either does not exist in the current
    request.  To inhibit this behavior, use the create=0 flag to the
    'getSessionData()' method::
      <dtml-let data="sessiondatamanager.getSessionData(create=0)">
         The 'data' name now refers to an existing session data object or
         None if there was no existing token or session data object.

    The 'getSessionData()' method is a highly used method.  It is
    probably the most-commonly used method of session data managers.
  Modifying A Session Data Object

    Once you've used 'getSessionData()' to obtain a session data
    object, you can set key/value pairs of the returned session data
    object.  These key/value pairs are where you store information
    related to a particular anonymous visitor.  You can use the
    'set', 'get', and 'has_key' methods of session data objects to
    perform actions related to it::

      <dtml-let data="sessiondatamanager.getSessionData()">
        <dtml-call "data.set('foo', 'bar')">
        <dtml-comment>Set 'foo' key to 'bar' value.</dtml-comment>
        <dtml-var "data.get('foo')">
        <dtml-comment>Will print 'bar'</dtml-comment>
        <dtml-if "data.has_key('foo')">
          This will be printed.
          This will not be printed.

    An essentially arbtrary set of key/value pairs can be placed
    into a session data object.  Keys and values can be any kinds of
    Python objects (note: see Concepts and Caveats section for
    exceptions to this rule).  The transient object container which
    houses the session data object determines its expiration policy.
    Session data objects will be available across client requests
    for as long as they are not expired.

   Manually Invalidating A Session Data Object

    Developers can manually invalidate a session data object.  When
    a session data object is invalidated, it will be flushed from
    the system, and will not be returned on subsequent requests to
    'getSessionData()'.  The 'invalidate()' method of a session data
    object causes this to happen::

      <dtml-let data="sessiondatamanager.getSessionData()">
        <dtml-call "data.invalidate()">

    Subsequent calls to 'getSessionData()' in this same request will
    return a new session data object.  Manual invalidation of
    session data is useful in cases where you know the session data
    is stale and you wish to flush it from the data manager.

  Manually Invalidating A Session Token Cookie

    Developers may manually invalidate the cookie associated with
    the session token, if any.  To do so, they can use the
    'flushTokenCookie()' method of a session data manager.  For

      <dtml-call "sessiondatamanager.flushTokenCookie()">

    If the 'cookies' namespace isn't a valid token key namespace
    when this call is performed, an exception will be raised.

  An Example Of Using Session Data from DTML

    An example of obtaining a session data object from a session
    data manager named 'sessiondatamgr' and setting one of its
    key-value pairs in DTML follows::

      <dtml-with sessiondatamgr>
        <dtml-let a=getSessionData>
          Before change: <dtml-var a><br>
          <dtml-call "a.set('zopetime', ZopeTime())">
          'zopetime' will be set to a datetime object for the current
          After change:  <dtml-var a><br>
    The first time you run this method, the "before change"
    representation of the session data object will be that of an
    empty dictionary, and the "after change" representation will
    show a key/value pair of 'zopetime' associated with a DateTime
    object.  Assuming you've configured your session id manager with
    cookies and they're working on your browser properly, the second
    and subsequent times you view this method, the "before change"
    representation of the session data object will have a datetime
    object in it that was the same as the last call's "after change"
    representation of the same session data object.  This
    demonstrates the very basics of session management, because it
    demonstrates that we are able to associate an object (the
    session data object obtained via getSessionData) with an
    anonymous visitor between HTTP requests.

    NOTE: To use this method in conjunction with formvar-based
    sessioning, you'd need to encode a link to its URL with the
    session token by using the session data manager's 'encodeUrl()'

    Using the 'mapping' Keyword With A Session Data Object in a 'dtml-with'

      DTML has the facility to treat a session data object as a
      mapping, making it easier to spell some of the more common
      methods of access to session data objects.  The 'mapping'
      keyword to dtml-with means "treat name lookups that follow
      this section as queries to my contents by name."  For

        <dtml-let a="sm.getSessionData()">
            <dtml-call "a.set('zopetime', ZopeTime())">
              'zopetime' will be set to a datetime object for the current
              session... the "set" it calls is the set method of the
              session data object.

        <dtml-with "sm.getSessionData()" mapping>
            <dtml-var zopetime>
              'dtml-var zopetime' will print the DateTime object just set
              because we've used the mapping keyword to map name lookups
              into the current session data object.

  Using Session Data From Python

    Here's an example of using a session data manager and session
    data object from a set of Python external methods::

      import time
      def setCurrentTime(self):
          sessiondatamgr = self.sessiondatamgr
          a = sessiondatamgr.getSessionData()
          a.set('thetime', time.time())

      def getLastTime(self):
          sessiondatamgr = self.sessiondatamgr
          a = sessiondatamgr.getSessionData()
          return a.get('thetime')

See Also

  - "Session API":SessionInterfaces.py

=== Products/Sessions/help/Sessions.stx 1.1 => 1.2 === (1252/1352 lines abridged)
+Session Tracking
-  This is the documentation to the Core Session Tracking product.
-  Session tracking allows you to keep state between HTTP requests for
-  anonymous users.
-  The Big Picture
-    There are four major components to the CoreSessionTracking design:
-      - Session Id Manager -- this is the component which determines a
-        remote client's session id.  The session id is contained in the
-        "session token", which is encoded in a form or cookie variable.
-        The session id manager examines and modifies cookie and
-        form variables to determine or set the client's session id.
-        There may be more than one session id manager in a Zope
-        installation, but commonly there will only be one.  Application
-        developers will generally not talk directly to a session id
-        manager.  Instead, they will talk to session data managers,
-        which will delegate some calls to a session id manager.  Session
-        id managers have "fixed" Zope ids so they can be found via
-        acquisition by session data managers.
-      - Session Data Manager -- this is the component which is
-        responsible for handing out session data to callers.  When
-        session data is required, the session data manager talks to a
-        session id manager to determine the current session token and
-        creates a new session data object or hands back an existing
-        session data object based on the token.  It also has interfaces
-        for encoding a URL with session information and performing other
-        utility functions.  Developers will generally use methods of
-        session data managers to obtain session data objects when
-        writing application code.  Many session data managers can use
-        one session id manager.  Many session data managers can be
-        instantiated on a single Zope installation.  Different session
-        data managers can implement different policies related to
-        session data object storage (e.g. to which session data
-        container the session data objects are stored).
-      - Session Data Container -- this is the component which actually
-        holds information related to sessions.  Currently, it is used to
-        hold a special "session data object" instance for each ongoing
-        session.  Developers will generally not interact with session
-        data containers.  The current implementation defines two types
-        of session data containers: internal and external.  "Internal"
-        session data containers are RAM-based, and they are available
-        for use on a per-session-data-manager basis, while "external"
-        session data containers are persistent Zope objects which may be
-        used to store (and persist) session data objects. External
-        session data containers are traversable, and they are meant to

[-=- -=- -=- 1252 lines omitted -=- -=- -=-]

+    To set up sessions on a Zope system, you must add:
+    	- A Browser ID Manager named "browser_id_manager"
+	- A Session Data Manager
+	- A Transient Object Container
+    To facilitate sessions on systems without ZEO, you may wish to create
+    a *Temporary Folder* to store your Transient Objects.
+  Usage
+    The simplest way to use sessions is to activate the "Automatic Session"
+    feature in the Session Data Manager object.  This will cause a session
+    object to be fetched or created if necessary and stored in the 'REQUEST'
+    object under the name 'SESSION'.
+    This 'SESSION' object behaves as a dictionary, so the following python
+    script would demonstrate incrementing a counter in the session::
+    	request = context.REQUEST
+	session = request.SESSION
+	counter = session.get('counter',0) + 1
+	session['counter'] = counter
+    For more advanced programming details, see the *Session API* documentation.
+  Networking with ZEO
+    It is important to note that in a ZEO environment, the default Zope
+    configuration which includes an already established Temporary Folder and
+    Transient Object container will not yeild the desired results; Temporary
+    Folders store their data **locally** and do not store information in ZEO,
+    thus any session data stored in a Temporary Folder will not be
+    distributed to other ZEO clients.
+  See Also
+    - "Transient Objects":../../Transience/Help/Transience.stx
+    - "Temporary Folders":../../TemporaryFolder/Help/TemporaryFolder.stx
+    - "Session API":SessionInterfaces.py
+    - "Session API Programming":sessionapi-prog.stx
+    - "Session Administration":session-admin.stx