zope.publisher¶

This package allows you to publish Python objects on the web. It has support for plain HTTP/WebDAV clients, web browsers as well as XML-RPC and FTP clients. Input and output streams are represented by request and response objects which allow for easy client interaction from Python. The behaviour of the publisher is geared towards WSGI compatibility.
Documentation is hosted at https://zopepublisher.readthedocs.io/
Base API Reference¶
Interfaces¶
Interfaces for the publisher.
-
exception
zope.publisher.interfaces.
Retry
(orig_exc=None)[source]¶ Bases:
zope.publisher.interfaces.PublishingException
Raise this to retry a request.
orig_exc must be a 3-tuple as returned from sys.exc_info() or None
-
interface
zope.publisher.interfaces.
IExceptionSideEffects
[source]¶ An exception caught by the publisher is adapted to this so that it can have persistent side-effects.
-
__call__
(obj, request, exc_info)¶ Effect persistent side-effects.
- Arguments are:
- obj context-wrapped object that was published request the request exc_info the exception info being handled
-
-
interface
zope.publisher.interfaces.
IResponse
[source]¶ Interface used by the publsher
-
setResult
(result)¶ Sets the response result value.
-
handleException
(exc_info)¶ Handles an exception.
This method is intended only as a convenience for the publication object. The publication object can choose to handle exceptions by calling this method. The publication object can also choose not to call this method at all.
Implementations set the reponse body.
-
internalError
()¶ Called when the exception handler bombs.
Should report back to the client that an internal error occurred.
-
reset
()¶ Reset the output result.
Reset the response by nullifying already set variables.
-
retry
()¶ Returns a retry response
Returns a response suitable for repeating the publication attempt.
-
-
interface
zope.publisher.interfaces.
IPublication
[source]¶ Object publication framework.
The responsibility of publication objects is to provide application hooks for the publishing process. This allows application-specific tasks, such as connecting to databases, managing transactions, and setting security contexts to be invoked during the publishing process.
-
beforeTraversal
(request)¶ Pre-traversal hook.
This is called once before any traversal has been done.
-
getApplication
(request)¶ Returns the object where traversal should commence.
-
callTraversalHooks
(request, ob)¶ Invokes any traversal hooks associated with the object.
This is called before traversing each object. The ob argument is the object that is about to be traversed.
-
traverseName
(request, ob, name)¶ Traverses to the next object.
Name must be an ASCII string or Unicode object.
-
afterTraversal
(request, ob)¶ Post-traversal hook.
This is called after all traversal.
-
callObject
(request, ob)¶ Call the object, returning the result.
For GET/POST this means calling it, but for other methods (including those of WebDAV and FTP) this might mean invoking a method of an adapter.
-
afterCall
(request, ob)¶ Post-callObject hook (if it was successful).
-
handleException
(object, request, exc_info, retry_allowed=1)¶ Handle an exception
Either: - sets the body of the response, request.response, or - raises a Retry exception, or - throws another exception, which is a Bad Thing.
-
endRequest
(request, ob)¶ Do any end-of-request cleanup
-
-
interface
zope.publisher.interfaces.
IPublicationRequest
[source]¶ Extends:
zope.security.interfaces.IParticipation
Interface provided by requests to IPublication objects
-
response
¶ The request’s response object
Return an IPublisherResponse for the request.
-
close
()¶ Release resources held by the request.
-
hold
(held)¶ Hold a reference to an object until the request is closed.
The object should be an IHeld. If it is an IHeld, its release method will be called when it is released.
-
getTraversalStack
()¶ Return the request traversal stack
This is a sequence of steps to traverse in reverse order. They will be traversed from last to first.
-
setTraversalStack
(stack)¶ Change the traversal stack.
See getTraversalStack.
-
getPositionalArguments
()¶ Return the positional arguments given to the request.
-
setPrincipal
(principal)¶ Set the principal attribute.
It should be IPrincipal wrapped in its AuthenticationService’s context.
-
-
interface
zope.publisher.interfaces.
IHeld
[source]¶ Object to be held and explicitly released by a request
-
release
()¶ Release the held object
This is called by a request that holds the IHeld when the request is closed
-
-
interface
zope.publisher.interfaces.
IPublisherRequest
[source]¶ Extends:
zope.publisher.interfaces.IPublicationRequest
Request interface use by the publisher
The responsibility of requests is to encapsulate protocol specific details, especially wrt request inputs.
Request objects also serve as “context” objects, providing construction of and access to responses and storage of publication objects.
-
supportsRetry
()¶ Check whether the request supports retry
Return a boolean value indicating whether the request can be retried.
-
retry
()¶ Return a retry request
Return a request suitable for repeating the publication attempt.
-
publication
¶ The request’s publication object
The publication object, an IRequestPublication provides application-specific functionality hooks.
-
setPublication
(publication)¶ Set the request’s publication object
-
traverse
(obj)¶ Traverse from the given object to the published object
The published object is returned.
The following hook methods on the publication will be called:
- callTraversalHooks is called before each step and after the last step.
- traverseName to actually do a single traversal
-
processInputs
()¶ Do any input processing that needs to be done before traversing
This is done after construction to allow the publisher to handle errors that arise.
-
-
interface
zope.publisher.interfaces.
IDebugFlags
[source]¶ Features that support debugging.
-
sourceAnnotations
¶ Enable ZPT source annotations
-
showTAL
¶ Leave TAL markup in rendered page templates
-
-
interface
zope.publisher.interfaces.
IApplicationRequest
[source]¶ Extends:
zope.interface.common.mapping.IEnumerableMapping
Features that support application logic
-
principal
¶ Principal object associated with the request This is a read-only attribute.
-
bodyStream
¶ The stream that provides the data of the request.
The data returned by the stream will not include any possible header information, which should have been stripped by the server (or previous layer) before.
Also, the body stream might already be read and not return any data. This is commonly done when retrieving the data for the
body
attribute.If you access this stream directly to retrieve data, it will not be possible by other parts of the framework to access the data of the request via the
body
attribute.
-
debug
¶ Debug flags (see IDebugFlags).
-
__getitem__
(key)¶ Return request data
The only request data are environment variables.
-
environment
¶ Request environment data
This is a read-only mapping from variable name to value.
-
annotations
¶ Stores arbitrary application data under package-unique keys.
By “package-unique keys”, we mean keys that are are unique by virtue of including the dotted name of a package as a prefex. A package name is used to limit the authority for picking names for a package to the people using that package.
For example, when implementing annotations for hypothetical request-persistent adapters in a hypothetical zope.persistentadapter package, the key would be (or at least begin with) the following:
"zope.persistentadapter"
-
-
interface
zope.publisher.interfaces.
IRequest
[source]¶ Extends:
zope.publisher.interfaces.IPublisherRequest
,zope.publisher.interfaces.IPublicationRequest
,zope.publisher.interfaces.IApplicationRequest
The basic request contract
-
interface
zope.publisher.interfaces.
IRequestEvent
[source]¶ An event which is about or for a request.
-
request
¶ The request this event is about.
-
-
interface
zope.publisher.interfaces.
IEndRequestEvent
[source]¶ Extends:
zope.publisher.interfaces.IRequestEvent
An event which gets sent when the publication is ended.
-
interface
zope.publisher.interfaces.
IStartRequestEvent
[source]¶ Extends:
zope.publisher.interfaces.IRequestEvent
An event which gets sent before publication of a request.
-
class
zope.publisher.interfaces.
RequestEvent
(request)[source]¶ Bases:
object
Events for requests.
Parameters: request – The request the event is for.
-
class
zope.publisher.interfaces.
EndRequestEvent
(ob, request)[source]¶ Bases:
zope.publisher.interfaces.RequestEvent
An event which gets sent when the publication is ended
-
class
zope.publisher.interfaces.
StartRequestEvent
(request)[source]¶ Bases:
zope.publisher.interfaces.RequestEvent
An event send when before publication of a request.
-
interface
zope.publisher.interfaces.
ISkinType
[source]¶ Extends:
zope.interface.interfaces.IInterface
Base interface for skin types.
-
interface
zope.publisher.interfaces.
ISkinnable
[source]¶ A skinnable (request) can provide a skin.
The implementation in BrowserRequest will apply a default skin/layer called
IDefaultBrowserLayer
if not default skin get registered.
-
interface
zope.publisher.interfaces.
IDefaultSkin
[source]¶ Any component providing this interface must be a skin.
This is a marker interface, so that we can register the default skin as an adapter from the presentation type to IDefaultSkin.
-
interface
zope.publisher.interfaces.
ISkinChangedEvent
[source]¶ Extends:
zope.publisher.interfaces.IRequestEvent
Event that gets triggered when the skin of a request is changed.
-
interface
zope.publisher.interfaces.
IDefaultViewName
[source]¶ A string that contains the default view name
A default view name is used to select a view when a user hasn’t specified one.
-
interface
zope.publisher.interfaces.
IReRaiseException
[source]¶ An exception that should be reraised, when handled in publisher.
Under some circumstances (for instance if acting in a WSGI pipeline with debugger middleware) certain exceptions occuring while publishing should be handled by the Zope machinery and never reach the ‘outside world’.
Adapters providing this interface for a certain exception type which also return
False
when being called, indicate by this that the exception should not be reraised during publishing.This makes it possible, for instance, to authenticate with basic-auth when a debugger middleware is used and IUnauthorized is raised.
-
__call__
()¶ Return True if an exception should be re-raised
-
Implementation¶
Base implementations of the Publisher objects
Specifically, ‘BaseRequest’, ‘BaseResponse’, and ‘DefaultPublication’ are specified here.
-
class
zope.publisher.base.
BaseRequest
(body_instream, environ, response=None, positional=None)[source]¶ Bases:
object
Represents a publishing request.
This object provides access to request data. Request data may vary depending on the protocol used.
Request objects are created by the object publisher and will be passed to published objects through the argument name, REQUEST.
The request object is a mapping object that represents a collection of variable to value mappings.
-
publication
¶ See IPublisherRequest
-
bodyStream
¶ See zope.publisher.interfaces.IApplicationRequest
-
has_key
(key)¶ See Interface.Common.Mapping.IReadMapping
-
HTTP API Reference¶
Interfaces¶
HTTP-related publisher interfaces.
-
interface
zope.publisher.interfaces.http.
IVirtualHostRequest
[source]¶ The support for virtual hosts in Zope is very important.
In order to make virtual hosts working, we need to support several methods in our Request object. This interface defines the required methods.
-
setVirtualHostRoot
(names)¶ Marks the currently traversed object as the root of a virtual host.
Any path elements traversed up to that
Set the names which compose the application path. These are the path elements that appear in the beginning of the generated URLs.
Should be called during traversal.
-
getVirtualHostRoot
()¶ Returns the object which is the virtual host root for this request
Return None if setVirtualHostRoot hasn’t been called.
-
setApplicationServer
(host, proto='http', port=None)¶ Override the host, protocol and port parts of generated URLs.
This affects automatically inserted <base> tags and URL getters in the request, but not things like @@absolute_url views.
-
shiftNameToApplication
()¶ Add the name being traversed to the application name
This is only allowed in the case where the name is the first name.
A Value error is raised if the shift can’t be performed.
-
-
interface
zope.publisher.interfaces.http.
IHTTPApplicationRequest
[source]¶ Extends:
zope.publisher.interfaces.IApplicationRequest
,zope.publisher.interfaces.http.IVirtualHostRequest
HTTP request data.
This object provides access to request data. This includes, the input headers, server data, and cookies.
Request objects are created by the object publisher and will be passed to published objects through the argument name, REQUEST.
The request object is a mapping object that represents a collection of variable to value mappings. In addition, variables are divided into four categories:
Environment variables
These variables include input headers, server data, and other request-related data. The variable names are as <a href=”http://hoohoo.ncsa.uiuc.edu/cgi/env.html“>specified</a> in the <a href=”http://hoohoo.ncsa.uiuc.edu/cgi/interface.html“>CGI specification</a>
Cookies
These are the cookie data, if present.
Other
Data that may be set by an application object.
The request object may be used as a mapping object, in which case values will be looked up in the order: environment variables, other variables, cookies, and special.
-
__getitem__
(key)¶ Return HTTP request data
Request data sre retrieved from one of:
Environment variables
These variables include input headers, server data, and other request-related data. The variable names are as <a href=”http://hoohoo.ncsa.uiuc.edu/cgi/env.html“>specified</a> in the <a href=”http://hoohoo.ncsa.uiuc.edu/cgi/interface.html“>CGI specification</a>
Cookies
These are the cookie data, if present.
Cookies are searched before environmental data.
-
getCookies
()¶ Return the cookie data
Data are returned as a mapping object, mapping cookie name to value.
Request cookie data
This is a read-only mapping from variable name to value.
-
getHeader
(name, default=None, literal=False)¶ Get a header value
Return the named HTTP header, or an optional default argument or None if the header is not found. Note that both original and CGI-ified header names are recognized, e.g. ‘Content-Type’, ‘CONTENT_TYPE’ and ‘HTTP_CONTENT_TYPE’ should all return the Content-Type header, if available.
If the literal argument is passed, the header is searched ‘as is’, eg: only if the case matches.
-
headers
¶ Request header data
This is a read-only mapping from variable name to value. It does not support iteration.
-
URL
¶ Request URL data
When converted to a string, this gives the effective published URL.
This object can also be used as a mapping object. The key must be an integer or a string that can be converted to an integer. A non-negative integer returns a URL n steps from the URL of the top-level application objects. A negative integer gives a URL that is -n steps back from the effective URL.
For example, ‘request.URL[-2]’ is equivalent to the Zope 2 ‘request[“URL2”]’. The notion is that this would be used in path expressions, like ‘request/URL/-2’.
-
getURL
(level=0, path_only=False)¶ Return the published URL with level names removed from the end.
If path_only is true, then only a path will be returned.
-
getApplicationURL
(depth=0, path_only=False)¶ Return the application URL plus depth steps
If path_only is true, then only a path will be returned.
-
interface
zope.publisher.interfaces.http.
IHTTPPublisher
[source]¶ Extends:
zope.publisher.interfaces.IPublishTraverse
HTTP Publisher
-
interface
zope.publisher.interfaces.http.
IHTTPView
[source]¶ Extends:
zope.browser.interfaces.IView
HTTP View
-
interface
zope.publisher.interfaces.http.
IHTTPApplicationResponse
[source]¶ HTTP Response
-
redirect
(location, status=302, trusted=False)¶ Causes a redirection without raising an error.
By default redirects are untrusted which restricts target URLs to the same host that the request was sent to.
If the trusted flag is set, redirects are allowed for any target URL.
-
-
interface
zope.publisher.interfaces.http.
IHeaderOutput
[source]¶ Interface for setting HTTP response headers.
This allows the HTTP server and the application to both set response headers.
zope.publisher.http.HTTPResponse is optionally passed an object which implements this interface in order to intermingle its headers with the HTTP server’s response headers, and for the purpose of better logging.
-
setResponseStatus
(status, reason)¶ Sets the status code and the accompanying message.
-
setResponseHeaders
(mapping)¶ Sets headers. The headers must be Correctly-Cased.
-
appendResponseHeaders
(lst)¶ Sets headers that can potentially repeat.
Takes a list of strings.
-
wroteResponseHeader
()¶ Returns a flag indicating whether the response
header has already been sent.
-
setAuthUserName
(name)¶ Sets the name of the authenticated user so the name can be logged.
-
-
interface
zope.publisher.interfaces.http.
IResult
[source]¶ An iterable that provides the body data of the response.
For simplicity, an adapter to this interface may in fact return any iterable, without needing to strictly have the iterable provide IResult.
IMPORTANT: The result object may be held indefinitely by a server and may be accessed by arbitrary threads. For that reason the result should not hold on to any application resources (i.e., should not have a connection to the database) and should be prepared to be invoked from any thread.
This iterable should generally be appropriate for WSGI iteration.
Each element of the iteration should generally be much larger than a character or line; concrete advice on chunk size is hard to come by, but a single chunk of even 100 or 200 K is probably fine.
If the IResult is a string, then, the default iteration of per-character is wildly too small. Because this is such a common case, if a string is used as an IResult then this is special-cased to simply convert to a tuple of one value, the string.
Adaptation to this interface provides the opportunity for efficient file delivery, pipelining hooks, and more.
-
__iter__
()¶ iterate over the values that should be returned as the result.
See IHTTPResponse.setResult.
-
-
interface
zope.publisher.interfaces.http.
IHTTPResponse
[source]¶ Extends:
zope.publisher.interfaces.IResponse
An object representation of an HTTP response.
The Response type encapsulates all possible responses to HTTP requests. Responses are normally created by the object publisher. A published object may recieve the response object as an argument named ‘RESPONSE’. A published object may also create its own response object. Normally, published objects use response objects to:
- Provide specific control over output headers,
- Set cookies, or
- Provide stream-oriented output.
If stream oriented output is used, then the response object passed into the object must be used.
-
authUser
¶ The authenticated user message.
-
getStatus
()¶ Returns the current HTTP status code as an integer.
-
setStatus
(status, reason=None)¶ Sets the HTTP status code of the response
The status parameter must be either an integer (preferred), a value that can be converted to an integer using the int() function, or one of the standard status messages listed in the status_codes dict of the zope.publisher.http module (including “OK”, “NotFound”, and so on). If the parameter is some other value, the status will be set to 500.
The reason parameter is a short message to be sent with the status code to the client. If reason is not provided, a standard reason will be supplied, falling back to “Unknown” for unregistered status codes.
-
getStatusString
()¶ Return the status followed by the reason.
-
setHeader
(name, value, literal=False)¶ Sets an HTTP return header “name” with value “value”
The previous value is cleared. If the literal flag is true, the case of the header name is preserved, otherwise word-capitalization will be performed on the header name on output.
-
addHeader
(name, value)¶ Add an HTTP Header
Sets a new HTTP return header with the given value, while retaining any previously set headers with the same name.
-
getHeader
(name, default=None)¶ Gets a header value
Returns the value associated with a HTTP return header, or ‘default’ if no such header has been set in the response yet.
-
getHeaders
()¶ Returns a list of header name, value tuples.
-
appendToCookie
(name, value)¶ Append text to a cookie value
If a value for the cookie has previously been set, the new value is appended to the old one separated by a colon.
-
expireCookie
(name, **kw)¶ Causes an HTTP cookie to be removed from the browser
The response will include an HTTP header that will remove the cookie corresponding to “name” on the client, if one exists. This is accomplished by sending a new cookie with an expiration date that has already passed. Note that some clients require a path to be specified - this path must exactly match the path given when creating the cookie. The path can be specified as a keyword argument. If the value of a keyword argument is None, it will be ignored.
-
setCookie
(name, value, **kw)¶ Sets an HTTP cookie on the browser
The response will include an HTTP header that sets a cookie on cookie-enabled browsers with a key “name” and value “value”. This overwrites any previously set value for the cookie in the Response object. If the value of a keyword argument is None, it will be ignored.
-
getCookie
(name, default=None)¶ Gets HTTP cookie data as a dict
Returns the dict of values associated with an HTTP cookie set in the response, or ‘default’ if no such cookie has been set in the response yet.
-
setResult
(result)¶ Sets response result value based on input.
Input is usually a unicode string, a string, None, or an object that can be adapted to IResult with the request. The end result is an iterable such as WSGI prefers, determined by following the process described below.
Try to adapt the given input, with the request, to IResult (found above in this file). If this fails, and the original value was a string, use the string as the result; or if was None, use an empty string as the result; and if it was anything else, raise a TypeError.
If the result of the above (the adaptation or the default handling of string and None) is unicode, encode it (to the preferred encoding found by adapting the request to zope.i18n.interfaces.IUserPreferredCharsets, usually implemented by looking at the HTTP Accept-Charset header in the request, and defaulting to utf-8) and set the proper encoding information on the Content-Type header, if present. Otherwise (the end result was not unicode) application is responsible for setting Content-Type header encoding value as necessary.
If the result of the above is a string, set the Content-Length header, and make the string be the single member of an iterable such as a tuple (to send large chunks over the wire; see discussion in the IResult interface). Otherwise (the end result was not a string) application is responsible for setting Content-Length header as necessary.
Set the result of all of the above as the response’s result. If the status has not been set, set it to 200 (OK).
-
consumeBody
()¶ Returns the response body as a string.
Note that this function can be only requested once, since it is constructed from the result.
-
consumeBodyIter
()¶ Returns the response body as an iterable.
Note that this function can be only requested once, since it is constructed from the result.
-
interface
zope.publisher.interfaces.http.
IHTTPVirtualHostChangedEvent
[source]¶ The host, port and/or the application path have changed.
The request referred to in this event implements at least the IHTTPAppliationRequest interface.
-
request
¶ The application request whose virtual host info has been altered
-
-
interface
zope.publisher.interfaces.http.
IHTTPException
[source]¶ Marker interface for http exceptions views
-
interface
zope.publisher.interfaces.http.
IMethodNotAllowed
[source]¶ Extends:
zope.interface.common.interfaces.IException
An exception that signals the 405 Method Not Allowed HTTP error
-
object
¶ The object on which the error occurred
-
request
¶ The request in which the error occurred
-
-
exception
zope.publisher.interfaces.http.
MethodNotAllowed
(object, request)[source]¶ Bases:
exceptions.Exception
An exception that signals the 405 Method Not Allowed HTTP error
Implementation¶
HTTP Publisher
-
class
zope.publisher.http.
HTTPInputStream
(stream, environment)[source]¶ Bases:
object
Special stream that supports caching the read data.
This is important, so that we can retry requests.
-
class
zope.publisher.http.
HTTPRequest
(body_instream, environ, response=None)[source]¶ Bases:
zope.publisher.base.BaseRequest
Model HTTP request data.
This object provides access to request data. This includes, the input headers, form data, server data, and cookies.
Request objects are created by the object publisher and will be passed to published objects through the argument name, REQUEST.
The request object is a mapping object that represents a collection of variable to value mappings. In addition, variables are divided into four categories:
Environment variables
These variables include input headers, server data, and other request-related data. The variable names are as <a href=”http://hoohoo.ncsa.uiuc.edu/cgi/env.html“>specified</a> in the <a href=”http://hoohoo.ncsa.uiuc.edu/cgi/interface.html“>CGI specification</a>
Form data
These are data extracted from either a URL-encoded query string or body, if present.
Cookies
These are the cookie data, if present.
Other
Data that may be set by an application object.
The form attribute of a request is actually a Field Storage object. When file uploads are used, this provides a richer and more complex interface than is provided by accessing form data as items of the request. See the FieldStorage class documentation for more details.
The request object may be used as a mapping object, in which case values will be looked up in the order: environment variables, other variables, form data, and then cookies.
See IHTTPCredentials
Creating HTTP Results¶
This document describes the state of creating HTTP results for Zope 3.4. This is different than it was in the past.
Traditionally in Zope, HTTP results are created by simply returning strings. Strings are inspected to deduce their content type, which is usually HTML. Applications can override this by setting a response headers (calling request.response.setHeader).
In Zope 2, applications could also call response.write. This allows both:
- Effecient handling of large output
- HTTP chucked output for streaming
Before release 3.1, Zope 3 has a response write method that did neither of these things. Developers coming from Zope 2 might use the write method, expecting it to have the same bahavior as it does in Zope 2. At least until we can satisfy those expectations, we have disabled the response write method for now. Maybe we’ll reinstate it in the future.
There is currently no support for streaming (at least while holding on to a database connection and transaction), but there is now support for returning large amounts of data.
Returning large amounts of data without storing the data in memory¶
To return a large result, you should write the result to a temporary file (tempfile.TemporaryFile) and return the temporary file. Alternatively, if the data you want to return is already in a (non-temporary) file, just open and return that file. The publisher (actually an adapter used by the publisher) will handle a returned file very efficiently.
The publisher will compute the response content length from the file automatically. It is up to applications to set the content type. It will also take care of positioning the file to it’s beginning, so applications don’t need to do this beforehand.
This is actually accomplished via zope.app.wsgi.fileresult.FileResult, and happens if and only if that, or something like it, is registered as an adapter. The FileResult, however, does what needs to happen thanks to a special hook associated with the IResult interface, used by the http module in this package.
zope.publisher.interfaces.http.IResult
¶
The interface for IResult describes the interface thoroughly. The IHTTPResponse.setHeader method that uses it also documents how it is used. Reading the IResult interface and the IHTTPResponse.setHeader description (in the same interface file) is highly recommended.
In addition to supporting sending large amoounts of data, IResult supports postprocessing of output. setResult tries to adapt everything to IResult. Postprocessing might include XSLT transforms, adding an O-wrap around the content, adding JavaScript and CSS header lines on the basis of elements added to a page, or pipelining somehow to do all of it sequentially. May the best approach win! This merely makes the different options possible.
To close, we’ll build a quick example so you can see it working.
(To make the code work in both python-2.x and python-3.x, define unicode
name for
python-3.x:
>>> import sys
>>> if sys.version_info[0] > 2:
... unicode = str
>>> import zope.interface
>>> import zope.component
>>> from zope.publisher.browser import TestRequest
>>> from zope.publisher.interfaces.http import IResult, IHTTPRequest
>>> try:
... from html import escape
... except ImportError:
... from cgi import escape
>>> @zope.interface.implementer(IResult)
... @zope.component.adapter(unicode, IHTTPRequest)
... def do_something_silly_to_unicode_results(val, request):
... request.response.setHeader('X-Silly', 'Yes')
... return (unicode('<html>\n<head>\n<title>raw</title>\n</head>\n<body>\n') +
... escape(val) + '\n</body>\n</html>')
...
>>> zope.component.provideAdapter(do_something_silly_to_unicode_results)
That’s returning a unicode string, which is special cased to (1) make an iterable that is chunked, (2) encode, and (3) set content-length.
>>> request = TestRequest()
>>> request.response.setHeader('content-type', 'text/html')
>>> request.response.setResult(unicode('<h1>Foo!</h1>'))
>>> request.response.getHeader('x-silly')
'Yes'
>>> request.response.getHeader('content-type')
'text/html;charset=utf-8'
>>> res = tuple(request.response.consumeBodyIter())
>>> res
(b'<html>\n<head>\n<title>raw</title>\n</head>\n<body>\n<h1>Foo!</h1>\n</body>\n</html>',)
>>> len(res[0]) == int(request.response.getHeader('content-length'))
True
You can also do everything yourself by returning any non-basestring iterable (for instance, a list or tuple).
>>> @zope.interface.implementer(IResult)
... @zope.component.adapter(int, IHTTPRequest)
... def do_something_silly_to_int_results(val, request):
... return ['This', ' is an int: %i' % (val,),]
...
>>> zope.component.provideAdapter(do_something_silly_to_int_results)
>>> request = TestRequest()
>>> request.response.setHeader('content-type', 'text/plain')
>>> request.response.setResult(42)
>>> request.response.getHeader('content-type')
'text/plain'
>>> res = tuple(request.response.consumeBodyIter())
>>> res
('This', ' is an int: 42')
>>> request.response.getHeader('content-length') is None
True
Again, READ THE INTERFACES. One important bit is that you can’t hold on to a database connection in one of these iterables.
You can bypass the adaptation by calling setResult with an object that
provides IResult. The DirectResult
class in the http module is the
simplest way to do this, but any other IResult should work.
>>> from zope.publisher.http import DirectResult
>>> @zope.interface.implementer(IResult)
... @zope.component.adapter(DirectResult, IHTTPRequest)
... def dont_touch_this(val, request):
... raise ValueError('boo! hiss!') # we don't get here.
...
>>> request = TestRequest()
>>> request.response.setResult(DirectResult(('hi',)))
>>> tuple(request.response.consumeBodyIter())
('hi',)
Browser API Reference¶
Interfaces¶
Browser Interfaces
-
interface
zope.publisher.interfaces.browser.
IBrowserApplicationRequest
[source]¶ Extends:
zope.publisher.interfaces.http.IHTTPApplicationRequest
Browser-specific requests
-
__getitem__
(key)¶ Return Browser request data
Request data are retrieved from one of:
Environment variables
These variables include input headers, server data, and other request-related data. The variable names are as <a href=”http://hoohoo.ncsa.uiuc.edu/cgi/env.html“>specified</a> in the <a href=”http://hoohoo.ncsa.uiuc.edu/cgi/interface.html“>CGI specification</a>
Cookies
These are the cookie data, if present.
Form data
Form data are searched before cookies, which are searched before environmental data.
-
form
¶ Form data
This is a read-only mapping from name to form value for the name.
-
-
interface
zope.publisher.interfaces.browser.
IBrowserPublication
[source]¶ Extends:
zope.publisher.interfaces.IPublication
Object publication framework.
-
getDefaultTraversal
(request, ob)¶ Get the default published object for the request
Allows a default view to be added to traversal. Returns (ob, steps_reversed).
-
-
interface
zope.publisher.interfaces.browser.
IBrowserRequest
[source]¶ Extends:
zope.publisher.interfaces.http.IHTTPRequest
,zope.publisher.interfaces.ISkinnable
Browser-specific Request functionality.
Note that the browser is special in many ways, since it exposes the Request object to the end-developer.
-
interface
zope.publisher.interfaces.browser.
IBrowserPage
[source]¶ Extends:
zope.browser.interfaces.IBrowserView
,zope.publisher.interfaces.browser.IBrowserPublisher
Browser page
-
__call__
(*args, **kw)¶ Compute a response body
-
-
interface
zope.publisher.interfaces.browser.
IBrowserSkinType
[source]¶ Extends:
zope.publisher.interfaces.ISkinType
A skin is a set of layers.
-
interface
zope.publisher.interfaces.browser.
IDefaultBrowserLayer
[source]¶ Extends:
zope.publisher.interfaces.browser.IBrowserRequest
The default layer.
Implementation¶
Browser-specific Publisher classes
Here we define the specific ‘BrowserRequest’ and ‘BrowserResponse’ class. The big improvement of the ‘BrowserRequest’ to ‘HTTPRequest’ is that is can handle HTML form data and convert them into a Python-native format. Even file data is packaged into a nice, Python-friendly ‘FileUpload’ object.
-
zope.publisher.browser.
start_of_header_search
()¶ search(string[, pos[, endpos]]) –> match object or None. Scan through string looking for a match, and return a corresponding match object instance. Return None if no position in the string matches.
-
zope.publisher.browser.
base_re_search
()¶ search(string[, pos[, endpos]]) –> match object or None. Scan through string looking for a match, and return a corresponding match object instance. Return None if no position in the string matches.
-
zope.publisher.browser.
isRelative
()¶ match(string[, pos[, endpos]]) –> match object or None. Matches zero or more characters at the beginning of the string
-
zope.publisher.browser.
get_converter
()¶ D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.
-
zope.publisher.browser.
registerTypeConverter
(field_type, converter, replace=False)[source]¶ Add a custom type converter to the registry.
- o If ‘replace’ is not true, raise a KeyError if a converter is
- already registered for ‘field_type’.
-
class
zope.publisher.browser.
FileUpload
(aFieldStorage)[source]¶ Bases:
object
File upload objects
File upload objects are used to represent file-uploaded data.
File upload objects can be used just like files.
In addition, they have a ‘headers’ attribute that is a dictionary containing the file-upload headers, and a ‘filename’ attribute containing the name of the uploaded file.
-
class
zope.publisher.browser.
RedirectingBrowserRequest
(body_instream, environ, response=None)[source]¶ Bases:
zope.publisher.browser.BrowserRequest
Browser requests that redirect when the actual and effective URLs differ
-
class
zope.publisher.browser.
TestRequest
(body_instream=None, environ=None, form=None, skin=None, **kw)[source]¶ Bases:
zope.publisher.browser.BrowserRequest
Browser request with a constructor convenient for testing
-
class
zope.publisher.browser.
BrowserResponse
[source]¶ Bases:
zope.publisher.http.HTTPResponse
Browser response
-
exception
zope.publisher.browser.
NotCompatibleAdapterError
[source]¶ Bases:
exceptions.Exception
Adapter not compatible with zope.i18n.interfaces.IModifiableBrowserLanguages has been used.
-
class
zope.publisher.browser.
BrowserView
(context, request)[source]¶ Bases:
zope.location.location.Location
Browser View.
>>> view = BrowserView("context", "request") >>> view.context 'context' >>> view.request 'request'
>>> view.__parent__ 'context' >>> view.__parent__ = "parent" >>> view.__parent__ 'parent'
-
class
zope.publisher.browser.
BrowserPage
(context, request)[source]¶ Bases:
zope.publisher.browser.BrowserView
Browser page
To create a page, which is an object that is published as a page, you need to provide an object that:
- has a __call__ method and that
- provides IBrowserPublisher, and
- if ZPT is going to be used, then your object should also provide request and context attributes.
The BrowserPage base class provides a standard constructor and a simple implementation of IBrowserPublisher:
>>> class MyPage(BrowserPage): ... pass
>>> request = TestRequest() >>> context = object() >>> page = MyPage(context, request)
>>> from zope.publisher.interfaces.browser import IBrowserPublisher >>> IBrowserPublisher.providedBy(page) True
>>> page.browserDefault(request) == (page, ()) True
>>> page.publishTraverse(request, 'bob') Traceback (most recent call last): ... NotFound: Object: <zope.publisher.browser.MyPage object at ...>, name: 'bob'
>>> page.request is request True
>>> page.context is context True
But it doesn’t supply a __call__ method:
>>> page() Traceback (most recent call last): ... NotImplementedError: Subclasses should override __call__ to provide a response body
It is the subclass’ responsibility to do that.
FTP API Reference¶
Interfaces¶
Virtual File System interfaces for the publisher.
-
interface
zope.publisher.interfaces.ftp.
IFTPRequest
[source]¶ Extends:
zope.publisher.interfaces.IRequest
FTP Request
Implementation¶
FTP Publisher
Logging API Reference¶
Interfaces¶
An interface for LoggingInfo.
Implementation¶
Adapter:
Adapts zope.security.interfaces.IPrincipal to zope.publisher.interfaces.logginginfo.ILoggingInfo.
Default View Name API¶
Default view name API
-
zope.publisher.defaultview.
queryDefaultViewName
(object, request, default=None, context=None)[source]¶ query the default view for a given object and request.
>>> from zope.publisher.defaultview import queryDefaultViewName
lets create an object with a default view.
>>> import zope.interface >>> class IMyObject(zope.interface.Interface): ... pass >>> @zope.interface.implementer(IMyObject) ... class MyObject(object): ... pass >>> queryDefaultViewName(MyObject(), object()) is None True
Now we can will set a default view.
>>> import zope.component >>> import zope.publisher.interfaces >>> zope.component.provideAdapter('name', ... adapts=(IMyObject, zope.interface.Interface), ... provides=zope.publisher.interfaces.IDefaultViewName) >>> queryDefaultViewName(MyObject(), object()) 'name'
This also works if the name is empty
>>> zope.component.provideAdapter('', ... adapts=(IMyObject, zope.interface.Interface), ... provides=zope.publisher.interfaces.IDefaultViewName) >>> queryDefaultViewName(MyObject(), object()) ''
Skinnable¶
Requests can provide skins. But what exactly is a skin? At the code level, a skin is just an interface which a request provides. Why do we need skins? We can use skins for registering different adapters.
That’s a little bit much use of the word skin. Let’s explain it in more detail. A skin is an interface which provides an interface. This interface is called ISkinType. The zope.publisher right now provides only one specific skin type interface used in the IBrowserRequest implementation. This interface is called BrowserSkinType.
Since the zope server provides request factories for building a request, each such request type could provide it’s own skin type interface. This ensures that we can register a skin type for each request.
Now let’s look at a higher level. A skin is a concept which we can use for providing different kinds of views, templates or other adapters adapting a request. These skins are the key component for providing different kind of application layers. A skin makes it possible for an application to act very differently with each skin. Of course, that’s only the case at the interaction level where the request is involved. But that’s the case most of the time since we have a web application server.
Another part of the skinnable concept is that an application can define zero or more default skins. This is done with the IDefaultSkin interface. Default skins can be defined for request interfaces or implementations. Such a default skin can get overriden in a custom setup. Overriding a skin can be done by using the defaultSkin directive offered from zope.app.publication.zcml.
Why does a request need a default skin? If a request needs to provide some pluggable concepts that require that a default adapter is registered for a request, this adapter could be registered for the default skin. If a project likes to use another pattern and needs to register another request adapter, the project could register its own skin and register the custom adapter for this new project based skin. This is very handy and allows developers to skip a complete default-skin-based setup for a given request.
In general, this means a request interface and the request class that implements the request interface only provides the basic API but no adapters if the request needs to delegate things to an adapter. For such a request a default skin can get defined. This default skin can provide all adapters which the request implementation needs to have. This gives us the option to replace the default skin within a custom skin and provide custom adapters.
Our exmple will define a full request and all its components from scratch. it doesn’t depend on IBrowserRequest. We’ll use a JSON-RPC as sample like the z3c.jsonrpc package provides.
Layers and Skins¶
We also use the term “layer” if we talk about skins. A layer or skin
layer is an interface registered as a ISkinType without a name. Zope
provides a traversal pattern which allows traversal to a skin within a
skin namespace called skin
. This allows traversal to a method called
applySkin
which will apply a registered named skin. This means if we
register an ISkinType with a name argument, we will register a skin. if
we register a ISkinType without a name just we register a layer. This
means, layers are not traversable ISkinType interfaces.
Let’s start define a request:
>>> from zope.publisher.interfaces import IRequest
>>> class IJSONRequest(IRequest):
... """JSON request."""
And we define a skin type:
>>> from zope.publisher.interfaces import ISkinType
>>> class IJSONSkinType(ISkinType):
... """JSON skin type."""
A request would implement the IJSONRequest interface but not the request type interface:
>>> import zope.interface
>>> from zope.publisher.base import BaseRequest
>>> @zope.interface.implementer(IJSONRequest)
... class JSONRequest(BaseRequest):
... """JSON request implementation."""
Now our request provides IJSONRequest because it implement that interface:
>>> from io import BytesIO
>>> request = JSONRequest(BytesIO(b''), {})
>>> IJSONRequest.providedBy(request)
True
setDefaultSkin¶
The default skin is a marker interface that can be registered as an adapter that provides IDefaultSkin for the request type. A default skin interface like any other skin must also provide ISkinType. This is important since applySkin will lookup for skins based on this type.
Note: Any interfaces that are directly provided by the request coming into this method are replaced by the applied layer/skin interface. This is very important since the retry pattern can use a clean request without any directly provided interface after a retry gets started.
If a default skin is not available, the fallback default skin is applied
if available for the given request type. The default fallback skin is
implemented as an named adapter factory providing IDefaultSkin and
using default
as name.
Important to know is that some skin adapters get registered as interfaces and the fallback skins as adapters. See the defaultSkin directive in zope.app.publication.zcml for more information. It registers plain interfaces as adapters which are not adaptable. We have special code to handle this case, which we will demonstrate below.
Each request can only have one (unnamed) default skin and will fallback to the named (default) fallback skin if available.
Only the IBrowserRequest provides such a default fallback adapter. This adapter will apply the IDefaultBrowserLayer if no explicit default skin is registered for IBrowserRequest.
Our test setup requires a custom default layer which we will apply to our request. Let’s define a custm layer:
>>> class IJSONDefaultLayer(zope.interface.Interface):
... """JSON default layyer."""
To illustrate, we’ll first use setDefaultSkin without a registered IDefaultSkin adapter:
>>> IJSONDefaultLayer.providedBy(request)
False
If we try to set a default skin and no one exist we will not fail but nothing happens
>>> from zope.publisher.skinnable import setDefaultSkin
>>> setDefaultSkin(request)
Make sure our IJSONDefaultLayer provides the ISkinType interface. This is normaly done in a configure.zcml using the interface directive:
>>> ISkinType.providedBy(IJSONDefaultLayer)
False
>>> zope.interface.alsoProvides(IJSONDefaultLayer, ISkinType)
>>> ISkinType.providedBy(IJSONDefaultLayer)
True
Now let’s examine what can happen with our legacy case: an interface is registered as an adapter.
>>> from zope.publisher.interfaces import IDefaultSkin
>>> sm = zope.component.getSiteManager()
>>> sm.registerAdapter(
... IJSONDefaultLayer, (IJSONRequest,), IDefaultSkin, name='default')
>>> request = JSONRequest(BytesIO(b''), {})
>>> IJSONDefaultLayer.providedBy(request)
False
>>> setDefaultSkin(request)
>>> IJSONDefaultLayer.providedBy(request)
True
What if the request already provides the interface?
>>> IJSONDefaultLayer.providedBy(request)
True
>>> setDefaultSkin(request)
>>> IJSONDefaultLayer.providedBy(request)
True
Now let’s define a default skin adapter which the setDefaultSkin can use. This
adapter return our IJSONDefaultLayer. We also register this adapter within
default
as name:
>>> def getDefaultJSONLayer(request):
... return IJSONDefaultLayer
>>> zope.component.provideAdapter(getDefaultJSONLayer,
... (IJSONRequest,), IDefaultSkin, name='default')
>>> setDefaultSkin(request)
>>> IJSONDefaultLayer.providedBy(request)
True
When we register a default skin, without that the skin provides an ISkinType, the setDefaultSkin will raise a TypeError:
>>> from zope.interface import Interface
>>> class IMySkin(Interface):
... pass
>>> zope.component.provideAdapter(IMySkin, (IJSONRequest,), IDefaultSkin)
>>> setDefaultSkin(request)
Traceback (most recent call last):
...
TypeError: Skin interface <InterfaceClass __builtin__.IMySkin> doesn't provide ISkinType
The default skin must provide ISkinType:
>>> zope.interface.alsoProvides(IMySkin, ISkinType)
>>> ISkinType.providedBy(IMySkin)
True
setDefaultSkin uses the custom layer interface instead of IJSONDefaultLayer:
>>> request = JSONRequest(BytesIO(b''), {})
>>> IMySkin.providedBy(request)
False
>>> IJSONDefaultLayer.providedBy(request)
False
>>> setDefaultSkin(request)
>>> IMySkin.providedBy(request)
True
>>> IJSONDefaultLayer.providedBy(request)
False
Any interfaces that are directly provided by the request coming into this method are replaced by the applied layer/skin interface. This is important for our retry pattern which will ensure that we start with a clean request:
>>> request = JSONRequest(BytesIO(b''), {})
>>> class IFoo(Interface):
... pass
>>> zope.interface.directlyProvides(request, IFoo)
>>> IFoo.providedBy(request)
True
>>> setDefaultSkin(request)
>>> IFoo.providedBy(request)
False
applySkin¶
The applySkin method is able to apply any given skin. Let’s define some custom skins:
>>> import pprint
>>> from zope.interface import Interface
>>> class ISkinA(Interface):
... pass
>>> zope.interface.directlyProvides(ISkinA, ISkinType)
>>> class ISkinB(Interface):
... pass
>>> zope.interface.directlyProvides(ISkinB, ISkinType)
Let’s start with a fresh request:
>>> request = JSONRequest(BytesIO(b''), {})
Now we can apply the SkinA:
>>> from zope.publisher.skinnable import applySkin
>>> applySkin(request, ISkinA)
>>> pprint.pprint(list(zope.interface.providedBy(request).interfaces()))
[<InterfaceClass __builtin__.ISkinA>,
<InterfaceClass __builtin__.IJSONRequest>,
<InterfaceClass zope.publisher.interfaces.IRequest>]
And if we apply ISkinB, ISkinA get removed at the same time ISkinB get applied:
>>> applySkin(request, ISkinB)
>>> pprint.pprint(list(zope.interface.providedBy(request).interfaces()))
[<InterfaceClass __builtin__.ISkinB>,
<InterfaceClass __builtin__.IJSONRequest>,
<InterfaceClass zope.publisher.interfaces.IRequest>]
setDefaultSkin and applySkin¶
If we set a default skin and later apply a custom skin, the default skin get removed at the time the applySkin get called within a new ISkinType:
>>> request = JSONRequest(BytesIO(b''), {})
Note, that our IMySkin is the default skin for IJSONRequest. We can aprove that by lookup an IDefaultSkin interface for our request:
>>> adapters = zope.component.getSiteManager().adapters
>>> default = adapters.lookup((zope.interface.providedBy(request),),
... IDefaultSkin, '')
>>> default
<InterfaceClass __builtin__.IMySkin>
>>> setDefaultSkin(request)
>>> IMySkin.providedBy(request)
True
>>> ISkinA.providedBy(request)
False
Now apply our skin ISkinA. This should remove the IMySkin at the same time the ISkinA get applied:
>>> applySkin(request, ISkinA)
>>> IMySkin.providedBy(request)
False
>>> ISkinA.providedBy(request)
True
SkinChangedEvent¶
We will use python-3 style print function, so we import it from the future:
>>> from __future__ import print_function
Changing the skin on a request triggers the ISkinChangedEvent event:
>>> import zope.component
>>> from zope.publisher.interfaces import ISkinChangedEvent
>>> def receiveSkinEvent(event):
... print("Notified SkinEvent for: %s" % event.request.__class__.__name__)
>>> zope.component.provideHandler(receiveSkinEvent, (ISkinChangedEvent,))
>>> applySkin(request, ISkinA)
Notified SkinEvent for: JSONRequest
XMLRPC publisher¶
Pre-marshal / Proxy removal¶
>>> sample = {'foo': (1, ['x', 'y', 1.2])}
if we put the sample in a security proxy:
>>> from zope.security.checker import ProxyFactory
>>> proxied_sample = ProxyFactory(sample)
We can still get to the data, but the non-rock data is proxied:
>>> from zope.security.proxy import Proxy
>>> proxied_sample['foo']
(1, ['x', 'y', 1.2])
>>> type(proxied_sample['foo']) is Proxy
True
>>> type(proxied_sample['foo'][1]) is Proxy
True
But we can strip the proxies using premarshal:
>>> from zope.publisher.xmlrpc import premarshal
>>> stripped = premarshal(proxied_sample)
>>> stripped
{'foo': [1, ['x', 'y', 1.2]]}
>>> type(stripped['foo']) is Proxy
False
>>> type(stripped['foo'][1]) is Proxy
False
So xmlrpclib will be happy. :)
Import xmlrpclib depending on current python interpreter version
>>> import sys
>>> if sys.version_info[0] == 2:
... import xmlrpclib
... else:
... import xmlrpc.client as xmlrpclib
We can also use premarshal to strip proxies off of Fault objects. We have to make a security declaration first though:
>>> fault = xmlrpclib.Fault(1, 'waaa')
>>> proxied_fault = ProxyFactory(fault)
>>> stripped_fault = premarshal(proxied_fault)
>>> type(stripped_fault) is Proxy
False
Standard python datetime objects are also handled:
>>> import datetime
>>> sample = datetime.datetime(2006,6,17,21,41,00)
>>> stripped_date = premarshal(sample)
>>> isinstance(stripped_date, datetime.datetime)
False
>>> isinstance(stripped_date, xmlrpclib.DateTime)
True
We can also use premarshal to strip proxies off of Binary objects. We have to make a security declaration first though:
>>> binary = xmlrpclib.Binary(b'foobar')
>>> proxied_binary = ProxyFactory(binary)
>>> stripped_binary = premarshal(proxied_binary)
>>> type(stripped_binary) is Proxy
False
Interfaces¶
Interfaces for the XMLRPC publisher.
-
interface
zope.publisher.interfaces.xmlrpc.
IXMLRPCPublisher
[source]¶ Extends:
zope.publisher.interfaces.IPublishTraverse
XML-RPC Publisher
-
interface
zope.publisher.interfaces.xmlrpc.
IXMLRPCPublication
[source]¶ Extends:
zope.publisher.interfaces.IPublication
Object publication framework.
-
getDefaultTraversal
(request, ob)¶ Get the default published object for the request
Allows a default view to be added to traversal. Returns (ob, steps_reversed).
-
-
interface
zope.publisher.interfaces.xmlrpc.
IXMLRPCRequest
[source]¶ Extends:
zope.publisher.interfaces.http.IHTTPRequest
XML-RPC Request
Implementation¶
XML-RPC Publisher
This module contains the XMLRPCRequest and XMLRPCResponse
-
class
zope.publisher.xmlrpc.
XMLRPCResponse
[source]¶ Bases:
zope.publisher.http.HTTPResponse
XMLRPC response.
This object is responsible for converting all output to valid XML-RPC.
-
setResult
(result)[source]¶ Sets the result of the response
Sets the return body equal to the (string) argument “body”. Also updates the “content-length” return header.
If the body is a 2-element tuple, then it will be treated as (title,body)
If is_error is true then the HTML will be formatted as a Zope error message instead of a generic HTML page.
-
handleException
(exc_info)[source]¶ Handle Errors during publsihing and wrap it in XML-RPC XML
>>> import sys >>> resp = XMLRPCResponse() >>> try: ... raise AttributeError('xyz') ... except: ... exc_info = sys.exc_info() ... resp.handleException(exc_info)
>>> resp.getStatusString() '200 OK' >>> resp.getHeader('content-type') 'text/xml;charset=utf-8' >>> body = ''.join(resp.consumeBody()) >>> 'Unexpected Zope exception: AttributeError: xyz' in body True
-
-
class
zope.publisher.xmlrpc.
XMLRPCView
(context, request)[source]¶ Bases:
object
A base XML-RPC view that can be used as mix-in for XML-RPC views.
-
class
zope.publisher.xmlrpc.
PreMarshallerBase
(data)[source]¶ Bases:
object
Abstract base class for pre-marshallers.
-
class
zope.publisher.xmlrpc.
DictPreMarshaller
(data)[source]¶ Bases:
zope.publisher.xmlrpc.PreMarshallerBase
Pre-marshaller for dicts
-
class
zope.publisher.xmlrpc.
ListPreMarshaller
(data)[source]¶ Bases:
zope.publisher.xmlrpc.PreMarshallerBase
Pre-marshaller for list
-
class
zope.publisher.xmlrpc.
BinaryPreMarshaller
(data)[source]¶ Bases:
zope.publisher.xmlrpc.PreMarshallerBase
Pre-marshaller for xmlrpc.Binary
-
class
zope.publisher.xmlrpc.
FaultPreMarshaller
(data)[source]¶ Bases:
zope.publisher.xmlrpc.PreMarshallerBase
Pre-marshaller for xmlrpc.Fault
-
class
zope.publisher.xmlrpc.
DateTimePreMarshaller
(data)[source]¶ Bases:
zope.publisher.xmlrpc.PreMarshallerBase
Pre-marshaller for xmlrpc.DateTime
-
class
zope.publisher.xmlrpc.
PythonDateTimePreMarshaller
(data)[source]¶ Bases:
zope.publisher.xmlrpc.PreMarshallerBase
Pre-marshaller for datetime.datetime
-
zope.publisher.xmlrpc.
premarshal
(data)[source]¶ Premarshal data before handing it to xmlrpclib for marhalling
The initial purpose of this function is to remove security proxies without resorting to removeSecurityProxy. This way, we can avoid inadvertently providing access to data that should be protected.
Package configuration¶
The zope.publisher
package provides a ZCML file that configures some
adapters and security:
>>> from zope.configuration.xmlconfig import XMLConfig
>>> import zope.publisher
>>> XMLConfig('configure.zcml', zope.publisher)()
>>> len(list(zope.component.getGlobalSiteManager().registeredUtilities()))
22
>>> len(list(zope.component.getGlobalSiteManager().registeredAdapters()))
11
ZCML Directives¶
This package also defines some ZCML directives for defining the
default skin (browser:defaultSkin
) and default view
(browser:defaultView
).
Default view and default skin ZCML configuration feature.
-
interface
zope.publisher.zcml.
IDefaultSkinDirective
[source]¶ Sets the default browser skin
-
name
¶ Default skin name
Default skin name
-
-
interface
zope.publisher.zcml.
IDefaultViewDirective
[source]¶ The name of the view that should be the default.
This name refers to view that should be the view used by default (if no view name is supplied explicitly).
-
name
¶ The name of the view that should be the default.
This name refers to view that should be the view used by default (if no view name is supplied explicitly).
-
for_
¶ The interface this view is the default for.
Specifies the interface for which the view is registered.
All objects implementing this interface can make use of this view. If this attribute is not specified, the view is available for all objects.
-
layer
¶ The layer the default view is declared for
The default layer for which the default view is applicable. By default it is applied to all layers.
-
-
zope.publisher.zcml.
setDefaultSkin
(name, info='')[source]¶ Set the default skin.
>>> from zope.interface import directlyProvides >>> from zope.app.testing import ztapi
>>> class Skin1: pass >>> directlyProvides(Skin1, IBrowserSkinType)
>>> ztapi.provideUtility(IBrowserSkinType, Skin1, 'Skin1') >>> setDefaultSkin('Skin1') >>> adapters = component.getSiteManager().adapters
Lookup the default skin for a request that has the>>> adapters.lookup((IBrowserRequest,), IDefaultSkin, '') is Skin1 True
Changes¶
4.3.3 (unreleased)¶
- Nothing changed yet.
4.3.2 (2017-05-23)¶
- Fix instances of
BaseRequest
(includingBrowserRequest
) being unexpectedlyFalse
on Python 3 by defining__bool__
. Such instances were alwaysTrue
on Python 2. See issue 18.
4.3.1 (2017-04-24)¶
Add support for Python 3.6.
Accept both new and old locations for
__code__
inzope.publisher.publisher.unwrapMethod
. This restores compatibility with Products.PythonScripts, where parameters were not extracted. [maurits, thet, MatthewWilkes]Fix file uploads on python 3.4 and up. cgi.FieldStorage explicitly closes files when it is garbage collected. For details, see:
- http://bugs.python.org/issue18394
- https://hg.python.org/cpython/rev/c0e9ba7b26d5
- https://github.com/zopefoundation/zope.publisher/pull/13
We now keep a reference to the FieldStorage till we are finished processing the request.
Fix POST with large values on Python 3. Related to cgi.FieldStorage doing the decoding in Python 3. See pull 16.
4.3.0 (2016-07-04)¶
- Add support for Python 3.5.
- Drop support for Python 2.6 and 3.2.
4.2.2 (2015-11-16)¶
- Emit HTTP response headers in a deterministic order (GH #8).
4.2.1 (2015-06-05)¶
- Add support for Python 3.2.
4.2.0 (2015-06-02)¶
- Add support for PyPy and PyPy3.
4.1.0 (2014-12-27)¶
- Add support for Python 3.4.
4.0.0 (2014-12-22)¶
- Enable testing on Travis.
- Add
__traceback_info__
toresponse.redirect()
to ease debugging untrusted redirects. - Add
trusted
support forRedirect
exception
4.0.0a4 (2013-03-12)¶
- Support UTF-8-encoding application/json responses returned as Unicode.
- Add YAML for travis-ci.
4.0.0a3 (2013-02-28)¶
- Return bytes from
PrincipalLogging.getLogMessage
instead of unicode.
4.0.0a2 (2013-02-22)¶
- Use BytesIO in
zope.publisher.xmlrpc.TestRequest
.
4.0.0a1 (2013-02-21)¶
Replace deprecated
zope.component.adapts
usage with equivalentzope.component.adapter
decorator.Replace deprecated
zope.interface.implements
usage with equivalentzope.interface.implementer
decorator.Drop support for Python 2.4, 2.5 and pypy.
Add support for Python 3.3.
Wrap
with interaction()
in try/finally.Don’t guess the content type with 304 responses which MUST NOT / SHOULD NOT include it according to: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
Unfortunately, the content type will still be guessed if the result is set before the status.
3.13.0 (2011-11-17)¶
- Fix error when no charset matches form data and HTTP_ACCEPT_CHARSET contains a
*
. - Add test convenience helper
create_interaction
andwith interaction()
.
3.12.6 (2010-12-17)¶
- Upload a non-CRLF version to pypi.
3.12.5 (2010-12-14)¶
- Rename the
tests
extra totest
. - Add a test for our own configure.zcml.
- Use UTF-8 as the charset if the browser does not set a header, per W3C spec.
3.12.4 (2010-07-15)¶
- LP #131460: Make principal logging unicode safe.
- Remove use of string exceptions in tests, http://bugs.debian.org/585343
- Add
IStartRequestEvent
andStartRequestEvent
for use inzope.app.publication
(matching up withIEndRequestEvent
andEndRequestEvent
). Includes refactoring to produce one definition of ‘event with a request’ - IRequestEvent.
3.12.3 (2010-04-30)¶
- LP #209440: Don’t obscure original exception when handling retries
in
publish.publish()
withhandleErrors == False
. This change makes debugging such exception in unit tests easier. Thanks to James Henstridge for the patch. - LP #98395: allow unicode output of XML content whose mimetype does not
begin with
text/
, per RFC 3023 as well as for content types ending in+xml
such as Mozilla XUL’sapplication/vnd+xml
. Thanks to Justin Ryan for the patch.
3.12.2 (2010-04-16)¶
- Remove use of
zope.testing.doctestunit
in favor of stdlib’sdoctest
. - Fix bug where xml-rpc requests would hang when served using
paster.httpserver
.
3.12.1 (2010-02-21)¶
- Ensure that
BaseRequest.traverse
does not call traversal hooks on elements previously traversed but wrapped in a security proxy.
3.12.0 (2009-12-31)¶
- Revert change done in 3.6.2, removing the
zope.authentication
dependency again. Move theBasicAuthAdapter
andFTPAuth
adapters to the newzope.login
package.
3.11.0 (2009-12-15)¶
- Move
EndRequestEvent
andIEndRequestEvent
here fromzope.app.publication
.
3.10.1 (2009-11-28)¶
- Declare minimum dependency on
zope.contenttype
3.5 (omitted in 3.10).
3.10.0 (2009-10-22)¶
- Move the implementation of
zope.publisher.contenttype
tozope.contenttype.parse
, leaving BBB imports and moving tests along.zope.contenttype
is a new but light-weight dependency of this package. - Support Python 2.6 by keeping QUERY_STRING out of request.form if the method is a POST. The original QUERY_STRING is still available if further processing is needed.
- Better support the zcml
defaultSkin
directive’s behavior (registering an interface as a default skin) in thesetDefaultSkin
function.
3.9.3 (2009-10-08)¶
- Fix the check for untrusted redirects introduced in 3.9.0 so it works with virtual hosting.
3.9.2 (2009-10-07)¶
- Make redirect validation works without HTTP_HOST variable.
- Add DoNotReRaiseException adapter that can be registered
for exceptions to flag that they should not be re-raised by
publisher when
handle_errors
parameter of thepublish
method is False.
3.9.1 (2009-09-01)¶
- Convert a location, passed to a redirect method of HTTPRequest to string before checking for trusted host redirection, because a location object may be some non-string convertable to string, like URLGetter.
3.9.0 (2009-08-27)¶
Move some parts of
zope.app.publisher
into this package duringzope.app.publisher
refactoring:IModifiableUserPreferredLanguages
adapter for requestsbrowser:defaultView
andbrowser:defaultSkin
ZCML directivesIHTTPView
,IXMLRPCView
and like interfaces- security ZCML declarations for some of
zope.publisher
classes
Introduce
IReRaiseException
interface. If during publishing an exception occurs and for this exception an adapter is available that returnsFalse
on being called, the exception won’t be reraised by the publisher. This happens only ifhandle_errors
parameter of thepublish()
method is set toFalse
. Fixes problems when acting in a WSGI pipeline with a debugger middleware enabled.See https://bugs.launchpad.net/grok/+bug/332061 for details.
Fix #98471: Restrict redirects to current host. This causes a ValueError to be raised in the case of redirecting to a different host. If this is intentional, the parameter trusted can be given.
Move dependency on
zope.testing
frominstall_requires
totests_require
.Remove
time.sleep
in thesupportsRetry
http request.Add a fix for Internet Explorer versions which upload files with full filesystem paths as filenames.
3.8.0 (2009-05-23)¶
- Move
IHTTPException
,IMethodNotAllowed
, andMethodNotAllowed
here fromzope.app.http
, fixing dependency cycles involvingzope.app.http
. - Move the
DefaultViewName
API here fromzope.app.publisher.browser
, making it accessible to other packages that need it.
3.7.0 (2009-05-13)¶
- Move
IView
andIBrowserView
interfaces intozope.browser.interfaces
, leaving BBB imports.
3.6.4 (2009-04-26)¶
- Add some BBB code to setDefaultSkin to allow IBrowserRequest’s to continue to work without configuring any special adapter for IDefaultSkin.
- Move getDefaultSkin to the skinnable module next to the setDefaultSkin method, leaving a BBB import in place. Mark IDefaultBrowserLayer as a IBrowserSkinType in code instead of relying on the ZCML to be loaded.
3.6.3 (2009-03-18)¶
- Mark HTTPRequest as IAttributeAnnotatable if
zope.annotation
is available, this was previously done byzope.app.i18n
. - Register IHTTPRequest -> IUserPreferredCharsets adapter in ZCML
configuration. This was also previously done by
zope.app.i18n
.
3.6.2 (2009-03-14)¶
Add an adapter from
zope.security.interfaces.IPrincipal
tozope.publisher.interfaces.logginginfo.ILoggingInfo
. It was moved fromzope.app.security
as a part of refactoring process.Add adapters from HTTP and FTP request to
zope.authentication.ILoginPassword
interface. They are moved fromzope.app.security
as a part of refactoring process. This change adds a dependency on thezope.authentication
package, but it’s okay, since it’s a tiny contract definition-only package.See http://mail.zope.org/pipermail/zope-dev/2009-March/035325.html for reasoning.
3.6.1 (2009-03-09)¶
- Fix: remove IBrowserRequest dependency in http implementation based on condition for setDefaultSkin. Use ISkinnable instead of IBrowserRequest.
3.6.0 (2009-03-08)¶
Clean-up: Move skin related code from zope.publisher.interfaces.browser and zope.publisher.browser to zope.publihser.interfaces and zope.publisher.skinnable and provide BBB imports. See skinnable.txt for more information.
Fix: ensure that we only apply skin interface in setDefaultSkin which also provide IBrowserSkinType. This will ensure that we find a skin if the applySkin method will lookup for a skin based on this type interface.
Fix: Make it possible to use adapters and not only interfaces as skins from the adapter registry. Right now the defaultSkin directive registers simple interfaces as skin adapters which will run into a TypeError if someone tries to adapter such a skin adapter. Probably we should change the defaultSkin directive and register real adapters instead of using the interfaces as fake adapters where we expect adapter factories.
Feature: allow use of
applySkinof
with different skin types using the optionalskinType
argument, which is by default set toIBrowserSkinType
.Feature: implement the default skin pattern within adapters. This allows us to register default skins for other requests then only
IBrowserRequest
usingIDefaultSkin
adapters.Note,
ISkinnable
andISkinType
and the skin implementation should be moved out of the browser request modules. Packages likez3c.jsonrpc
do not depend onIBrowserRequest
but they are skinnable.Feature: add
ISkinnable
interface which allows us to implement the apply skin pattern not only forIBrowserRequest
.Fix: Don’t cause warnings on Python 2.6
Fix: Make
IBrowserPage
inheritIBrowserView
.Move
IView
andIDefaultViewName
here fromzope.component.interfaces
. Stop inheriting from deprecated (for years) interfaces defined inzope.component
.Remove deprecated code.
Clean-up: Move
zope.testing
from extras to dependencies, per Zope Framework policy. Removezope.app.testing
as a dependency: tests run fine without it.
3.5.6 (2009-02-14)¶
- Fix an untested code path that incorrectly attempted to construct a
NotFound
, adding a test.
3.5.5 (2009-02-04)¶
- LP #322486:
setStatus()
now allows anyint()
-able status value.
3.5.4 (2008-09-22)¶
- LP #98440: interfaces lost on retried request
- LP #273296: dealing more nicely with malformed HTTP_ACCEPT_LANGUAGE headers within getPreferredLanguages().
- LP #253362: dealing more nicely with malformed HTTP_ACCEPT_CHARSET headers within getPreferredCharsets().
- LP #98284: Pass the
size
argument to readline, as the version of twisted used in zope.app.twisted supports it. - Fix the LP #98284 fix: do not pass
size
argument of None that causes cStringIO objects to barf with a TypeError.
3.5.3 (2008-06-20)¶
- It turns out that some Web servers (Paste for example) do not send the EOF character after the data has been transmitted and the read() of the cached stream simply hangs if no expected content length has been specified.
3.5.2 (2008-04-06)¶
A previous fix to handle posting of non-form data broke handling of form data with extra information in the content type, as in:
application/x-www-form-urlencoded; charset=UTF-8
3.5.1 (2008-03-23)¶
When posting non-form (and non-multipart) data, the request body was consumed and discarded. This makes it impossible to deal with other post types, like xml-rpc or json without resorting to overly complex “request factory” contortions.
https://bugs.launchpad.net/zope2/+bug/143873
zope.publisher.http.HTTPCharsets
was confused by the Zope 2 publisher, which gives misleading information about which headers it has.
3.5.0 (2008-03-02)¶
- Added a PasteDeploy app_factory implementation. This should make it easier to integrate Zope 3 applications with PasteDeploy. It also makes it easier to control the publication used, giving far greater control over application policies (e.g. whether or not to use the ZODB).
3.4.2 (2007-12-07)¶
- Made segmentation of URLs not strip (trailing) whitespace from path segments to allow URLs ending in %20 to be handled correctly. (#172742)
3.4.1 (2007-09-29)¶
No changes since 3.4.1b2.
3.4.1b2 (2007-08-02)¶
- Add support for Python 2.5.
- Fix a problem with
request.get()
when the object that’s to be retrieved is the request itself.
3.4.1b1 (2007-07-13)¶
No changes.
3.4.0b2 (2007-07-05)¶
- LP #122054:
HTTPInputStream
understands both the CONTENT_LENGTH and HTTP_CONTENT_LENGTH environment variables. It is also now tolerant of empty strings and will treat those as if the variable were absent.
3.4.0b1 (2007-07-05)¶
- Fix caching issue. The input stream never got cached in a temp file
because of a wrong content-length header lookup. Added CONTENT_LENGTH
header check in addition to the previous used HTTP_CONTENT_LENGTH. The
HTTP_
prefix is sometimes added by some CGI proxies, but CONTENT_LENGTH is the right header info for the size. - LP #98413:
HTTPResponse.handleException
should set the content type
3.4.0a1 (2007-04-22)¶
Initial release as a separate project, corresponds to zope.publisher from Zope 3.4.0a1
Project URLs¶
- https://pypi.python.org/pypi/zope.publisher (PyPI entry and downloads)