module poorwsgi link | top
Poor WSGI connector for Python
Current Contents:
request: Request and FieldStorage classes, which are used for managing requests.
response: Response classes and functions for creating HTTP responses.
results: Default result handlers for the connector, such as directory index, server errors, or debug output handlers.
state: Constants like HTTP status codes and method types.
wsgi: The Application callable class, which is the main entry point for a PoorWSGI web application.
digest: HTTP Digest Authorization support.
openapi_wrapper: OpenAPI core wrapper for PoorWSGI Request and Response objects.
module wsgi link | top
Application callable class, which is the main entry point for a WSGI application.
| Classes: | |
|---|---|
| Functions: |
class Application link | top
Poor WSGI application that is called by the WSGI server.
Its working is described in PEP 333. This object stores the route dispatch table, and has methods for its use, as well as a __call__ method for use as a WSGI application.
after (READ) top
A tuple of after-response handlers.
auth_algorithm (READ | WRITE) top
Authorization algorithm.
The algorithm depends on the authorization type and client support. Supported:
| Digest: | MD5 | MD5-sess | SHA256 | SHA256-sess |
|---|---|
| default: | MD5-sess |
auth_hash (READ) top
Returns the authorization hash function.
The function can be changed by the auth_algorithm property.
| default: | md5 |
|---|
auth_qop (READ | WRITE) top
Authorization quality of protection.
This is used for Digest authorization only. PoorWSGI supports only
auth or an empty value, consistent with common browser support.
| default: | auth |
|---|
auth_timeout (READ | WRITE) top
Digest Authorization timeout for the nonce value in seconds.
In fact, the timeout will be between timeout and 2*timeout because time alignment is used. If timeout is None or 0, no timeout is used.
| default: | 300 (5 min) |
|---|
auth_type (READ | WRITE) top
Authorization type.
Only the Digest type is currently supported.
auto_args (READ | WRITE) top
Automatic parsing of request arguments from the URI.
If it is True (default), the Request object automatically parses the request URI into its args variable.
auto_cookies (READ | WRITE) top
Automatic parsing of cookies from request headers.
If it is True (default) and the Cookie request header is set, a SimpleCookie object is parsed to the Request property cookies.
auto_data (READ | WRITE) top
Enables the Request.data property for smaller requests.
Default value is True.
auto_form (READ | WRITE) top
Automatic parsing of arguments from the request body.
If it is True (default) and the method is POST, PUT, or PATCH, and the request MIME type is one of form_mime_types, the Request object automatically parses the request body into its form variable.
auto_json (READ | WRITE) top
Automatic parsing of JSON from the request body.
If it is True (default), the method is POST, PUT, or PATCH, and the request MIME type is one of json_mime_types, the Request object automatically parses the request body into the json variable.
before (READ) top
A tuple of before-response handlers.
cached_size (READ | WRITE) top
Enables cached_size for faster POST requests.
Default value is 65365.
data_size (READ | WRITE) top
Size limit for the Request.data property.
This value is compared to the request's Content-Length. The default value is 32768 (30KB).
debug (READ | WRITE) top
Application debug mode, as another way to set poor_Debug.
This setting will be overridden by the poor_Debug environment variable.
defaults (READ) top
A copy of the table with default handlers.
document_index (READ | WRITE) top
The application's document_index, as another way to set poor_DocumentIndex.
This setting will be overridden by the poor_DocumentIndex environment variable.
document_root (READ | WRITE) top
The application's document_root, as another way to set poor_DocumentRoot.
This setting will be overridden by the poor_DocumentRoot environment variable.
errors (READ) top
A copy of the table with exception handlers.
file_callback (READ | WRITE) top
A file callback used as a parameter when parsing the request body.
Default is None. The value can be a class or factory that receives a filename from the request body and has a file-compatible interface.
filters (READ) top
A copy of the filter table.
The filter table contains regular expressions and conversion functions; see Application.set_filter and Application.route.
Default filters are:
:int matches a number and converts it to an int
:float matches a number and converts it to a float
:word matches a single string word
:hex matches a hexadecimal value and converts it to a str
:re: matches a user-defined regular expression
none matches any string without the '/' character
For more details, see the /debug-info page of your application, where you can find all filters with their regular expression definitions.
form_mime_types (READ) top
A copy of the form MIME type list.
Contains a list of strings as form MIME types, which are used for testing when an automatic Form object is created from the request body.
json_mime_types (READ) top
A copy of the JSON MIME type list.
Contains a list of strings as JSON MIME types, which are used for testing when an automatic JSON object is created from the request body.
keep_blank_values (READ | WRITE) top
Keeps blank values in request arguments.
If it is 1 (0 is default), automatic parsing of the request URI or body will keep blank values as empty strings.
name (READ) top
read_timeout (READ | WRITE) top
regular_routes (READ) top
A copy of the table with regular expression handlers.
routes (READ) top
A copy of the table with static handlers.
See Application.route.
secret_key (READ | WRITE) top
The application's secret_key can be overridden by poor_SecretKey in the request.
The secret key is used by the PoorSession class. It is generated from some server variables; it is best to set it to your own long key.
states (READ) top
A copy of the table with HTTP state handlers.
strict_parsing (READ | WRITE) top
Strict parsing of request arguments.
If it is 1 (0 is default), automatic parsing of the request URI or body will raise an exception on a parsing error.
def __call__(self, env, start_response) link | top
Callable defined for the Application instance.
This method runs the __request__ method.
def __init__(self, name='__main__') link | top
The Application class is a per-name singleton.
That means, there can only be one instance with the same name.
def __profile_request__(self, env, start_response) link | top
Profiler version of __request__.
This method is used if set_profile is called.
def __repr__(self) link | top
def __request__(self, env, start_response) link | top
Creates a Request instance and returns a WSGI response.
This method creates a Request object, calls handlers from Application.before, the URI handler (handler_from_table), the default handler (Application.defaults) or the error handler (Application.state_from_table), and handlers from Application.after.
def add_after_request(self, fun: Callable) link | top
def add_after_response(self, fun: Callable) link | top
Appends a handler to call after each response.
This method directly appends a function to the list of functions that are called after each response.
def after_each_response(request, response): print("Response out") return response app.add_after_response(after_each_response)
def add_before_request(self, fun: Callable) link | top
def add_before_response(self, fun: Callable) link | top
Appends a handler to call before each response.
This method adds a function to the list of functions that are called before each response.
def before_each_response(req):
print("Response coming")
app.add_before_response(before_each_response)
def after_request(self) link | top
def after_response(self) link | top
Appends a handler to call after each response.
This decorator appends a function to be called after each response. The handler must return a response object.
@app.after_response() def after_each_response(request, response): print("Response out") return response
def before_request(self) link | top
def before_response(self) link | top
Appends a handler to call before each response.
This is a decorator for a function to call before each response.
@app.before_response()
def before_each_response(req):
print("Response coming")
def default(self, method: int = 3) link | top
Sets a default handler.
This is a decorator for a default handler for an HTTP method (called before error_not_found).
@app.default(METHOD_GET_POST) def default_get_post(req): # Called if no URI matches in the internal URI table for # the method. Similar to a not_found error, but without # an error. ...
def del_profile(self) link | top
def error_from_table(self, req: poorwsgi.request.SimpleRequest, error: Exception) link | top
def error_handler(self, error: Type[Exception], method: int = 7) link | top
Wraps a function to handle exceptions.
@app.error_handler(ValueError)
def value_error(req, error):
log.exception("ValueError %s", error)
return "Values %s are not correct." % req.args, "text/plain"
def get_options() link | top
Returns a dictionary with application variables from the system environment.
Application variables start with the app_ prefix,
but in the returned dictionary, they are set without this prefix.
app_db_server = localhost # application variable db_server app_templates = app/templ # application variable templates
This method works like Request.get_options, but it works with os.environ, so it is effective only with WSGI servers that set not only the request environment, but also os.environ. Apache's mod_wsgi does not do that; uWsgi and PoorHTTP do.
def handler_from_before(self, req: poorwsgi.request.SimpleRequest) link | top
Internal method, which runs all before (pre_process) handlers.
This method is called before the endpoint route handler.
def handler_from_default(self, req: poorwsgi.request.SimpleRequest) link | top
def handler_from_table(self, req: poorwsgi.request.Request) link | top
Calls the correct handler from the handlers table (populated by the route function).
If no handler is found, it attempts to serve a file from Document Root or a directory listing if Document Index is also enabled. Then it attempts to call the default handler for the correct method or calls the handler for status code 404 (Not Found).
def http_state(self, status_code: int, method: int = 7) link | top
Wraps a function to handle HTTP status codes.
@app.http_state(state.HTTP_NOT_FOUND) def page_not_found(req, *_): return "Your page %s was not found." % req.path, "text/plain"
def is_regular_route(self, r_uri) link | top
def is_route(self, uri: str) link | top
def pop_after_request(self, fun: Callable) link | top
def pop_after_response(self, fun: Callable) link | top
def pop_before_request(self, fun: Callable) link | top
def pop_before_response(self, fun: Callable) link | top
def pop_default(self, method: int) link | top
def pop_error_handler(self, error: Type[Exception], method: int) link | top
Pops a handler for an exception and method.
Similar to Application.pop_route, to pop a multi-method handler, you must call pop_error_handler for each method.
def pop_http_state(self, status_code: int, method: int) link | top
Pops a handler for an HTTP state and method.
Similar to Application.pop_route, to pop a multi-method handler, you must call pop_http_state for each method.
def pop_regular_route(self, uri: str, method: int) link | top
Pops a handler and converters for a URI and method from the handlers table.
For more details, see Application.pop_route.
def pop_route(self, uri: str, method: int) link | top
Pops a handler for a URI and method from the handlers table.
The method must be defined uniquely, so METHOD_GET_POST cannot be used. If you want to remove a handler for both methods, you must call pop_route for each method state.
def regular_route(self, ruri: str, method: int = 3) link | top
Wraps a function to be a handler for a URI defined by a regular expression.
Both regular_route and set_regular_route functions store routes in a special internal table, which is separate from the table of static routes.
# simple regular expression
@app.regular_route(r'/user/\w+')
def any_user(req):
...
# regular expression with named group
@app.regular_route(r'/user/(?P<user>\w+)')
def user_detail(req, user): # named path args
...
Be mindful of the ordering when calling this decorator or the set_regular_route function. Regular expression routes are checked in the same order as they are created in the internal table. The first match stops any further searching.
def route(self, uri: str, method: int = 3) link | top
Wraps a function to be a handler for a URI and specified method.
You can define the URI as a static path or with groups, which are passed to the handler as subsequent parameters.
# static URI
@app.route('/user/post', method=METHOD_POST)
def user_create(req):
...
# group regular expression
@app.route('/user/<name>')
def user_detail(req, name):
...
# group regular expression with filter
@app.route('/<surname:word>/<age:int>')
def surnames_by_age(req, surname, age):
...
# group with its own regular expression filter
@app.route('/<car:re:\w+>/<color:re:#[\da-fA-F]+>')
def car(req, car, color):
...
If you need to use a group name that is a Python keyword, such as
'class', you can use the **kwargs syntax:
@app.route('/<class>/<len:int>')
def classes(req, **kwargs):
return ("'%s' class is %d length." %
(kwargs['class'], kwargs['len']))
Be mindful of the ordering when calling this decorator or the set_route function with group regular expressions. Regular expression routes are checked in the same order as they are created in the internal table. The first match stops any further searching. In fact, if groups are detected, they will be transferred to normal regular expressions and added to a second internal table.
def set_default(self, fun: Callable, method: int = 3) link | top
Sets a default handler.
Sets fun as the default handler for the HTTP method, called before
error_not_found.
app.set_default(default_get_post, METHOD_GET_POST)
def set_error_handler(self, error: Type[Exception], fun: Callable, method: int = 7) link | top
def set_filter(self, name: str, regex: str, converter: Callable = <class 'str'>) link | top
Creates a new filter or overwrites built-ins.
- name
The name of the filter used in the route or set_route method.
- regex
The regular expression used for the filter.
- converter
The converter function or class that takes a string as input. The default is the str function, which calls the __str__ method on the input object.
app.set_filter('uint', r'\d+', int)
def set_http_state(self, status_code: int, fun: Callable, method: int = 7) link | top
def set_profile(self, runctx, dump) link | top
Sets a profiler for the __call__ function.
- runctx
Function from the profiler module.
- dump
Path and prefix for .profile files.
Typical usage:
import cProfile
cProfile.runctx('from simple import *', globals(), locals(),
filename="log/init.profile")
app.set_profile(cProfile.runctx, 'log/req')
def set_regular_route(self, uri: str, fun: Callable, method: int = 3, converters=(), rule: Optional[str] = None) link | top
Sets a handler for a URI defined by a regular expression.
Another way to add fun as a handler for a URI defined by a
regular expression. See Application.regular_route documentation
for details.
app.set_regular_route('/use/\w+/post', user_create, METHOD_POST)
This method is used internally when groups are found in a static route, added by the route or set_route method.
def set_route(self, uri: str, fun: Callable, method: int = 3) link | top
Sets a handler for a URI and method.
Another way to add fun as a handler for the URI. See
Application.route documentation for details.
app.set_route('/use/post', user_create, METHOD_POST)
def state_from_table(self, req: poorwsgi.request.SimpleRequest, status_code: int, **kwargs) link | top
Internal method, which is called if another HTTP state has occurred.
If the status code is in Application.shandlers (filled with the http_state function), this handler is called.
def to_response(response) link | top
AUTH_DIGEST_ALGORITHMS = {'MD5': <built-in function openssl_md5>, 'MD5-sess': <built-in function openssl_md5>, 'SHA-256': <built-in function openssl_sha256>, 'SHA-256-sess': <built-in function openssl_sha256>} top
log = <Logger poorwsgi (WARNING)> top
re_filter = (<(\w+)(:[^>]+)?>, 32) top
re_invalid_filter = (<\s+\w+|<\w+\s+[:|>]|<\w+:\s+\w+|<\w+:[^>]+\s+>, 32) top
module request link | top
Classes that are used for managing requests.
| Classes: | SimpleRequest, Request, EmptyForm, Args, Json |
|---|
class Args link | top
Compatibility class for reading values from QUERY_STRING.
This class is based on a dictionary. It has getfirst and getlist methods, which can call a function on the values.
def __init__(self, req: request.Request, keep_blank_values=0, strict_parsing=0) link | top
def getfirst(self, key: str, default: Any = None, func: Callable = poorwsgi.fieldstorage.<lambda>, fce: Optional[Callable] = None) link | top
Gets the first item from a list for a key, or a default value.
- default
The default value if the key does not exist.
- func
The function that processes the value.
- fce
Deprecated converter name. Use the func converter, just like getvalue.
def getlist(self, key: str, default: Optional[list] = None, func: Callable = poorwsgi.fieldstorage.<lambda>, fce: Optional[Callable] = None) link | top
Returns a list of variable values for a key, or an empty list.
- default
The default list if the key does not exist.
- func
The function that processes each value.
- fce
Deprecated converter name. Use the func converter, just like getvalue.
def getvalue(self, key: str, default: Any = None, func: Callable = poorwsgi.fieldstorage.<lambda>) link | top
Returns the value for the given key, applying func to it.
- key
The key name.
- default
The default value if the key is not found.
- func
The function or class that processes the value. The default type of value is bytes for files and string for others.
class CachedInput link | top
A wrapper around the wsgi.input file that reads data block by block.
- timeout
How long to wait for new bytes, in seconds.
def __init__(self, file, size, block_size=32768, timeout: Optional[float] = 10.0) link | top
def read(self, size=-1) link | top
def readline(self, size=-1) link | top
class EmptyForm link | top
def getfirst(self, key: str, default: Any = None, func: Callable = request.<lambda>, fce: Optional[Callable] = None) link | top
def getlist(self, key: str, default: Any = None, func: Callable = request.<lambda>, fce: Optional[Callable] = None) link | top
def getvalue(self, key: str, default: Any = None, func: Callable = request.<lambda>) link | top
class JsonDict link | top
A compatibility class for reading values from a JSON POST, PUT, or PATCH request.
It has getfirst and getlist methods, which can call a function on the values.
Deprecated: This class will be removed in a future major version.
>>> json = JsonDict({"key": "42"}) >>> json.getvalue("key", func=int) 42
>>> json = JsonDict({"key": ["42", "15"]}) >>> json.getlist("key", func=int) [42, 15]
>>> json.getfirst("key", func=int)
42
def getfirst(self, key: str, default: Any = None, func: Callable = poorwsgi.fieldstorage.<lambda>, fce: Optional[Callable] = None) link | top
Gets the first item from a list for a key, or a default value.
- default
The default value if the key does not exist.
- func
The function that processes the value.
- fce
Deprecated converter name. Use the func converter, just like getvalue.
def getlist(self, key: str, default: Optional[list] = None, func: Callable = poorwsgi.fieldstorage.<lambda>, fce: Optional[Callable] = None) link | top
Returns a list of variable values for a key, or an empty list.
- default
The default list if the key does not exist.
- func
The function that processes each value.
- fce
Deprecated converter name. Use the func converter, just like getvalue.
def getvalue(self, key: str, default: Any = None, func: Callable = poorwsgi.fieldstorage.<lambda>) link | top
Returns the value for the given key, applying func to it.
- key
The key name.
- default
The default value if the key is not found.
- func
The function or class that processes the value. The default type of value is bytes for files and string for others.
class JsonList link | top
A compatibility class for reading values from a JSON POST, PUT, or PATCH request.
It has getfirst and getlist methods, which can call a function on the values.
Deprecated: This class will be removed in a future major version.
def getfirst(self, key=None, default: Any = None, func: Callable = request.<lambda>, fce: Optional[Callable] = None) link | top
Returns the first variable's value, or the default if it does not exist.
- key
This compatibility parameter is ignored.
- default
The default value if the key does not exist.
- func
A function that processes the value.
- fce
Deprecated converter name. Use the func converter just like getvalue.
def getlist(self, key: str, default: Optional[list] = None, func: Callable = request.<lambda>, fce: Optional[Callable] = None) link | top
Returns a list of values.
- key
This compatibility parameter is ignored.
- default
The default value when self is empty.
- func
A function that processes the value.
- fce
Deprecated converter name. Use the func converter just like getvalue.
def getvalue(self, key=None, default: Any = None, func: Callable = request.<lambda>) link | top
Returns the first item, or the default value if it does not exist.
- key
This compatibility parameter is ignored.
- default
The default value if the key does not exist.
- func
A function or class that processes the value. The default type of the value is bytes for files and string for others.
class Request link | top
HTTP request object with all server elements.
It aims to be as compatible as possible with mod_python.apache.request.
Special variables for user use are prefixed with app_.
accept (READ) top
accept_charset (READ) top
accept_encoding (READ) top
accept_html (READ) top
text/html MIME type is in the accepted
negotiation values.accept_json (READ) top
application/json MIME type is in the
accepted negotiation values.accept_language (READ) top
accept_xhtml (READ) top
text/xhtml MIME type is in the accepted
negotiation values.api (READ | WRITE) top
app (READ) top
args (READ | WRITE) top
An extended dictionary (Args instance) of request arguments.
Arguments are parsed from the QUERY_STRING, which is typical for, but not limited to, the GET method. Arguments are parsed when Application.auto_args is set (which is the default).
This property can be set only once.
authorization (READ) top
charset (READ) top
Content-Type charset header string; defaults to
'utf-8' if not set.content_length (READ) top
Content-Length header value; -1 if not set.cookies (READ) top
A SimpleCookie iterable object of all cookies from the Cookie header.
This property is set if Application.auto_cookies is set to True (which is the default). Otherwise, cookies is None.
data (READ) top
Returns input data from the wsgi.input file.
This works only when auto_data is configured and the request's Content-Length is lower than the input_cache configuration value. Other requests, like large file data uploads, will increase memory and system request time.
db (READ | WRITE) top
debug (READ) top
poor_Debug variable.document_index (READ) top
Value of the poor_DocumentIndex variable.
This variable is used to generate an index.html page when poor_DocumentRoot is set.
document_root (READ) top
end_time (READ) top
environ (READ) top
Copy of the table object containing the request environment.
Information is retrieved from the WSGI server.
error_handler (READ | WRITE) top
This property is set only when an error handler is called.
It is set by the Application object when the error handler is known before being called.
form (READ | WRITE) top
A dictionary-like class (FieldStorage instance) for body arguments.
Arguments must be sent in the request body with a MIME type from Application.form_mime_types. The method must be POST, PUT, or PATCH. The request body is parsed when Application.auto_form is set (which is the default) and the method is POST, PUT, or PATCH.
This property can be set only once.
forwarded_for (READ) top
X-Forward-For HTTP header, if it exists.forwarded_host (READ) top
X-Forwarded-Host HTTP header without the port, if it
exists.forwarded_port (READ) top
X-Forward-Host or X-Forward-Proto header.forwarded_proto (READ) top
X-Forwarded-Proto HTTP header, if it exists.full_path (READ) top
headers (READ) top
host_port (READ) top
hostname (READ) top
input (READ) top
is_body_request (READ) top
is_chunked (READ) top
is_chunked_request (READ) top
is_xhr (READ) top
X-Requested-With header is set to
XMLHttpRequest.json (READ) top
A JSON dictionary if the request's MIME type is JSON.
JSON types are defined in Application.json_mime_types (typically
application/json). The request method must be POST, PUT, or
PATCH, and Application.auto_json must be set to True (default).
Otherwise, json is an EmptyForm.
When request data is present, it will be parsed with the parse_json_request function.
method (READ) top
GET, HEAD, POST, etc.method_number (READ) top
mime_type (READ) top
Content-Type header, or an empty string if not
set.path (READ) top
path_args (READ | WRITE) top
poor_environ (READ) top
Environment with poor_ variables.
It is the environment from the request or os.environ.
port (READ) top
server_port property.protocol (READ) top
server_protocol property.query (READ) top
referer (READ) top
remote_addr (READ) top
remote_host (READ) top
scheme (READ) top
secret_key (READ) top
Value of the poor_SecretKey variable.
The secret key is used by the PoorSession class. It is generated from some server variables, and the best way to set it is programmatically via Application.secret_key from random data.
server_admin (READ) top
webmaster@hostname.server_hostname (READ) top
server_port (READ) top
server_protocol (READ) top
Server protocol, as given by the client.
In HTTP/1.1. CGI SERVER_PROTOCOL value.
server_scheme (READ) top
server_software (READ) top
start_time (READ) top
uri (READ) top
uri_handler (READ | WRITE) top
This property is set at the same time as uri_rule.
It is set by the Application object when the endpoint handler is known before calling all pre-handlers. A typical use case is to set a special attribute on the handler and read it in a pre-handler.
The property is set when any route is found for the request URI. Sending a file internally when document_root is set, or by Error handlers, leaves uri_handler as None.
uri_rule (READ | WRITE) top
Rule from one of the application handler tables.
This property can be set only once by the Application object. There
are some internal uri_rules that are typically set if an internal
handler was called. These include: /* for the default,
directory, and file handlers, and /debug-info for the debug
handler. In other cases, it will be a URL or a regex.
user (READ | WRITE) top
user_agent (READ) top
def __del__(self) link | top
def __init__(self, environ, app) link | top
The object is created automatically in the wsgi module.
Its input parameters are the same as those that the Application object gets from the WSGI server, plus a file callback for automatic request body parsing.
def construct_url(self, uri: str) link | top
This function returns a fully qualified URI string.
The URL is created from the path specified by the URI, using information stored in the request to determine the scheme, server hostname, and port. The port number is not included in the string if it is the same as the default port (80 for http, 443 for https).
def get_options(self) link | top
Returns a dictionary with application variables from the environment.
Application variables start with the app_ prefix, but in the
returned dictionary, they are set without this prefix.
poor_Debug = on # Poor WSGI variable app_db_server = localhost # application variable db_server app_templates = app/templ # application variable templates
def read(self, length=-1) link | top
Reads data from the client (typical for XHR2 data POST).
If length is not set, or if it is less than zero, Content-Length will be used.
def read_chunk(self) link | top
Reads a chunk when Transfer-Encoding is 'chunked'.
The method first reads a line with the chunk size, then reads the chunk and returns it. It will raise a ValueError if the chunk size is in a bad format.
Ensure that the WSGI server allows readline from wsgi.input. For example, uWSGI has an extra API for this: https://uwsgi-docs.readthedocs.io/en/latest/Chunked.html
class SimpleRequest link | top
app (READ) top
debug (READ) top
poor_Debug variable.document_index (READ) top
Value of the poor_DocumentIndex variable.
This variable is used to generate an index.html page when poor_DocumentRoot is set.
document_root (READ) top
end_time (READ) top
environ (READ) top
Copy of the table object containing the request environment.
Information is retrieved from the WSGI server.
error_handler (READ | WRITE) top
This property is set only when an error handler is called.
It is set by the Application object when the error handler is known before being called.
forwarded_for (READ) top
X-Forward-For HTTP header, if it exists.forwarded_host (READ) top
X-Forwarded-Host HTTP header without the port, if it
exists.forwarded_port (READ) top
X-Forward-Host or X-Forward-Proto header.forwarded_proto (READ) top
X-Forwarded-Proto HTTP header, if it exists.full_path (READ) top
host_port (READ) top
hostname (READ) top
method (READ) top
GET, HEAD, POST, etc.method_number (READ) top
path (READ) top
poor_environ (READ) top
Environment with poor_ variables.
It is the environment from the request or os.environ.
port (READ) top
server_port property.protocol (READ) top
server_protocol property.query (READ) top
referer (READ) top
remote_addr (READ) top
remote_host (READ) top
scheme (READ) top
secret_key (READ) top
Value of the poor_SecretKey variable.
The secret key is used by the PoorSession class. It is generated from some server variables, and the best way to set it is programmatically via Application.secret_key from random data.
server_admin (READ) top
webmaster@hostname.server_hostname (READ) top
server_port (READ) top
server_protocol (READ) top
Server protocol, as given by the client.
In HTTP/1.1. CGI SERVER_PROTOCOL value.
server_scheme (READ) top
server_software (READ) top
start_time (READ) top
uri (READ) top
uri_handler (READ | WRITE) top
This property is set at the same time as uri_rule.
It is set by the Application object when the endpoint handler is known before calling all pre-handlers. A typical use case is to set a special attribute on the handler and read it in a pre-handler.
The property is set when any route is found for the request URI. Sending a file internally when document_root is set, or by Error handlers, leaves uri_handler as None.
uri_rule (READ | WRITE) top
Rule from one of the application handler tables.
This property can be set only once by the Application object. There
are some internal uri_rules that are typically set if an internal
handler was called. These include: /* for the default,
directory, and file handlers, and /debug-info for the debug
handler. In other cases, it will be a URL or a regex.
user_agent (READ) top
def __init__(self, environ, app) link | top
def construct_url(self, uri: str) link | top
This function returns a fully qualified URI string.
The URL is created from the path specified by the URI, using information stored in the request to determine the scheme, server hostname, and port. The port number is not included in the string if it is the same as the default port (80 for http, 443 for https).
def get_options(self) link | top
Returns a dictionary with application variables from the environment.
Application variables start with the app_ prefix, but in the
returned dictionary, they are set without this prefix.
poor_Debug = on # Poor WSGI variable app_db_server = localhost # application variable db_server app_templates = app/templ # application variable templates
def FieldStorage(req=<class 'request.Request'>, headers=None, keep_blank_values=0, strict_parsing=0, encoding='utf-8', errors='replace', max_num_fields=None, separator='&', file_callback=None) link | top
Deprecated: A backwards compatibility function.
This function will be removed in a future major version.
Use FieldStorageParser directly instead of this.
def parse_json_request(raw: bytes, charset: str = 'utf-8') link | top
Tries to parse request data.
The returned type can be:
RE_AUTHORIZATION = ((\w+\*?)[=] ?("[^"]+"|[\w\-\'%]+), 32) top
RE_HTTPURLPATTERN = (^(http|https):\/\/, 32) top
log = <Logger poorwsgi (WARNING)> top
module response link | top
Poor WSGI Response classes.
| Exceptions: | |
|---|---|
| Classes: | Response, JSONResponse, FileResponse, GeneratorResponse, StrGeneratorResponse, EmptyResponse, RedirectResponse |
| Functions: |
class BaseResponse link | top
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, content_type: str = '', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 200) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
class Declined link | top
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, status_code: int = 200) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, *args, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
class EmptyResponse link | top
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, status_code: int = 204) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
class FileObjResponse link | top
FileResponse returns a file object directly to the WSGI server.
This means that the sendfile UNIX system call can be used.
Be careful not to use a single FileResponse instance multiple times! The WSGI server closes the file that is returned by this response. So, just like Response, an instance of FileResponse can be used only once!
The file content is returned from the current position. So, Content-Length is set from the file system or from the buffer, minus the position.
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
Returns the data content.
This property works only if file_obj is seekable.
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, file_obj: Union[io.IOBase, BinaryIO], content_type: Optional[str] = None, headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 200) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
class FileResponse link | top
FileResponse returns an opened file directly to the WSGI server.
This means that the sendfile UNIX system call can be used.
Be careful not to use a single FileResponse instance multiple times! The WSGI server closes the file that is returned by this response. So, just like Response, an instance of FileResponse can be used only once!
This object adds a Last-Modified header if it is not already set.
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
Returns the data content.
This property works only if file_obj is seekable.
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, path: str, content_type: Optional[str] = None, headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 200) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
class GeneratorResponse link | top
For a response that uses a generator as the returned value.
Even though you can figure out how to iterate your generator multiple times, just like a Response, an instance of a GeneratorResponse can be used only once!
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, generator: Iterable[bytes], content_type: str = 'text/html; charset=utf-8', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 200, content_length: int = 0) link | top
def __range_generator__(self) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
class HTTPException link | top
An HTTP Exception to quickly stop execution.
Simple error exception:
>>> HTTPException(404) # doctest: +ELLIPSIS HTTPException(404, {}...)
Exception with response:
>>> HTTPException(Response(data=b'Created', status_code=201)) ... # doctest: +ELLIPSIS HTTPException(<poorwsgi.response.Response object at 0x...>...)
Attributes:
>>> HTTPException(401, stale=True) # doctest: +ELLIPSIS HTTPException(401, {'stale': True}...)
response (READ) top
status_code (READ) top
def __init__(self, arg: Union[int, response.BaseResponse], **kwargs) link | top
The status_code is one of the HTTP_* status codes from the state module.
If a response is set, it will be used; otherwise, the handler from the Application will be called.
def make_response(self) link | top
class IBytesIO link | top
def __iter__(self) link | top
def read_kilo(self) link | top
class JSONGeneratorResponse link | top
A JSON Response for data from a generator.
The data will be processed in a generator fashion, so it needs to be buffered. This class requires the simplejson module.
The **kwargs from the constructor are serialized to a JSON structure.
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, charset: str = 'utf-8', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 200, **kwargs) link | top
def __range_generator__(self) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
class JSONResponse link | top
A simple application/json response.
- Arguments:
- data_: Any
An alternative way to add data to the JSON response.
- charset: str
charsetvalue forContent-Typeheader.utf-8by default.- headers: Headers
- status_code: int
- encoder_kwargs: dict
Keyword arguments for
json.dumpsfunction.- kwargs: keyword arguments
Other keys and values are serialized to JSON structure.
>>> res = JSONResponse(msg="Čeština", ... encoder_kwargs={"ensure_ascii": False}) >>> res.data b'{"msg": "ÄeÅ¡tina"}'
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, data_=None, charset: str = 'utf-8', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 200, encoder_kwargs=None, **kwargs) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
def write(self, data: Union[str, bytes]) link | top
class NoContentResponse link | top
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 204) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
class NotModifiedResponse link | top
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, etag: Optional[str] = None, content_location: Optional[str] = None, date: Union[str, int, datetime.datetime, NoneType] = None, vary: Optional[str] = None) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
class PartialResponse link | top
A Partial Response object that only computes the Content-Range header.
This is for special cases where you know how to return the correct range, for example, when you want to return a different unit.
>>> res = PartialResponse() >>> res.make_range([(1, 3)], "blocks") >>> res.headers Headers("...('Content-Range', 'blocks 1-3/*'))") >>> res.make_range([(1, 3)], "blocks", 10) >>> res.headers Headers("...('Content-Range', 'blocks 1-3/10'))")
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, data: Union[str, bytes] = b'', content_type: str = 'text/html; charset=utf-8', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
This method does nothing.
To create a Content-Range header, use the special make_range method.
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
def write(self, data: Union[str, bytes]) link | top
class RedirectResponse link | top
Redirects the browser to another location.
A short text is sent to the browser informing it that the document
has moved (for those rare browsers that do not support redirection);
this text can be overridden by supplying a text string (message).
When permanent is True or status_code is set to a redirect
status, the corresponding status code will be sent to the client.
The use of permanent and boolean values for status_code is
deprecated; use the actual status_code instead.
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, location: str, status_code: Union[int, bool] = 302, message: Union[str, bytes] = b'', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, permanent: bool = False) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
def write(self, data: Union[str, bytes]) link | top
class Response link | top
An HTTP Response object.
This is the base Response object that is processed by the PoorWSGI application.
Since Response uses BytesIO as an internal cache, which is closed by the WSGI server, the response can be used only once!.
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, data: Union[str, bytes] = b'', content_type: str = 'text/html; charset=utf-8', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 200) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
def write(self, data: Union[str, bytes]) link | top
class ResponseError link | top
class StrGeneratorResponse link | top
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, generator: Iterable[str], content_type: str = 'text/html; charset=utf-8', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 200) link | top
def __range_generator__(self) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
class TextResponse link | top
content_length (READ) top
Returns the content_length of the response.
This is the size of the internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
The HTTP response reason phrase is set automatically when setting the status_code.
Modifying the response message is not a good idea, but you can create your own class based on Response, where you can override the status_code setter.
status_code (READ | WRITE) top
The HTTP status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is a very good idea in
http_state handlers), it is a good solution to use one of the
HTTP_ constants from the state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method is called from the Application object at the end of the request to return the correct value to the WSGI server.
def __init__(self, text: str, charset: str = 'utf-8', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 200) link | top
def __start_response__(self, start_response: Callable) link | top
def add_header(self, name: str, value: str, **kwargs) link | top
def make_partial(self, ranges: Optional[List[Tuple[Optional[int], Optional[int]]]] = None, units='bytes') link | top
Makes the response partial.
It adds the Accept-Ranges header with the units value and sets the range to a new value. If a range is defined and the response supports seeking in the buffer or skipping the generator, it returns the correct range response.
Inconsistent ranges are skipped!
The response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behavior, like If-Range conditions, depends on the response or programmer's implementation.
See https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> res = BaseResponse() >>> res.make_partial([(0, 100)]) >>> res.ranges ((0, 100),) >>> res.make_partial([(50, 100), (60, 20), (150, None), (None, 200)]) >>> res.ranges ((50, 100), (150, None), (None, 200))
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just sets the Content-Range header values and the units attribute.
The Content-Range is set in the __start_response__ method for an HTTP_OK status. This method is needed when you want to create a partial response manually. This method requires a response with an HTTP_PARTIAL_CONTENT status.
def write(self, data: Union[str, bytes]) link | top
def abort(arg: Union[int, response.BaseResponse]) link | top
Raises an HTTPException with the given argument.
Raises a simple error exception:
>>> abort(404) Traceback (most recent call last): ... poorwsgi.response.HTTPException: (404, {})
Raises an exception with a response:
>>> abort(Response(data=b'Created', status_code=201)) # doctest: +ELLIPSIS Traceback (most recent call last): ... poorwsgi.response.HTTPException: (<poorwsgi.response.Response object at 0x...>, {})
def make_response(data: Union[str, bytes, dict, Iterable[bytes], NoneType], content_type: str = 'text/html; charset=utf-8', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, status_code: int = 200) link | top
Creates a response from values.
If data is:
| str, bytes: | A Response is returned. |
|---|---|
| list, dict: | A JSONResponse is returned. A list cannot be a list of bytes; otherwise, a GeneratorResponse is returned. |
| Iterable: | A GeneratorResponse is returned. |
Data can be a string, bytes, or a bytes-returning iterable object like a file.
Response from string:
>>> res = make_response("Hello world!") >>> res <poorwsgi.response.Response object at ...> >>> res.data b'Hello world!' >>> res.content_type 'text/html; charset=utf-8' >>> res.status_code 200
Response from bytes:
>>> res = make_response(b"2", "application/octet-stream", {}, 412) >>> res.data b'2' >>> res.content_type 'application/octet-stream' >>> res.status_code 412
Own response header field:
>>> res = make_response("OK", headers={"Ok-Header": "OK"}) >>> res.headers["OK-Header"] 'OK'
JSONResponse from dictionary, content_type argument is ignored:
>>> res = make_response({"key": "value"}, "text/plain", status_code=201) >>> res <poorwsgi.response.JSONResponse object at ...> >>> res.data b'{"key": "value"}' >>> res.content_type 'application/json; charset=utf-8' >>> res.status_code 201
JSONResponse from list, content_type argument is ignored:
>>> res = make_response([["key", "value"]]) >>> res <poorwsgi.response.JSONResponse object at ...> >>> res.data b'[["key", "value"]]'
GeneratorResponse from iterable of bytes:
>>> res = make_response([b"key", b"value"]) >>> res <poorwsgi.response.GeneratorResponse object at ...> >>> res.__end_of_response__() <generator object GeneratorResponse.__range_generator__ at ...> >>> list(res.__end_of_response__()) [b'key', b'value']
NoContentResponse from None, content_type argument is ignored. If status_code is left at 200 OK, then status will be 204 No Content:
>>> res = make_response(None) >>> res <poorwsgi.response.NoContentResponse object at ...> >>> res.status_code 204
>>> res = make_response(None, status_code=201) >>> res.status_code 201
def redirect(location: str, status_code: Union[int, bool] = 302, message: Union[str, bytes] = b'', headers: Union[poorwsgi.headers.Headers, List, Tuple, set, dict, NoneType] = None, permanent: bool = False) link | top
Raises an HTTPException with a RedirectResponse.
See RedirectResponse for more information about the response, as it has the same interface.
NOT_MODIFIED_DENY = {'Content-MD5', 'Content-Language', 'Content-Type', 'Content-Encoding', 'Content-Range', 'Content-Length'} top
NOT_MODIFIED_ONE_OF_REQUIRED = {'Date', 'Content-Location', 'ETag', 'Vary'} top
log = <Logger poorwsgi (WARNING)> top
module headers link | top
Classes that are used for managing headers.
| Classes: | |
|---|---|
| Functions: |
class ContentRange link | top
The Content-Range header.
>>> str(ContentRange(1, 2)) 'bytes 1-2/*' >>> str(ContentRange(1, 2, 10)) 'bytes 1-2/10' >>> str(ContentRange(2, 5, units="lines")) 'lines 2-5/*'
def __init__(self, start=0, end=0, full='*', units='bytes') link | top
def __str__(self) link | top
class Headers link | top
A class inherited from collections.Mapping.
As PEP 333, respectively RFC 2616, states, all header names must contain only US-ASCII characters, excluding control characters or separators. Header values must be stored in strings encoded in ISO-8859-1. The Headers.add and Headers.add_header methods of this class automatically convert values from UTF-8 to ISO-8859-1 encoding if possible. Therefore, all modification methods must use UTF-8 strings.
Some headers can be set twice. Currently, a response can contain
multiple Set-Cookie headers, but you can use the add_header
method to add multiple headers with the same name. Alternatively,
you can create headers from tuples, which is used in Request.
When multiple headers with the same name are set in an HTTP request, the server joins their values into one.
An empty header is not allowed.
>>> headers = Headers({'X-Powered-By': 'Test'}) >>> headers['X-Powered-By'] 'Test' >>> headers['x-powered-by'] 'Test' >>> headers.get('X-Powered-By') 'Test' >>> headers.get('x-powered-by') 'Test' >>> 'X-Powered-By' in headers True >>> 'x-powered-by' in headers True
def __contains__(self, key) link | top
def __delitem__(self, name: str) link | top
def __eq__(self, other) link | top
def __getitem__(self, name: str) link | top
def __init__(self, headers: Union[List, Tuple, set, dict, NoneType] = None, strict: bool = True) link | top
Headers constructor.
A Headers object can be created from a list, set, or tuple of (name, value) pairs, or from a dictionary. All names or values must be ISO-8859-1 encodable. If not, an AssertionError will be raised.
If strict is False, header names and values are not encoded to ISO-8859-1. This is for input headers only.
def __iter__(self) link | top
def __len__(self) link | top
def __repr__(self) link | top
def __setitem__(self, name: str, value: str) link | top
def add(self, name: str, value: str) link | top
Sets a header name to a value.
Duplicate names are not allowed, except for Set-Cookie.
def add_header(self, name: str, value: Union[str, List[Tuple], NoneType] = None, **kwargs) link | top
Extended header setting.
- name
The header field to add.
- value
If the value is a list of tuples, render_negotiation will be used.
- kwargs
Arguments can be used to set additional value parameters for the header field, with underscores converted to dashes. Normally, the parameter will be added as name="value".
h.add_header('X-Header', 'value')
h.add_header('Content-Disposition', 'attachment',
filename='image.png')
h.add_header('Accept-Encoding', [('gzip',1.0), ('*',0)])
All names must be US-ASCII strings, excluding control characters or separators.
def get(self, key, default=None) link | top
def get_all(self, name: str) link | top
Returns a tuple of all values for the header identified by its lowercase name.
>>> headers = Headers([('Set-Cookie', 'one'), ('Set-Cookie', 'two')]) >>> headers.get_all('Set-Cookie') ('one', 'two') >>> headers.get_all('X-Test') ()
def iso88591(value: str) -> str link | top
Performs automatic conversion to ISO-8859-1 strings.
Converts from UTF-8 to ISO-8859-1 strings. This means all input values for the Headers class must be UTF-8 strings.
def items(self) link | top
def keys(self) link | top
def names(self) link | top
def setdefault(self, name: str, value: str) link | top
def utf8(value: str) -> str link | top
def values(self) link | top
def _parseparam(s) link | top
def datetime_to_http(value: datetime.datetime) link | top
Returns an HTTP Date from a timestamp.
>>> datetime_to_http(datetime.fromtimestamp(0, timezone.utc)) 'Thu, 01 Jan 1970 00:00:00 GMT'
def http_to_datetime(value: str) link | top
Returns a datetime from an HTTP Date string.
>>> http_to_datetime("Thu, 01 Jan 1970 00:00:00 GMT") datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)
def http_to_time(value: str) link | top
Returns a timestamp from an HTTP Date.
>>> http_to_time("Thu, 01 Jan 1970 00:00:00 GMT") 0
def parse_header(line) link | top
Parses a Content-Type-like header.
Returns the main content type and a dictionary of options.
>>> parse_header("text/html; charset=latin-1") ('text/html', {'charset': 'latin-1'}) >>> parse_header("text/plain") ('text/plain', {})
def parse_negotiation(value: str) link | top
Parses content negotiation headers into a list of (value, quality) tuples.
>>> parse_negotiation('gzip;q=1.0, identity;q=0.5, *;q=0') [('gzip', 1.0), ('identity', 0.5), ('*', 0.0)] >>> parse_negotiation('text/html;level=1, text/html;level=2;q=0.5') [('text/html;level=1', 1.0), ('text/html;level=2', 0.5)]
def parse_range(value: str) -> Dict[str, List[Tuple[Optional[int], Optional[int]]]] link | top
Parses an HTTP Range header.
Parses the Range header value and returns a dictionary with the units key and a list of range tuples.
see: https://www.rfc-editor.org/rfc/rfc9110.html#name-range-requests
>>> parse_range("bytes=0-499") {'bytes': [(0, 499)]} >>> parse_range("units=500-999") {'units': [(500, 999)]} >>> parse_range("bytes=-500") {'bytes': [(None, 500)]} >>> parse_range("bytes=9500-") {'bytes': [(9500, None)]} >>> parse_range("chunks=500-600,601-999") {'chunks': [(500, 600), (601, 999)]} >>> parse_range("bytes=0-1,1-2,1-,-5") {'bytes': [(0, 1), (1, 2), (1, None), (None, 5)]} >>> parse_range("bytes=0-499") {'bytes': [(0, 499)]} >>> parse_range("invalid") {} >>> parse_range("invalid=a-b") {'invalid': []}
def render_negotiation(negotation: List[Tuple]) link | top
Renders a negotiation header value from tuples.
>>> render_negotiation([('gzip',1.0), ('*',0)]) 'gzip;q=1.0, *;q=0' >>> render_negotiation((('gzip',1.0), ('compress',))) 'gzip;q=1.0, compress' >>> render_negotiation((('text/html;level=1',), ... ('text/html;level=2', 0.5))) 'text/html;level=1, text/html;level=2;q=0.5'
def time_to_http(value: Union[int, float, NoneType] = None) link | top
Returns an HTTP Date from a timestamp.
>>> time_to_http(0) 'Thu, 01 Jan 1970 00:00:00 GMT' >>> time_to_http() # doctest: +ELLIPSIS '... GMT'
HEADER_DATETIME_FORMAT = '%a, %d %b %Y %X GMT' top
HeadersList = typing.Union[typing.List, typing.Tuple, set, dict] top
RE_BYTES_RANGE = ((\d*)-(\d*),?, 32) top
RangeList = typing.List[typing.Tuple[typing.Optional[int], typing.Optional[int]]] top
log = <Logger poorwsgi (WARNING)> top
module fieldstorage link | top
PoorWSGI reimplementation of the legacy cgi.FieldStorage.
| Classes: | |
|---|---|
| Functions: |
class FieldStorage link | top
A class inspired by cgi.FieldStorage.
Instead of FieldStorage from the cgi module, this is only storage for fields, with some additional functionality in getfirst, getlist, getvalue, or simple get methods. They return values instead of __getitem__ ([]), which returns another FieldStorage.
Available attributes:
| name: | The variable name, the same name as from the input attribute. |
|---|---|
| value: | A property that returns the content of the field. |
| type: | The MIME type of the variable. All variables have an internal MIME type; if it is not a file, the MIME type is text/plain. |
| type_options: | Other Content-Type parameters, such as encoding. |
| disposition: | The Content-Disposition header, if set. |
| disposition_options: | Other Content-Disposition parameters, if set. |
| filename: | If the variable is a file, filename is its name from the form. |
| length: | The field length if it was set in the header; -1 by default. |
| file: | A file type instance from which you can read the variable. This instance can be a TemporaryFile (default for files), StringIO (for normal variables), or an instance of your own file type class, created from file_callback. |
| lists: | If the variable is a list of variables, this contains instances of other fields. |
FieldStorage is created by FieldStorageParser.
FieldStorage has context methods, so you can read files like this: >>> field = FieldStorage("key") >>> field.file = StringIO("value") >>> with field: ... print(field.value) value
value (READ) top
Returns the content of the field.
If the field is a file, its content is returned.
If the field is a string value, the string is returned.
If the field is a list of other fields (root FieldStorage), that list is returned.
>>> field = FieldStorage() >>> print(field.value) None >>> field.list = [FieldStorage("key", "value")] >>> field.value [FieldStorage(key, value)] >>> field = FieldStorage("key", "value") >>> field.value 'value' >>> field = FieldStorage("key") >>> field.file = StringIO("string") >>> field.value 'string' >>> field = FieldStorage("key") >>> field.file = BytesIO(b"bytes") >>> field.value b'bytes'
def __bool__(self) link | top
>>> field = FieldStorage("key", "value") >>> bool(field) True >>> field = FieldStorage() >>> field.list = [FieldStorage("key")] >>> bool(field) True >>> field = FieldStorage("key") >>> bool(field) False
def __contains__(self, key: str) link | top
>>> field = FieldStorage() >>> field.list = [FieldStorage("key", "value")] >>> "key" in field True >>> "no-key" in field False
def __del__(self) link | top
def __enter__(self) link | top
def __exit__(self, *args) link | top
def __getitem__(self, key: str) link | top
def __init__(self, name: Optional[str] = None, value: Optional[str] = None) link | top
def __iter__(self) link | top
>>> field = FieldStorage() >>> field.list = [FieldStorage("key", "value")] >>> for key in field: ... print(key, ":", field.get(key)) key : value
def __len__(self) link | top
>>> field = FieldStorage() >>> len(field) # no fields in field storage 0 >>> field.list = [FieldStorage("k1", "value"), FieldStorage("k2", "K")] >>> len(field) # two different keys 2 >>> field = FieldStorage() >>> field.list = [FieldStorage("k", "value"), FieldStorage("k", "K")] >>> len(field) # one key with two values 1
def __repr__(self) link | top
def get(self, key: str, default: Any = None) link | top
Compatibility method with dict.
Returns the field value, or a list of values if multiple exist for the key.
>>> field = FieldStorage() >>> field.list = [FieldStorage("key", "value")] >>> field.get("key") 'value' >>> field.get("zero", "0") '0'
def getfirst(self, key: str, default: Any = None, func: Callable = fieldstorage.<lambda>, fce: Optional[Callable] = None) link | top
Gets the first item from a list for a key, or a default value.
Uses the func converter just like getvalue.
- fce
Deprecated converter name.
>>> field = FieldStorage() >>> field.list = [FieldStorage("key", "1"), FieldStorage("key", "2")] >>> field.getfirst("key", func=int) 1
def getlist(self, key: str, default: Optional[list] = None, func: Callable = fieldstorage.<lambda>, fce: Optional[Callable] = None) link | top
Returns a list of variable values for a key, or an empty list.
Uses the func converter just like getvalue.
- fce
Deprecated converter name.
>>> field = FieldStorage() >>> field.list = [FieldStorage("key", "1"), FieldStorage("key", "2")] >>> field.getlist("key", func=int) [1, 2] >>> field.getlist("no-key") [] >>> field.getlist("no-key", default=["empty"]) ['empty']
def getvalue(self, key: str, default: Any = None, func: Callable = fieldstorage.<lambda>) link | top
Returns the value for the given key, applying func to each value.
- key
The key name.
- default
The default value if the key is not found.
- func
The function or class that processes the value. The default type of value is bytes for files and string for others.
>>> field = FieldStorage() >>> field.list = [FieldStorage("key", "42")] >>> field.getvalue("key", func=int) 42
def keys(self) link | top
A dictionary-like keys() method.
>>> field = FieldStorage() >>> field.list = [FieldStorage("key", "value")] >>> field.keys() dict_keys(['key'])
class FieldStorageInterface link | top
FieldStorage Interface
Implements the methods getvalue, getfirst, and getlist.
def __contains__(self, key: str) -> bool link | top
def __getitem__(self, key: str) link | top
def getfirst(self, key: str, default: Any = None, func: Callable = fieldstorage.<lambda>, fce: Optional[Callable] = None) link | top
Gets the first item from a list for a key, or a default value.
- default
The default value if the key does not exist.
- func
The function that processes the value.
- fce
Deprecated converter name. Use the func converter, just like getvalue.
def getlist(self, key: str, default: Optional[list] = None, func: Callable = fieldstorage.<lambda>, fce: Optional[Callable] = None) link | top
Returns a list of variable values for a key, or an empty list.
- default
The default list if the key does not exist.
- func
The function that processes each value.
- fce
Deprecated converter name. Use the func converter, just like getvalue.
def getvalue(self, key: str, default: Any = None, func: Callable = fieldstorage.<lambda>) link | top
Returns the value for the given key, applying func to it.
- key
The key name.
- default
The default value if the key is not found.
- func
The function or class that processes the value. The default type of value is bytes for files and string for others.
class FieldStorageParser link | top
A class inspired by cgi.FieldStorage.
This is only the parsing part of the old FieldStorage. It contains methods for parsing POST forms encoded in multipart/form-data or application/x-www-form-urlencoded, which is the default.
It generates FieldStorage or Field depending on the encoding, but it does so only from the request body. FieldStorage has an internal StringIO for all values that are not stored in a file. Some small binary files can be stored in BytesIO. The limit for storing fields in temporary files is 8192 bytes.
parser = FieldStorageParser(request.input, request.headers) form = parser.parse() assert isinstance(form, FieldStorage)
def __init__(self, input_=None, headers=None, outerboundary=b'', keep_blank_values=0, strict_parsing=0, limit=None, encoding='utf-8', errors='replace', max_num_fields=None, separator='&', file_callback=None) link | top
Constructor. Reads multipart/* until the last part.
Arguments, all optional:
- input_
Request.input file object.
- headers
A header dictionary-like object.
- outerboundary
The terminating multipart boundary (for internal use only).
- keep_blank_values
A flag indicating whether blank values in percent-encoded forms should be treated as blank strings. A true value indicates that blanks should be retained as blank strings. The default false value indicates that blank values are to be ignored and treated as if they were not included.
- strict_parsing
A flag indicating what to do with parsing errors. If False (the default), errors are silently ignored. If True, errors raise a ValueError exception.
- limit
Used internally to read parts of multipart/form-data forms, to exit from the reading loop when reached. It is the difference between the form's content-length and the number of bytes already read.
- encoding, errors
The encoding and error handler used to decode the binary stream to strings. Must be the same as the charset defined for the page sending the form (content-type : meta http-equiv or header).
- max_num_fields
If set, then parse throws a ValueError if there are more than n fields read by parse_qsl().
- file_callback
A function that returns a file class for custom handling of creating files for write operations. This allows you to write a file from the request directly to its destination without temporary files.
def _parse_content_type(self) link | top
Processes the Content-Type header.
Honors any existing Content-Type header. If no Content-Type header is present, sensible defaults are used. Assumes outerboundary is "" at the outer level, but something non-false inside a multi-part. The default for an inner part is text/plain, but for an outer part it should be urlencoded. This should catch bogus clients that erroneously forget to include a Content-Type header.
See below for what is done if a Content-Type header exists, but it is not understood.
def _skip_to_boundary(self) link | top
def _write(self, line, file) link | top
def make_file(self) link | top
Returns a readable and writable temporary file.
If a filename and file_callback are set, file_callback is called instead of creating a temporary file.
def parse(self) -> fieldstorage.FieldStorage link | top
def read_binary(self) link | top
def read_lines(self) link | top
def read_lines_to_eof(self, file) link | top
def read_lines_to_outerboundary(self, file) link | top
def read_multi(self) link | top
def read_single(self) link | top
def read_urlencoded(self) link | top
def skip_lines(self) link | top
def valid_boundary(data) link | top
Checks for a valid boundary label.
>>> valid_boundary("----WebKitFormBoundaryMPRpF8CUUmlmqKqy") True >>> valid_boundary(b"----WebKitFormBoundaryMPRpF8CUUmlmqKqy") True
_RE_BIN_BOUNDARY = (b'^[ -~]{0,200}[!-~]$', 0) top
_RE_STR_BOUNDARY = (^[ -~]{0,200}[!-~]$, 32) top
module session link | top
PoorSession self-contained cookie class.
| Classes: | |
|---|---|
| Functions: |
class NoCompress link | top
Fake compress class/module with two static methods for PoorSession.
If the compress parameter is None, this class is used.
def compress(data, compresslevel=0) link | top
def decompress(data) link | top
class PoorSession link | top
A self-contained cookie with session data.
You can store or read data from the object via the PoorSession.data variable, which must be a dictionary. Data is stored to the cookie by JSON serialization and then hidden with app.secret_key. Therefore, it must be set on the Application object or with the poor_SecretKey environment variable. Be careful with stored objects. You can add objects with a little Python trick:
sess = PoorSession(app.secret_key) sess.data['class'] = obj.__class__.__name__ # write to cookie sess.data['dict'] = obj.__dict__.copy() obj = globals()[sess.data['class']]() # read from cookie obj.__dict__ = sess.data['dict'].copy()
For a better solution, you can create export and import methods for your object like this:
class Obj:
def from_dict(self, d):
self.attr1 = d['attr1']
self.attr2 = d['attr2']
def to_dict(self):
return {'attr1': self.attr1, 'attr2': self.attr2}
obj = Obj()
sess = PoorSession(app.secret_key)
sess.data['name'] = obj.__class__.__name__ # write to cookie
sess.data['dict'] = obj.to_dict()
obj = globals()[sess.data['name']]() # read from cookie
obj.from_dict(sess.data['dict'])
def __init__(self, secret_key: Union[poorwsgi.request.Request, str, bytes], expires: int = 0, max_age: Optional[int] = None, domain: str = '', path: str = '/', secure: bool = False, same_site: bool = False, compress=<module 'bz2' from...) link | top
Constructor.
- Arguments:
- expires
Cookie
Expirestime in seconds. If it is 0, no expiration is set.- max_age
Cookie
Max-Ageattribute. If both expires and max-age are set, max_age has precedence.- domain
The cookie
Hostto which the cookie will be sent.- path
The cookie
Paththat must exist in the requested URL.- secure
If the
Securecookie attribute will be sent.- same_site
The
SameSiteattribute. When set, it can be one ofStrict|Lax|None. By default, the attribute is not set, which browsers default toLax.- compress
Can be
bz2,gzip.zlib, or any other, which has standard compress and decompress methods. Or it can beNoneto not use any compressing method.- sid
The cookie key name.
session_config = {
'expires': 3600, # one hour
'max_age': 3600,
'domain': 'example.net',
'path': '/application',
'secure': True,
'same_site': True,
'compress': gzip,
'sid': 'MYSID'
}
session = PoorSession(app.secret_key, **session_config)
try:
session.load(req.cookies)
except SessionError as err:
log.error("Invalid session: %s", str(err))
Changed in version 2.4.x: Use app.secret_key in the constructor, and then call the load method.
def destroy(self) link | top
Destroys the session by setting the cookie's expires value to the past (-1).
Ensures that data cannot be changed: https://stackoverflow.com/a/5285982/8379994
def header(self, headers: Union[poorwsgi.headers.Headers, poorwsgi.response.Response, NoneType] = None) link | top
Generates cookie headers and appends them to headers if set.
Returns a list of cookie header pairs.
- headers
The object used to write the header directly.
def load(self, cookies: Optional[http.cookies.SimpleCookie]) link | top
def write(self) link | top
Stores data to the cookie value.
This method is called automatically in the header method.
class SessionError link | top
def check_token(token: str, secret: str, client: str, timeout: Optional[int] = None) link | top
Checks if the token is correct.
The secret, client, and timeout arguments must match those used when the token was generated. If timeout is set, the token must not be older than 2 * timeout.
def get_token(secret: str, client: str, timeout: Optional[int] = None, expired: int = 0) link | top
Creates a token from a secret and client string.
If timeout is set, the token contains a time aligned with twice this value. This is because the creation time can be very close to the computed time.
def hidden(text: Union[str, bytes], passwd: Union[str, bytes]) -> bytes link | top
(En|de)crypts text with a SHA hash of the password via XOR.
- text
Raw data to (en|de)crypt.
- passwd
The password.
log = <Logger poorwsgi (WARNING)> top
module digest link | top
HTTP Authenticate Digest method.
This file can be used as a standalone htdigest-like tool.
python3 -m poorwsgi.digest --help # adding / updating user password python3 -m poorwsgi.digest -c auth.digest 'Secret Zone' user
class PasswordMap link | top
A simple memory object to store user passwords.
- Attributes:
- pathname: str
The full path to the password file; must be set for PasswordMap.write and PasswordMap.load methods.
def __init__(self, pathname=None) link | top
def delete(self, realm, username) link | top
def find(self, realm, username) link | top
def load(self) link | top
def set(self, realm, username, digest) link | top
def verify(self, realm, username, digest) link | top
def write(self) link | top
def check_credentials(req, realm, username=None) link | top
Checks Digest authorization credentials.
Returns True if the Authorization header is valid for the realm. The username is also checked if it is set.
def check_digest(realm, username=None) link | top
Checks HTTP Digest Authentication.
Allows only valid HTTP Digest authorization for the realm. The username is also checked if it is set. If not, an HTTP_UNAUTHORIZED response is raised with the realm and stale value, if needed.
If the user is valid, the req.user attribute is set to the username.
app.auth_type = 'Digest'
@app.route('/admin')
@check_digest('Admin Zone')
def admin_zone(req):
return "This is only for Admins, just like you %s." % req.user
@app.route('/user-looser')
@check_digest('Users', looser)
def looser_only(req):
return "You are the right looser user."
def check_response(req, password) link | top
def get_re_type() link | top
def hexdigest(username, realm, password, algorithm=<built-in function openssl_md5>) link | top
Returns the digest hash value for a user's password.
Returns algorithm(username:realm:password).hexdigest().
def main() link | top
log = <Logger poorwsgi (WARNING)> top
module results link | top
Default PoorWSGI handlers.
| Functions: | not_modified, internal_server_error, bad_request, forbidden, not_found, method_not_allowed, not_implemented, directory_index, debug_info |
|---|
def bad_request(req, error=None) link | top
def debug_info(req, app) link | top
Returns the debug page.
When Application.debug is enabled, this handler is used for /debug-info.
def directory_index(req, path) link | top
def forbidden(req, error=None) link | top
def handlers_view(handlers, sort=True) link | top
def hbytes(val: float) link | top
Returns a value and its unit as a pair.
>>> hbytes(2000000) (1.9..., 'M') >>> hbytes(1024.0) (1.0, 'k')
def html_escape(text: str) link | top
def human_methods_(m) link | top
def internal_server_error(req, *_) link | top
A more debug-friendly 500 Internal Server Error server handler.
It is called automatically when no handlers are defined in dispatch_table.errors. If the poor_Debug variable is set to On, a traceback will be generated.
def method_not_allowed(req, error=None) link | top
def not_found(req, error=None) link | top
def not_implemented(req, code: Optional[int] = None, error=None) link | top
def not_modified(req) link | top
Returns a NotModifiedResponse.
The ETag and Content-Location headers are returned from the request. The Date header will be set.
def unauthorized(req, realm=None, stale='', error=None) link | top
HTML_ESCAPE_TABLE = {'&': '&', '"': '"', "'": ''', '>': '>', '<': '<'} top
log = <Logger poorwsgi (WARNING)> top
module state link | top
def deprecated(reason='') link | top
DECLINED = 0 top
HTTP_ACCEPTED = 202 top
HTTP_ALREADY_REPORTED = 208 top
HTTP_BAD_GATEWAY = 502 top
HTTP_BAD_REQUEST = 400 top
HTTP_CLIENT_CLOSED_REQUEST = 499 top
HTTP_CONFLICT = 409 top
HTTP_CONNECTION_CLOSED_WITHOUT_RESPONSE = 444 top
HTTP_CONTINUE = 100 top
HTTP_CREATED = 201 top
HTTP_EXPECTATION_FAILED = 417 top
HTTP_FAILED_DEPENDENCY = 424 top
HTTP_FORBIDDEN = 403 top
HTTP_GATEWAY_TIME_OUT = 504 top
HTTP_GONE = 410 top
HTTP_IM_USED = 226 top
HTTP_INSUFFICIENT_STORAGE = 507 top
HTTP_INTERNAL_SERVER_ERROR = 500 top
HTTP_I_AM_A_TEAPOT = 418 top
HTTP_LENGTH_REQUIRED = 411 top
HTTP_LOCKED = 423 top
HTTP_LOOP_DETECTED = 508 top
HTTP_METHOD_NOT_ALLOWED = 405 top
HTTP_MOVED_PERMANENTLY = 301 top
HTTP_MOVED_TEMPORARILY = 302 top
HTTP_MULTIPLE_CHOICES = 300 top
HTTP_MULTI_STATUS = 207 top
HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511 top
HTTP_NETWORK_CONNECT_TIMEOUT_ERROR = 599 top
HTTP_NON_AUTHORITATIVE = 203 top
HTTP_NOT_ACCEPTABLE = 406 top
HTTP_NOT_EXTENDED = 510 top
HTTP_NOT_FOUND = 404 top
HTTP_NOT_IMPLEMENTED = 501 top
HTTP_NOT_MODIFIED = 304 top
HTTP_NO_CONTENT = 204 top
HTTP_OK = 200 top
HTTP_PARTIAL_CONTENT = 206 top
HTTP_PAYMENT_REQUIRED = 402 top
HTTP_PERMANENT_REDIRECT = 308 top
HTTP_PRECONDITION_FAILED = 412 top
HTTP_PRECONDITION_REQUIRED = 428 top
HTTP_PROCESSING = 102 top
HTTP_PROXY_AUTHENTICATION_REQUIRED = 407 top
HTTP_RANGE_NOT_SATISFIABLE = 416 top
HTTP_REQUEST_ENTITY_TOO_LARGE = 413 top
HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431 top
HTTP_REQUEST_TIME_OUT = 408 top
HTTP_REQUEST_URI_TOO_LARGE = 414 top
HTTP_RESET_CONTENT = 205 top
HTTP_SEE_OTHER = 303 top
HTTP_SERVICE_UNAVAILABLE = 503 top
HTTP_SWITCHING_PROTOCOLS = 101 top
HTTP_TEMPORARY_REDIRECT = 307 top
HTTP_TOO_MANY_REQUESTS = 429 top
HTTP_UNAUTHORIZED = 401 top
HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451 top
HTTP_UNPROCESSABLE_ENTITY = 422 top
HTTP_UNSUPPORTED_MEDIA_TYPE = 415 top
HTTP_UPGRADE_REQUIRED = 426 top
HTTP_USE_PROXY = 305 top
HTTP_VARIANT_ALSO_VARIES = 506 top
HTTP_VERSION_NOT_SUPPORTED = 505 top
METHOD_ALL = 511 top
METHOD_CONNECT = 128 top
METHOD_DELETE = 16 top
METHOD_GET = 2 top
METHOD_GET_POST = 7 top
METHOD_HEAD = 1 top
METHOD_OPTIONS = 64 top
METHOD_PATCH = 256 top
METHOD_POST = 4 top
METHOD_PUT = 8 top
METHOD_TRACE = 32 top
methods = {'HEAD': 1, 'GET': 2, 'POST': 4, 'PUT': 8, 'DELETE': 16, 'TRACE': 32, 'OPTIONS': 64, 'CONNECT': 128, 'PATCH': 256} top
sorted_methods = [('HEAD', 1), ('GET', 2), ('POST', 4), ('PUT', 8), ('DELETE', 16), ('TRACE', 32), ('OPTIONS', 64), ('CONNECT', 128), ('PATCH', 256)] top
module openapi_wrapper link | top
OpenAPI core wrappers module.
This module (and only this module) requires the openapi_core Python
module from https://github.com/p1c2u/openapi-core, with version 0.13.0
or higher.
| Classes: |
|---|
class OpenAPIRequest link | top
Wrapper of a PoorWSGI request to OpenAPIRequest.
Be careful when testing large incoming request body properties, which
return Request.data depending on the auto_data and data_size
configuration properties. Request.data is available only when the request's
Content-Length is available.
body (READ) top
content_type (READ) top
full_url_pattern (READ) top
host_url (READ) top
method (READ) top
mimetype (READ) top
parameters (READ) top
path (READ) top
def __init__(self, request) link | top
class OpenAPIResponse link | top
content_type (READ) top
data (READ) top
Returns the response data for the validator.
Warning! This will not work for generator responses.