Summary of Changes

This chapter describes the changes made to Albatross between releases.

Release 1.42.

This section describes the changes made to Albatross since release 1.40.

Incompatibilities

  • As of version 1.42, Albatross no longer supports Python 2.3 - version 2.4 or up is required (Python 3 is not supported at this time).
  • Application.handle_exception(ctx, req) no longer escapes the python and template tracebacks before executing any application-supplied trackback template. As this change could result in a potential security problem, the application-supplied exception template has been renamed from traceback.html to uncaught_exception.html. If you used this functionality, you must remove “noescape” from your `traceback.html` template before renaming it to uncaught_exception.html.
  • SessionExpired handling was made consistent across session models and SessionExpired is now caught by the Application.run() method. When run() catches a SessionExpired exception, it calls Application.handle_session_expired(). This method attempts to display an application-supplied session_expired.html template before falling back to an internal “Your session has expired” message.
  • The noescape attribute (which disables the escaping of special HTML characters) is now only honoured for tag content, not tag attributes. Formerly, noescape on a tag would turn off escaping of all attributes and tag content. On reflection, this is too broad to be used safely. The noescape attribute will now raise an exception if used on any tag other than <al-option>, <al-select>, <al-textarea> or <al-value>, and only applies to the tag content. The new htmlsafe() mechanism provides an alternative way to disable escaping of evaluated attributes (see Escaping generated content).
  • The session daemon al-session-daemon and the stand-alone development server al-httpd are now part of the Albatross command line tool. Usage remains largely the same, but rather than invoking al-session-daemon start, use albatross session-server start, and rather than al-httpd module.app 8080, use albatross serve --port=8080 module.app. You can also symlink the albatross script to al-session-daemon and al-httpd. For more information on the session server, see Session Server Daemon, and for more information on the stand-alone development server, see Stand-alone Python HTTP Server Deployment.

New Features

  • Template evaluation namespaces

    Evaluation of expressions in templates normally takes place within the scope of ctx.locals. The new <al-namespace> tag allows you to switch temporarily to a subordinate namespace. Expression evaluation will take place with respect to that namespace, and input names will automatically be prefixed with the name of the namespace.

    For example:

    class Field:
        prompt = 'Enter age'
        data = 23
    
    field = Field()
    

    And

    <al-namespace name="field">
        <al-value expr="prompt">: <al-input name="data" whitespace>
    </al-namespace>
    

    Would produce:

    Enter age: <input name="field.data" value="23" />
    

    A namespace="..." attribute has also been added to the <al-expand> and <al-for> tags allowing you to execute their contained content in the specified namespace.

  • Easier selection of Application and Context classes

    A new get_app_classes(page_model, context_model) function has been added that makes choosing Application and Context classes easier. Previously, you had to choose between one of twelve Application classes and match this with an appropriate Context class. With the get_app_classes() function, you just need to choose a page model and a session model, and the appropriate Application and Context classes are returned. For more information, see Prepackaged Application and Execution Context Classes.

  • Albatross command line and quick-start application skeleton

    An albatross command line utility has been added. This utility currently has four sub-commands:

    • create - creates the basic framework of an application.
    • add-page - adds a page to an application so created.
    • serve - starts a stand-alone development server for the specified application.
    • session-server - starts a session server (see Session Server Daemon for more information).

    This makes it very easy to get started writing Albatross applications:

    $ albatross create myapp
    $ cd myapp
    $ ls
    app.ini  app.py  pages      session  static
    $ ls pages
    environment.html  macros.html  new_session.py       session_expired.html
    environment.py    main.html    page_not_found.html  uncaught_exception.html
    __init__.py       main.py      raise_exception.py   unhandled_exception.html
    1$ ls static
    alxform.css  favicon.ico  logo.png  style.css
    $ albatross serve
    Starting web server for "myapp" on port 8000
    Stop the server with Ctrl-C
    http://localhost:8000/
    

Enhancements

  • A new alternative to the noescape attribute has been implemented that allows a data source to signal that a given string does not require escaping when it is rendered by template execution by casting it to the htmlsafe() type. This moves the responsibility for this potentially risky action from the template closer to the code that generated the string. The htmlsafe() type can also be used to selectively disable the escaping of evaluated attributes.

    While the “noescape” attribute still works, it’s scope has been reduced, and it should be considered deprecated.

  • RandomModular applications will now attempt to render an application-supplied page_not_found.html template, before falling back to an internal “URL .. was not found on this server” message.

  • A simple logging mechanism has been added. Calling the Application.set_logger(logger) method with a logger compatible with the standard python logging module registers that logger with the application. Exceptions will be logged to the logger at “error” level, and a ctx.log(msg) method allows messages to be logged at “info” level.

Bug Fixes

  • If an application supplied it’s own traceback.html template, the HTML headers would be emitted twice. Also see the important note above regarding escaping of the tracebacks and renaming the template.
  • PageModuleMixin.load_page_module() now raises a new PageNotFound exception (a subclass of ApplicationError) if the page module is not found. This addresses a bug where the RandomPageModuleMixin would not reliably handle an unknown page.
  • The standard exception handling bypasses the context logic, writing directly to the Request object. This created an issue with the session cookie not being cleared when an exception occurred. The exception handler now explicitly adds a “Set-Cookie:” header to clear the application cookie.

Release 1.40.

This section describes the changes made to Albatross since release 1.36.

Major Changes

  • Conversion of documentation to reStructuredText

    With the Python documentation moving from LaTeX markup to reStructuredText and the Sphinx documentation generator, we could no longer rely on the documentation utilities released with Python. The Albatross documentation has been converted to ReST, and uses Sphinx to render this to HTML and PDF formats.

  • Albatross Forms

    A simple HTML form generation and validation framework has been added to Albatross (as an optional extension under the module name albatross.ext.form).

Bug Fixes

  • Redirects were not calling req.return_code() - for FastCGI deployment, this meant the request would hang [11164].
  • The python built-in __import__() gained extra arguments with python 2.6 - the decode session import hook has been changed to pass all arguments (positional and keyword) [14823].
  • When rendering tags to HTML, the handling of the noescape attribute was not consistently honoured. Attribute rendering has been moved to the common Tag base class as the write_attrib() method [15398].
  • Relaxed tag recognition regular expressions, so that malformed tag attributes with no value, such as <al-input name= />, are still recognised as valid Albatross tags, albeit with a null name attribute (which subsequently generates an error) [15398].

Miscellaneous Changes

  • Miscellaneous changes to RedHat, Ubuntu, Solaris and OS X packaging rules.
  • Reorganised the unit tests to eliminate the use of explicitly assembled test suites, relying instead on the unittest module to collect methods of TestCase subclasses. The documentation example tests were also reimplemented as TestCase subclasses, allowing them to be run via common test driver.

Release 1.36

This section describes the changes in release 1.36 of Albatross that were made since release 1.35.

New Features

New <al-for vars=”...”> attribute

A vars attribute has been added to <al-for> - this inserts the iterator value into the local namespace. The iterator value was previously only accessible via the iterator value() method.

<al-for> now accepts iterators

<al-for> now loops over sequences using the iterator protocol by default. The previous behaviour of indexing the sequence is retained where pagination or columns are requested.

Default arguments for macros using <al-setdefault>

New <al-setdefault> tag which allows macros to define default values for their arguments (suggested by Greg Bond).

<al-expand> argument shorthand

Macro expansion can now use attributes on the <al-expand> tag to specify macro arguments (suggested by Greg Bond).

Access to HTTP environment variables

Added get_param() method to Request classes, which deployment method agnostic access to http “environment” variables.

Functional Changes

Safer request merging

NameRecorderMixin no longer falls back to merging all request fields if no __albform__ field is present. Applications using the NameRecorderMixin and GET-style requests will need to explicitly merge relevent fields with the ctx.merge_vars(...) method.

Switch from MD5 to SHA1

Pickles embedded in hidden fields are now signed using the HMAC-SHA1 algorithm (was MD5).

New FastCGI driver now default

The experimental FastCGI driver included in version 1.35 now becomes the default FastCGI driver. The old driver has been renamed fcgiappold. The new driver implements the FastCGI protocol itself, rather than depending on an external module.

Bug Fixes

<al-option> fixes

If the <al-option> tag was not immediately enclosed within an <al-select> tag, it would be silently ignored. <al-option> now works within containing flow control tags such as <al-for> or <al-if>, has improved error reporting, and supports attributes for dynamically setting value and label.

Session server client code enhancements

Communication with the session server has been made more robust. EINTR is handled, as are partial reads and writes, and requests are restarted if the socket closes.

Fix to input type recording

Mixing radio inputs with other inputs of the same name did not raise an exception (reported by Michael Neel).

Fixed incorrect constant in FastCGI driver

FCGI_MAX_DATA was incorrect due to an operator precedence mistake. Found by Tom Limoncelli.

Miscellaneous Changes

Clean up pre-python 2.2 constructs

Cleaned up and replaced many pre-python 2.2 constructs.

New and updated unit tests

Many new tests have been added, and existing tests restructured.

Release 1.35

This section describes the changes in release 1.35 of Albatross that were made since release 1.34. Note that release 1.34 was an internal release.

New Features

New FastCGI module

A drop-in replacement for the fcgiapp module, called fcgiappnew has been added. This version implements the FastCGI protocol itself, rather than relying on an external module to implement the protocol (we have not been able to clarify the license of the fcgi.py module). This new module addresses several minor problems with fcgi.py, and should be faster, although it should not be used in critical applications until it has received wider testing. This module will eventually be renamed to replace fcgiapp (at which point, the fcgiappnew name will dropped).

Functional Changes

Validate extension tag names

When extension tags (alx-*) are registered, their name is now checked against the template parsing regexp to ensure they can subsequently be matched.

Bug Fixes

Enhance AnyTag with knowledge of empty HTML tags

The AnyTag functionality was given knowledge of HTML tags for which the close tag is forbidden, so it can avoid generating XHTML empty tag (which could cause the page to fail HTML validation).

Input tags with disabledbool attribute

When the disabledbool attribute was used on input tags, the disabled state was not being passed through to the input registry within the NameRecorderMixin.

Improve session server handling of aborted connections

If a client closed it’s connection to the session server while the server had data pending for the client, a subsequent del_write_file would generate an exception, killing the session server.

Release 1.33

This section describes the changes in release 1.33 of Albatross that were made since release 1.32.

Bug Fixes

ctx.set_value()

Fixed handling of tree iterator backdoor and improved error reporting.

Release 1.32

This section describes the changes in release 1.32 of Albatross that were made since release 1.31.

Bug Fixes

_caller_globals()

To obtain a reference to the current frame, _caller_globals was raising and catching an exception, then extracting the tb_frame member of sys.exc_traceback. sys.exc_traceback was deprecated in python 1.5 as it is not thread-safe. It now appears to be unreliable in 2.4, so _caller_globals has been changed to use sys._getframe().

ctx.set_page() from start page

If ctx.set_page() was called from within the start page, then the wrong page methods (page_enter, page_display, etc) would be called (those of the initial page, rather than the page requested via set_page).

Release 1.31

This section describes the changes in release 1.31 of Albatross that were made since release 1.30.

Bug Fixes

RandomPage error handling

Fixes to handling of missing RandomPage page modules.

Release 1.30

This section describes the changes in release 1.30 of Albatross that were made since release 1.20.

Functional Changes

Evaluate any attribute of any tag

Arbitrary HTML tags can now access the templating engine by prefixing the tag with “al-”. Attributes of the tag can then be selectively evaluated to derive their value. Appending “expr” to the attribute name causes the result of evaluating the expression to be substituted for the value of the attribute. Appending “bool” results in the attribute value being evaluated in a boolean context, and if true, a boolean HTML attribute is emitted. For example:

<al-td colspanexpr="i.span()">

could produce

<td colspan="3">

and:

<al-input name="abc.value" disabledbool="abc.isdisabled()">

could produce

<input name="abc.value" disabled>

Enforce only one definition of macros and lookups

Since macros and lookups are an application global resource, they can only be defined once per application, however this was not previously enforced. Redefinition of macros or lookups will now result in an ApplicationError exception.

In-line expansion of <al-lookup>

The <al-lookup> tag can now be optionally expanded in place. If the tag has an expr= attribute, this will be evaluated and used as the value to look up, and the results of the lookup substituted for the tag.

Functionality of named lookups remains unchanged.

New <al-require> tag

A new <al-require> tag has been added to allow templates to assert that specific Albatross features are available, or templating scheme version number is high enough. For instance, the addition of the “Any Tag” functionality has resulting in the templating version incrementing from 1 to 2.

Set Cache-Control header

Cache-Control: no-cache is now set in addition to Pragma: no-cache.

Cache-Control was introduced in HTTP/1.1, prior to this the same effect was achieved with Pragma. Some browsers change their behaviour depending on whether the page was delivered via HTTP/1.1 or HTTP/1.0.

Bug Fixes

FastCGI finalisation

FastCGI apps were not being explicitly finalised, relying instead on their object destructor, with the result that writing application output (or errors) would be indefinitely deferred if object cycles existed. We now call fcgi.Finish() from the fcgiapp Request.return_code() method.

Delete traceback objects

When handling exceptions, the traceback is now explicitly deleted from the local namespace to prevent cycles (otherwise the garbage collection of other objects in the local namespace will be delayed).

<al-select> fixes

Two fixes to the <al-select> tag: the albatross-specific “list” attribute was leaking into resulting markup, and the use of the “expr” attribute would result in invalid markup being emitted.

Illegal placement of <input> tag

Thanks to Robert Fendt for picking this up: the Albatross-generated hidden field input element must not appear naked inside a form element for strict HTML conformance. The solution is to wrap the input elements in div.

Allow BranchingSessions to be deleted

BranchingSession sessions could not be “deleted” because each interaction is a separate session. The solution implemented is to add a dummy “session” shared by all branches, which is deleted when one branch “logs out”.

Release 1.20

This section describes the changes in release 1.20 of Albatross that were made since release 1.11.

Functional Changes

New BranchingSessionContext

A persistent problem with server-side sessions is the browser state getting out of synchronisation with the application state. This occurs when the user reloads the page or uses the “back” button.

A new BranchingSessionContext application context class has been added that attempts to work around this problem by creating a new server-side session for every interaction with the browser. The unique session identifier is stored in a hidden form field, rather than a cookie.

The new Context class is intended to be used with the server-side Application classes, and provides a similar experience to storing the context in a hidden form field, without the overhead and security issues of sending the context on a round-trip through the user’s browser.

No effort is made at this time to control the resources used by these server- side sessions, other than expiring them after session_age seconds.

Improved Request classes

The Request classes provide the interface between specific application deployment models (CGI, FastCGI, mod_python, etc), and the Albatross application. These classes have been refactored to extract common functionality into a new RequestBase class. The Request classes also now have methods for passing status back to browser.

Page Module loading

The page module loader in PageModuleMixin has been reimplemented so that it does not pollute sys.modules. Page modules are now loaded into a synthetic module’s namespace, rather than the global module namespace. This will break code that defined classes in page modules and placed instances of those classes into the session.

Multi-instance response headers now supported

Some HTTP headers can appear multiple times (for example Set-Cookie) - the response handling has been modified to allow multiple instances of a header. ResponseMixin.get_header() now returns a list of strings, rather than just a string. The httpdapp module has also been updated to allow multiple instances of a header, keeping headers in a list rather than a dictionary.

simpler req_equals() matching with image maps

ctx.req_equals(name) now checks for name.x if name is not found. This makes using image maps as buttons easier (from Michael C. Neel).

Bug Fixes

redirect_url() fixes

Under some circumstances, redirect_url() would redirect to incorrect or invalid URLs (for example, an https app would redirect to http) - the URI parsing has been refactored, and this bug has been fixed. Tests were also added for the refactored URI parsing.

Improved request status handling

  1. Symbolic names are now defined for the RFC1945 status header values, such as HTTP_OK, HTTP_MOVED_PERMANENTLY, HTTP_MOVED_TEMPORARILY and HTTP_INTERNAL_SERVER_ERROR
  2. The Request classes (deployment model adaptors) and Application run() method have been updated to correctly pass the returned status back to the client.

Response header matching now case-insensitive

Response header names were being matched in a case-sensitive way - this was incorrect and has been fixed.

Release 1.11

This section describes the changes in release 1.11 of Albatross that were made since release 1.10.

Functional Changes

<al-select>/<al-input> consistency

<al-select> handling of name, expr, valueexpr and value attributes has been made consistent with that of <al-input>.

absolute_base_url method

New method absolute_base_url() has been added to the AppContext.

al-httpd enhancements

Matt Goodall has continued to improve the capabilities of the al-httpd program and httpdapp.py so that it is now possible to run all of the CGI based sample applications.

You can now initialise the static_resources from the command line. For example, the tree samples can be executed to serve up their images like this:

$ cd samples/tree2
$ al-httpd tree.app 8080 /alsamp/images ../images/

XHTML fixes

The <al-input> and <al-img> tags now output XHTML compliant end tags.

Bug Fixes

mod_python support

Greg Bond fixed a cgiapp field handling incompatibility with mod_python 3.

get_servername() support

The get_servername() method of the cgiapp and fcgiapp Request classes now use the HTTP_HOST environment variable rather than SERVER_NAME.

Multiple cookies

All session cookies now include a path attribute. This prevents multiple redundant cookies being set for all URI paths in an application.

Release 1.10

This section describes the changes in release 1.10 of Albatross that were made since release 1.01.

Functional Changes

FastCGI support

Matt Goodall developed support for deployment of applications via FastCGI. FastCGI applications import their Request class from albatross.fcgiapp.

Standalone BaseHTTPServer support

Matt Goodall developed support for standalone deployment of applications via the standard Python BaseHTTPServer module. The al-httpd program can be used to deploy a CGI application as a standalone BaseHTTPServer server.

Exception Classes

All Albatross exceptions have been redefined to indicate the source of the error; user (UserError), programmer (ApplicationError), or Albatross itself (InternalError). The ServerError exception reports problems related to the session server, SecurityError reports either a programmer error, or a user attempt to access restricted values in the execution context, and TemplateLoadError reports failures to load templates.

All of the exceptions inherit from AlbatrossError.

The albatross.common module defines the exceptions.

Response Header Management

All response header management has been moved to the ResponseMixin class. The AppContext class now inherits from ResponseMixin. The Request class no longer tracks whether or not headers have been sent.

ResponseMixin provides the ability to set, get, delete, and send headers. Headers are automatically sent when the application sends any content to the browser.

The write_headers() method has been deleted from the following classes; SimpleAppContext, SessionAppContext, SessionServerContextMixin, SessionFileContextMixin, SessionFileAppContext.

For SessionServerContextMixin and SessionFileContextMixin the Set-Cookie header is set when session is created or loaded.

HTTP Response Codes

The Application.run() method no longer unconditionally returns an HTTP response code of 200. The returned response code is retrieved from the Request.status() method. You can call the Request.set_status() method to override the default HTTP response code of 200.

File Uploading

The <al-input> tag now supports type="file" input tags. When you use file input tags the enclosing <al-form> tag automatically adds the enctype="multipart/form-data" attribute to the generated <form> tag.

The albatross.cgiapp and albatross.apacheapp modules define a FileField class which provides access to uploaded files. During request merging the Request.field_file() method returns instances of FileField for uploaded files.

Session Changes

The Application.run() method now saves the session before flushing the response to the browser. This allows applications to support dynamically generated images.

The SessionBase.add_session_vars() method now raises an ApplicationError exception if you attempt to add variables to the session which do not exist in the local namespace.

The SessionBase.default_session_var() method allows you to add a variable to the session and place it in the local namespace at the same time.

Session saving previously silently removed session values which could not be pickled. Now unpickleable values are reported via an ApplicationError exception.

Errors handling and reporting during session loading has been improved.

Exception Formatting and Handling

The exception formatting in Application.handle_exception() has been moved into the format_exception() method. Applications can perform their own exception formatting and/or send formatted exceptions to locations other than the browser.

Unicode

The ExecuteMixin.write_content() method now converts unicode to UTF-8.

Execution Context Available to Template Expressions

During NamespaceMixin.eval_expr() the execution context is temporary placed into the local namespace as the variable __ctx__.

Request Merging

NamespaceMixin.set_value() ignores attempts to set Albatross iterators that are not present in the namespace.

NamespaceMixin.set_value() produces a nice syntax error like report when an illegal field name is used.

Locating Globals for Template Expressions

The _caller_globals() function has been changed to use the name of a function rather a stack frame count. This is used by the methods AppContext.run_template(), AppContext.run_template_once(), RandomPageModuleMixin.display_response(), and SimpleContext.__init__() to locate the module whose globals will be used as the global namespace for evaluating template expressions.

Tree Handling

The <al-tree> tag now has a single attribute which enables the single select mode. In single select mode, selecting a node automatically deselects any previously selected node.

The <al-input> tag now supports the treefold="expr", treeselect="expr", and treeellipsis="expr" attributes. The expression specifies a tree node that is used to construct a tree iterator input value.

The following methods have been added to the LazyTreeIterator class; load_children(), is_selected(), select_alias(), open_alias().

Lookup Evaluation

The <al-lookup> tag now registers the lookup during template parsing rather than during evaluation. This allows template code to make use of lookups that are defined later in the same file. The item dictionary is created the first time that the lookup is used rather than when the template is interpreted.

Macro Argument Evaluation

Macro arguments are now evaluated when they are referenced rather than before they are passed to a macro.

This removes a limitation where you could not define macros including <al-form> tags that retrieved <al-input> tags from their arguments. Previously the <al-input> tags passed as macro arguments would have been evaluated outside of the context of the form defined in the macro. This effectively made the input tags invisible to the form recorder.

<select>/<option> formatting

The <al-option> and <al-select> tags always write </option> close tags.

noescape tag attribute

The noescape attribute has been added to the <al-input>, <al-img>, <al-select>, and <al-textarea> tags.

Documentation

The templates reference documentation has been completely restructured to improve clarity. All attributes of each tag have been documented.

Bug Fixes

Lingering Content Trap

In some circumstances exceptions would leave a content trap in place that prevented an error report from being written to the browser.

Session Loading

More exceptions are trapped by the session unpickling code to make error handling more robust.

Random Page Module Loading

Fixed a bug where an import error inside a page module loaded by the RandomPageModuleMixin was being handled as if page module could not be located.

<al-input> tag

Fixed bug in checkbox.

Only prevent the generation of the value attribute when the value is None.

<al-input> tag

The apacheapp Request class now works for mod_python 2.3 and 3.0.

Table Of Contents

Previous topic

Prepackaged Application and Execution Context Classes

This Page