257 lines
8.6 KiB
Plaintext
257 lines
8.6 KiB
Plaintext
PEP: 222
|
||
Title: Web Library Enhancements
|
||
Version: $Revision$
|
||
Last-Modified: $Date$
|
||
Author: A.M. Kuchling <amk@amk.ca>
|
||
Status: Deferred
|
||
Type: Standards Track
|
||
Created: 18-Aug-2000
|
||
Python-Version: 2.1
|
||
Post-History: 22-Dec-2000
|
||
|
||
|
||
Abstract
|
||
|
||
This PEP proposes a set of enhancements to the CGI development
|
||
facilities in the Python standard library. Enhancements might be
|
||
new features, new modules for tasks such as cookie support, or
|
||
removal of obsolete code.
|
||
|
||
The original intent was to make improvements to Python 2.1.
|
||
However, there seemed little interest from the Python community,
|
||
and time was lacking, so this PEP has been deferred to some future
|
||
Python release.
|
||
|
||
|
||
Open Issues
|
||
|
||
This section lists changes that have been suggested, but about
|
||
which no firm decision has yet been made. In the final version of
|
||
this PEP, this section should be empty, as all the changes should
|
||
be classified as accepted or rejected.
|
||
|
||
cgi.py: We should not be told to create our own subclass just so
|
||
we can handle file uploads. As a practical matter, I have yet to
|
||
find the time to do this right, so I end up reading cgi.py's temp
|
||
file into, at best, another file. Some of our legacy code actually
|
||
reads it into a second temp file, then into a final destination!
|
||
And even if we did, that would mean creating yet another object
|
||
with its __init__ call and associated overhead.
|
||
|
||
cgi.py: Currently, query data with no `=' are ignored. Even if
|
||
keep_blank_values is set, queries like `...?value=&...' are
|
||
returned with blank values but queries like `...?value&...' are
|
||
completely lost. It would be great if such data were made
|
||
available through the FieldStorage interface, either as entries
|
||
with None as values, or in a separate list.
|
||
|
||
Utility function: build a query string from a list of 2-tuples
|
||
|
||
Dictionary-related utility classes: NoKeyErrors (returns an empty
|
||
string, never a KeyError), PartialStringSubstitution (returns
|
||
the original key string, never a KeyError)
|
||
|
||
|
||
|
||
New Modules
|
||
|
||
This section lists details about entire new packages or modules
|
||
that should be added to the Python standard library.
|
||
|
||
* fcgi.py : A new module adding support for the FastCGI protocol.
|
||
Robin Dunn's code needs to be ported to Windows, though.
|
||
|
||
Major Changes to Existing Modules
|
||
|
||
This section lists details of major changes to existing modules,
|
||
whether in implementation or in interface. The changes in this
|
||
section therefore carry greater degrees of risk, either in
|
||
introducing bugs or a backward incompatibility.
|
||
|
||
The cgi.py module would be deprecated. (XXX A new module or
|
||
package name hasn't been chosen yet: 'web'? 'cgilib'?)
|
||
|
||
Minor Changes to Existing Modules
|
||
|
||
This section lists details of minor changes to existing modules.
|
||
These changes should have relatively small implementations, and
|
||
have little risk of introducing incompatibilities with previous
|
||
versions.
|
||
|
||
|
||
Rejected Changes
|
||
|
||
The changes listed in this section were proposed for Python 2.1,
|
||
but were rejected as unsuitable. For each rejected change, a
|
||
rationale is given describing why the change was deemed
|
||
inappropriate.
|
||
|
||
* An HTML generation module is not part of this PEP. Several such
|
||
modules exist, ranging from HTMLgen's purely programming
|
||
interface to ASP-inspired simple templating to DTML's complex
|
||
templating. There's no indication of which templating module to
|
||
enshrine in the standard library, and that probably means that
|
||
no module should be so chosen.
|
||
|
||
* cgi.py: Allowing a combination of query data and POST data.
|
||
This doesn't seem to be standard at all, and therefore is
|
||
dubious practice.
|
||
|
||
Proposed Interface
|
||
|
||
XXX open issues: naming convention (studlycaps or
|
||
underline-separated?); need to look at the cgi.parse*() functions
|
||
and see if they can be simplified, too.
|
||
|
||
Parsing functions: carry over most of the parse* functions from
|
||
cgi.py
|
||
|
||
# The Response class borrows most of its methods from Zope's
|
||
# HTTPResponse class.
|
||
|
||
class Response:
|
||
"""
|
||
Attributes:
|
||
status: HTTP status code to return
|
||
headers: dictionary of response headers
|
||
body: string containing the body of the HTTP response
|
||
"""
|
||
|
||
def __init__(self, status=200, headers={}, body=""):
|
||
pass
|
||
|
||
def setStatus(self, status, reason=None):
|
||
"Set the numeric HTTP response code"
|
||
pass
|
||
|
||
def setHeader(self, name, value):
|
||
"Set an HTTP header"
|
||
pass
|
||
|
||
def setBody(self, body):
|
||
"Set the body of the response"
|
||
pass
|
||
|
||
def setCookie(self, name, value,
|
||
path = '/',
|
||
comment = None,
|
||
domain = None,
|
||
max-age = None,
|
||
expires = None,
|
||
secure = 0
|
||
):
|
||
"Set a cookie"
|
||
pass
|
||
|
||
def expireCookie(self, name):
|
||
"Remove a cookie from the user"
|
||
pass
|
||
|
||
def redirect(self, url):
|
||
"Redirect the browser to another URL"
|
||
pass
|
||
|
||
def __str__(self):
|
||
"Convert entire response to a string"
|
||
pass
|
||
|
||
def dump(self):
|
||
"Return a string representation useful for debugging"
|
||
pass
|
||
|
||
# XXX methods for specific classes of error:serverError,
|
||
# badRequest, etc.?
|
||
|
||
|
||
class Request:
|
||
|
||
"""
|
||
Attributes:
|
||
|
||
XXX should these be dictionaries, or dictionary-like objects?
|
||
.headers : dictionary containing HTTP headers
|
||
.cookies : dictionary of cookies
|
||
.fields : data from the form
|
||
.env : environment dictionary
|
||
"""
|
||
|
||
def __init__(self, environ=os.environ, stdin=sys.stdin,
|
||
keep_blank_values=1, strict_parsing=0):
|
||
"""Initialize the request object, using the provided environment
|
||
and standard input."""
|
||
pass
|
||
|
||
# Should people just use the dictionaries directly?
|
||
def getHeader(self, name, default=None):
|
||
pass
|
||
|
||
def getCookie(self, name, default=None):
|
||
pass
|
||
|
||
def getField(self, name, default=None):
|
||
"Return field's value as a string (even if it's an uploaded file)"
|
||
pass
|
||
|
||
def getUploadedFile(self, name):
|
||
"""Returns a file object that can be read to obtain the contents
|
||
of an uploaded file. XXX should this report an error if the
|
||
field isn't actually an uploaded file? Or should it wrap
|
||
a StringIO around simple fields for consistency?
|
||
"""
|
||
|
||
def getURL(self, n=0, query_string=0):
|
||
"""Return the URL of the current request, chopping off 'n' path
|
||
components from the right. Eg. if the URL is
|
||
"http://foo.com/bar/baz/quux", n=2 would return
|
||
"http://foo.com/bar". Does not include the query string (if
|
||
any)
|
||
"""
|
||
|
||
def getBaseURL(self, n=0):
|
||
"""Return the base URL of the current request, adding 'n' path
|
||
components to the end to recreate more of the whole URL.
|
||
|
||
Eg. if the request URL is
|
||
"http://foo.com/q/bar/baz/qux", n=0 would return
|
||
"http://foo.com/", and n=2 "http://foo.com/q/bar".
|
||
|
||
Returned URL does not include the query string, if any.
|
||
"""
|
||
|
||
def dump(self):
|
||
"String representation suitable for debugging output"
|
||
pass
|
||
|
||
# Possibilities? I don't know if these are worth doing in the
|
||
# basic objects.
|
||
def getBrowser(self):
|
||
"Returns Mozilla/IE/Lynx/Opera/whatever"
|
||
|
||
def isSecure(self):
|
||
"Return true if this is an SSLified request"
|
||
|
||
|
||
# Module-level function
|
||
def wrapper(func, logfile=sys.stderr):
|
||
"""
|
||
Calls the function 'func', passing it the arguments
|
||
(request, response, logfile). Exceptions are trapped and
|
||
sent to the file 'logfile'.
|
||
"""
|
||
# This wrapper will detect if it's being called from the command-line,
|
||
# and if so, it will run in a debugging mode; name=value pairs
|
||
# can be entered on standard input to set field values.
|
||
# (XXX how to do file uploads in this syntax?)
|
||
|
||
|
||
Copyright
|
||
|
||
This document has been placed in the public domain.
|
||
|
||
|
||
|
||
Local Variables:
|
||
mode: indented-text
|
||
indent-tabs-mode: nil
|
||
End:
|