diff options
-rw-r--r-- | wsgitools/applications.py | 10 | ||||
-rwxr-xr-x | wsgitools/digest.py | 16 | ||||
-rw-r--r-- | wsgitools/filters.py | 101 | ||||
-rw-r--r-- | wsgitools/middlewares.py | 21 | ||||
-rw-r--r-- | wsgitools/scgi/asynchronous.py | 18 | ||||
-rw-r--r-- | wsgitools/scgi/forkpool.py | 15 |
6 files changed, 93 insertions, 88 deletions
diff --git a/wsgitools/applications.py b/wsgitools/applications.py index 909500e..33823bd 100644 --- a/wsgitools/applications.py +++ b/wsgitools/applications.py @@ -14,7 +14,7 @@ class StaticContent: @type status: str @param status: is the HTTP status returned to the browser (ex: "200 OK") @type headers: list - @param headers: is a list of (header, value) pairs being delivered as + @param headers: is a list of C{(header, value)} pairs being delivered as HTTP headers @type content: basestring @param content: contains the data to be delivered to the client. It is @@ -62,13 +62,13 @@ class StaticFile: @type status: str @param status: is the HTTP status returned to the browser @type headers: [(str, str)] - @param headers: is a list of (header, value) pairs being delivered as + @param headers: is a list of C{(header, value)} pairs being delivered as HTTP headers @type filelike: str or file-like @param filelike: may either be an path in the local file system or a - file-like that must support read(size) and seek(0). If tell() - is present, seek(0, 2) and tell() will be used to compute the - content-length. + file-like that must support C{read(size)} and C{seek(0)}. If + C{tell()} is present, C{seek(0, 2)} and C{tell()} will be used + to compute the content-length. @type blocksize: int @param blocksize: the content is provided in chunks of this size """ diff --git a/wsgitools/digest.py b/wsgitools/digest.py index 63227be..0aca584 100755 --- a/wsgitools/digest.py +++ b/wsgitools/digest.py @@ -47,7 +47,7 @@ class AuthenticationRequired(Exception): __all__.append("AuthTokenGenerator") class AuthTokenGenerator: - """Generates authentification tokens for AuthDigestMiddleware. The + """Generates authentification tokens for L{AuthDigestMiddleware}. The interface consists of beeing callable with a username and having a realm attribute being a string.""" def __init__(self, realm, getpass): @@ -56,7 +56,8 @@ class AuthTokenGenerator: @param realm: is a string according to RFC2617. @type getpass: str -> str @param getpass: this function is called with a username and password is - expected as result. None may be used as an invalid password.""" + expected as result. C{None} may be used as an invalid password. + """ self.realm = realm self.getpass = getpass def __call__(self, username, algo="md5"): @@ -119,7 +120,7 @@ class StatelessNonceStore(NonceStoreBase): it difficult by posing a timeout on nonces and making it difficult to forge nonces. - This nonce store is usable with scgi.forkpool. + This nonce store is usable with L{scgi.forkpool}. """ def __init__(self, maxage=300, secret=None): """ @@ -298,12 +299,13 @@ class AuthDigestMiddleware: @param app: is the wsgi application to be served with authentification. @type gentoken: str -> str @param gentoken: has to have the same functionality and interface as the - AuthTokenGenerator class. + L{AuthTokenGenerator} class. @type maxage: int - @param maxage: deprecated, see MemoryNonceStore or StatelessNonceStore + @param maxage: deprecated, see L{MemoryNonceStore} or + L{StatelessNonceStore} @type maxuses: int - @param maxuses: deprecated, see MemoryNonceStore - @type store: NonceStoreBase + @param maxuses: deprecated, see L{MemoryNonceStore} + @type store: L{NonceStoreBase} @param store: a nonce storage implementation object. Usage of this parameter will override maxage and maxuses. """ diff --git a/wsgitools/filters.py b/wsgitools/filters.py index 943f56b..b0bf8e1 100644 --- a/wsgitools/filters.py +++ b/wsgitools/filters.py @@ -2,7 +2,7 @@ This module contains a generic way to create middelwares that filter data. The work is mainly done by the L{WSGIFilterMiddleware} class. One can write filters by extending the L{BaseWSGIFilter} class and passing this class -(not an instance) to the C{WSGIFilterMiddleware} constructor. +(not an instance) to the L{WSGIFilterMiddleware} constructor. """ __all__ = [] @@ -19,10 +19,10 @@ __all__.append("CloseableIterator") class CloseableIterator: """Concatenating iterator with close attribute.""" def __init__(self, close_function, *iterators): - """If close_function is not None, it will be the close attribute of - the created iterator object. Further parameters specify iterators + """If close_function is not C{None}, it will be the C{close} attribute + of the created iterator object. Further parameters specify iterators that are to be concatenated. - @type close_function: a function or None + @type close_function: a function or C{None} """ if close_function is not None: self.close = close_function @@ -46,10 +46,10 @@ __all__.append("CloseableList") class CloseableList(list): """A list with a close attribute.""" def __init__(self, close_function, *args): - """If close_function is not None, it will be the close attribute of - the created list object. Other parameters are passed to the list + """If close_function is not C{None}, it will be the C{close} attribute + of the created list object. Other parameters are passed to the list constructor. - @type close_function: a function or None + @type close_function: a function or C{None} """ if close_function is not None: self.close = close_function @@ -64,17 +64,17 @@ class BaseWSGIFilter: """Generic WSGI filter class to be used with L{WSGIFilterMiddleware}. For each request a filter object gets created. - The environment is then passed through filter_environ. - Possible exceptions are filtered by filter_exc_info. - After that for each (header, value) tuple filter_header is used. - The resulting list is filtered through filter_headers. - Any data is filtered through filter_data. - In order to possibly append data the append_data method is invoked. - When the request has finished handle_close is invoked. + The environment is then passed through L{filter_environ}. + Possible exceptions are filtered by L{filter_exc_info}. + After that for each C{(header, value)} tuple L{filter_header} is used. + The resulting list is filtered through L{filter_headers}. + Any data is filtered through L{filter_data}. + In order to possibly append data the L{append_data} method is invoked. + When the request has finished L{handle_close} is invoked. All methods do not modify the passed data by default. Passing the - BaseWSGIFilter class to a WSGIFilterMiddleware will result in not modifying - the request at all. + L{BaseWSGIFilter} class to a L{WSGIFilterMiddleware} will result in not + modifying requests at all. """ def __init__(self): """This constructor does nothing and can safely be overwritten. It is @@ -83,28 +83,28 @@ class BaseWSGIFilter: pass def filter_environ(self, environ): """Receives a dict with the environment passed to the wsgi application - and a dict must be returned. The default is to return the same dict. + and a C{dict} must be returned. The default is to return the same dict. @type environ: {str: str} @rtype: {str: str} """ return environ def filter_exc_info(self, exc_info): - """Receives either None or a tuple passed as third argument to - start_response from the wrapped wsgi application. Either None or such a - tuple must be returned.""" + """Receives either C{None} or a tuple passed as third argument to + C{start_response} from the wrapped wsgi application. Either C{None} or + such a tuple must be returned.""" return exc_info def filter_status(self, status): - """Receives a status string passed as first argument to start_response - from the wrapped wsgi application. A valid HTTP status string must be - returned. + """Receives a status string passed as first argument to + C{start_response} from the wrapped wsgi application. A valid HTTP status + string must be returned. @type status: str @rtype: str """ return status def filter_header(self, headername, headervalue): - """This function is invoked for each (headername, headervalue) tuple in - the second argument to the start_response from the wrapped wsgi - application. Such a value or None for discarding the header must be + """This function is invoked for each C{(headername, headervalue)} tuple + in the second argument to the C{start_response} from the wrapped wsgi + application. Such a value or C{None} for discarding the header must be returned. @type headername: str @type headervalue: str @@ -112,15 +112,15 @@ class BaseWSGIFilter: """ return (headername, headervalue) def filter_headers(self, headers): - """A list of headers passed as the second argument to the start_response - from the wrapped wsgi application is passed to this function and such a - list must also be returned. + """A list of headers passed as the second argument to the + C{start_response} from the wrapped wsgi application is passed to this + function and such a list must also be returned. @type headers: [(str, str)] @rtype: [(str, str)] """ return headers def filter_data(self, data): - """For each string that is either written by the write callable or + """For each string that is either written by the C{write} callable or returned from the wrapped wsgi application this method is invoked. It must return a string. @type data: str @@ -140,14 +140,14 @@ class BaseWSGIFilter: __all__.append("WSGIFilterMiddleware") class WSGIFilterMiddleware: - """This wsgi middleware can be used with specialized BaseWSGIFilters to + """This wsgi middleware can be used with specialized L{BaseWSGIFilter}s to modify wsgi requests and/or reponses.""" def __init__(self, app, filterclass): """ @param app: is a wsgi application. @type filterclass: L{BaseWSGIFilter}s subclass - @param filterclass: is a subclass of BaseWSGIFilter or some class that - implements the interface.""" + @param filterclass: is a subclass of L{BaseWSGIFilter} or some class + that implements the interface.""" self.app = app self.filterclass = filterclass def __call__(self, environ, start_response): @@ -184,8 +184,8 @@ class WSGIFilterMiddleware: + list(reqfilter.append_data())) ret = iter(ret) def late_append_data(): - """Invoke reqfilter.append_data() after filter_data() has seen all - data.""" + """Invoke C{reqfilter.append_data()} after C{filter_data()} has seen + all data.""" for data in reqfilter.append_data(): yield data return CloseableIterator(modified_close, @@ -197,8 +197,8 @@ class RequestLogWSGIFilter(BaseWSGIFilter): """This filter logs all requests in the apache log file format.""" @classmethod def creator(cls, log): - """Returns a function creating RequestLogWSGIFilters on given log file. - log has to be a file-like object. + """Returns a function creating L{RequestLogWSGIFilter}s on given log + file. log has to be a file-like object. @type log: file-like """ return lambda:cls(log) @@ -263,13 +263,13 @@ __all__.append("TimerWSGIFilter") class TimerWSGIFilter(BaseWSGIFilter): """Replaces a specific string in the data returned from the filtered wsgi application with the time the request took. The string has to be exactly - eight bytes long, defaults to "?GenTime" and must be an element of the + eight bytes long, defaults to C{"?GenTime"} and must be an element of the iterable returned by the filtered application. If the application returns - something like ["spam?GenTime", "?GenTime spam", "?GenTime"] only the last - occurance get's replaced.""" + something like C{["spam?GenTime", "?GenTime spam", "?GenTime"]} only the + last occurance get's replaced.""" @classmethod def creator(cls, pattern): - """Returns a function creating TimerWSGIFilters with a given pattern + """Returns a function creating L{TimerWSGIFilter}s with a given pattern beeing a string of exactly eight bytes. @type pattern: str """ @@ -298,7 +298,8 @@ class EncodeWSGIFilter(BaseWSGIFilter): """ @classmethod def creator(cls, charset): - """Returns a function creating EncodeWSGIFilters with a given charset. + """Returns a function creating L{EncodeWSGIFilter}s with a given + charset. @type charset: str """ return lambda:cls(charset) @@ -330,7 +331,7 @@ class GzipWSGIFilter(BaseWSGIFilter): @classmethod def creator(cls, flush=True): """ - Returns a function creating GzipWSGIFilters. + Returns a function creating L{GzipWSGIFilter}s. @type flush: bool @param flush: whether or not the filter should always flush the buffer """ @@ -392,28 +393,28 @@ class GzipWSGIFilter(BaseWSGIFilter): return [data] class ReusableWSGIInputFilter(BaseWSGIFilter): - """Make environ["wsgi.input"] readable multiple times. Although this is not - required by the standard it is sometimes desirable to read wsgi.input + """Make C{environ["wsgi.input"]} readable multiple times. Although this is + not required by the standard it is sometimes desirable to read C{wsgi.input} multiple times. This filter will therefore replace that variable with a - StringIO instance which provides a seek method. + C{StringIO} instance which provides a C{seek} method. """ @classmethod def creator(cls, maxrequestsize): """ - Returns a function creating ReusableWSGIInputFilters with desired + Returns a function creating L{ReusableWSGIInputFilter}s with desired maxrequestsize being set. If there is more data than maxrequestsize is - available in wsgi.input the rest will be ignored. (It is up to the + available in C{wsgi.input} the rest will be ignored. (It is up to the adapter to eat this data.) @type maxrequestsize: int @param maxrequestsize: is the maximum number of bytes to store in the - StringIO + C{StringIO} """ return lambda:cls(maxrequestsize) def __init__(self, maxrequestsize=65536): """ReusableWSGIInputFilters constructor. @type maxrequestsize: int @param maxrequestsize: is the maximum number of bytes to store in the - StringIO, see creator + C{StringIO}, see L{creator} """ BaseWSGIFilter.__init__(self) self.maxrequestsize = maxrequestsize diff --git a/wsgitools/middlewares.py b/wsgitools/middlewares.py index 908b5b3..146d7a5 100644 --- a/wsgitools/middlewares.py +++ b/wsgitools/middlewares.py @@ -45,8 +45,8 @@ class SubdirMiddleware: __all__.append("NoWriteCallableMiddleware") class NoWriteCallableMiddleware: """This middleware wraps a wsgi application that needs the return value of - start_response function to a wsgi application that doesn't need one by - writing the data to a StringIO and then making it be the first result + C{start_response} function to a wsgi application that doesn't need one by + writing the data to a C{StringIO} and then making it be the first result element.""" def __init__(self, app): """Wraps wsgi application app.""" @@ -106,14 +106,14 @@ class NoWriteCallableMiddleware: __all__.append("ContentLengthMiddleware") class ContentLengthMiddleware: """Guesses the content length header if possible. - @note: The application used must not use the write callable returned by - start_response.""" + @note: The application used must not use the C{write} callable returned by + C{start_response}.""" def __init__(self, app, maxstore=0): """Wraps wsgi application app. It can also store the first result bytes to possibly return a list of strings which will make guessing the size of iterators possible. At most maxstore bytes will be accumulated. Please note that a value larger than 0 will violate the wsgi standard. - The magical value () will make it always gather all data. + The magical value C{()} will make it always gather all data. @type maxstore: int or () """ self.app = app @@ -192,15 +192,15 @@ def cacheable(environ): __all__.append("CachingMiddleware") class CachingMiddleware: - """Caches reponses to requests based on SCRIPT_NAME, PATH_INFO and - QUERY_STRING.""" + """Caches reponses to requests based on C{SCRIPT_NAME}, C{PATH_INFO} and + C{QUERY_STRING}.""" def __init__(self, app, maxage=60, storable=storable, cacheable=cacheable): """ @param app: is a wsgi application to be cached. @type maxage: int @param maxage: is the number of seconds a reponse may be cached. @param storable: is a predicate that determines whether the response - may be cached at all based on the environ dict. + may be cached at all based on the C{environ} dict. @param cacheable: is a predicate that determines whether this request invalidates the cache.""" self.app = app @@ -278,7 +278,8 @@ class BasicAuthMiddleware: @param check_function: is a function taking three arguments username, password and environment returning a bool indicating whether the request may is allowed. The older interface of taking only the - first two arguments is still supported via catching a TypeError. + first two arguments is still supported via catching a + C{TypeError}. @type realm: str @param app401: is an optional WSGI application to be used for error messages @@ -333,7 +334,7 @@ class BasicAuthMiddleware: __all__.append("TracebackMiddleware") class TracebackMiddleware: """In case the application throws an exception this middleware will show an - html-formatted traceback using cgitb.""" + html-formatted traceback using C{cgitb}.""" def __init__(self, app): """app is the wsgi application to proxy.""" self.app = app diff --git a/wsgitools/scgi/asynchronous.py b/wsgitools/scgi/asynchronous.py index 338fac9..81ed567 100644 --- a/wsgitools/scgi/asynchronous.py +++ b/wsgitools/scgi/asynchronous.py @@ -9,7 +9,7 @@ except ImportError: import StringIO class SCGIConnection(asyncore.dispatcher): - """SCGI connection class used by WSGISCGIServer.""" + """SCGI connection class used by L{SCGIServer}.""" # connection states NEW = 0*4 | 1 # connection established, waiting for request HEADER = 1*4 | 1 # the request length was received, waiting for the rest @@ -59,15 +59,15 @@ class SCGIConnection(asyncore.dispatcher): self.outbuff += data def readable(self): - """asyncore interface""" + """C{asyncore} interface""" return self.state & 1 == 1 def writable(self): - """asyncore interface""" + """C{asyncore} interface""" return self.state & 2 == 2 def handle_read(self): - """asyncore interface""" + """C{asyncore} interface""" data = self.recv(self.blocksize) self.inbuff += data if self.state == SCGIConnection.NEW: @@ -148,7 +148,7 @@ class SCGIConnection(asyncore.dispatcher): return self._wsgi_write def handle_write(self): - """asyncore interface""" + """C{asyncore} interface""" assert self.state >= SCGIConnection.REQ if len(self.outbuff) < self.blocksize: self._try_send_headers() @@ -173,7 +173,7 @@ class SCGIConnection(asyncore.dispatcher): self.outbuff = self.outbuff[sentbytes:] def handle_close(self): - """asyncore interface""" + """C{asyncore} interface""" self.close() __all__.append("SCGIServer") @@ -188,9 +188,9 @@ class SCGIServer(asyncore.dispatcher): @param port: is an int representing the TCP port number to be used. @type interface: str @param interface: is a string specifying the network interface to bind - which defaults to "localhost" making the server inaccessible + which defaults to C{"localhost"} making the server inaccessible over network. - @param error: is a file-like object being passed as wsgi.error in the + @param error: is a file-like object being passed as C{wsgi.error} in the environ parameter defaulting to stderr. @type maxrequestsize: int @param maxrequestsize: limit the size of request blocks in scgi @@ -229,6 +229,6 @@ class SCGIServer(asyncore.dispatcher): def run(self): """Runs the server. It will not return and you can invoke - asyncore.loop() instead achieving the same effect.""" + C{asyncore.loop()} instead achieving the same effect.""" asyncore.loop() diff --git a/wsgitools/scgi/forkpool.py b/wsgitools/scgi/forkpool.py index 3058316..0393bb1 100644 --- a/wsgitools/scgi/forkpool.py +++ b/wsgitools/scgi/forkpool.py @@ -1,5 +1,5 @@ """ -The forkpool.SCGIServer adapts a wsgi application to a scgi service. +The L{forkpool.SCGIServer} adapts a wsgi application to a scgi service. It works with multiple processes that are periodically cleaned up to prevent memory leaks having an impact to the system. @@ -14,7 +14,7 @@ import errno class SocketFileWrapper: """Wraps a socket to a wsgi-compliant file-like object.""" def __init__(self, sock, toread): - """@param sock: is a socket.socket()""" + """@param sock: is a C{socket.socket()}""" self.sock = sock self.buff = "" self.toread = toread @@ -47,7 +47,8 @@ class SocketFileWrapper: def close(self): """Does not close the socket, because it might still be needed. It - reads all data that should have been read as given by CONTENT_LENGTH.""" + reads all data that should have been read as given by C{CONTENT_LENGTH}. + """ try: while self.toread > 0: if self.toread > 4096: @@ -155,8 +156,8 @@ class SocketFileWrapper: map(self.write, lines) class SCGIServer: - """Usage: create an SCGIServer object and invoke the run method which will - then turn this process into an scgi server.""" + """Usage: create an L{SCGIServer} object and invoke the run method which + will then turn this process into an scgi server.""" class WorkerState: """state: 0 means idle and 1 means working. These values are also sent as strings '0' and '1' over the socket.""" @@ -172,8 +173,8 @@ class SCGIServer: @type port: int @param port: is the tcp port to listen on @type interface: str - @param interface: is the interface to bind to (default: "localhost") - @param error: is a filelike object beeing passed as wsgi.error in + @param interface: is the interface to bind to (default: C{"localhost"}) + @param error: is a file-like object beeing passed as C{wsgi.error} in environ @type minworkers: int @param minworkers: is the number of worker processes to spawn |