module poorwsgi link | top
Poor WSGI connector for Python
Current Contents:
request: Request and FieldStorage classes, which is used for managing requests.
response: Response classes and some make responses functions for creating request response.
results: default result handlers of connector like directory index, servers errors or debug output handler.
state: constants like http status code and method types
wsgi: Application callable class, which is the main point for poorwsgi web application.
digest: HTTP Digest Authorization support.
openapi_wrapper: OpenAPI core wrapper for PoorWSGI Request and Response object
module wsgi link | top
Application callable class, which is the main point for wsgi application.
Classes: | |
---|---|
Functions: |
class Application link | top
Poor WSGI application which is called by WSGI server.
Working of is describe in PEP 333. This object store route dispatch table, and have methods for it's using and of course __call__ method for use as WSGI application.
after (READ) top
Tuple of table with after-response handlers.
auth_algorithm (READ | WRITE) top
Authorization algorithm.
Algorithm depends on authorization type and client support. Supported:
Digest: | MD5 | MD5-sess | SHA256 | SHA256-sess |
---|---|
default: | MD5-sess |
auth_hash (READ) top
Return authorization hash function.
Function can be changed by auth_algorithm property.
default: | md5 |
---|
auth_qop (READ | WRITE) top
Authorization quality of protection.
This is use for Digest authorization only. When browsers
supports only auth
or empty value, PoorWSGI supports the same.
default: | auth |
---|
auth_timeout (READ | WRITE) top
Digest Authorization timeout of nonce value in seconds.
In fact, 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 (5min) |
---|
auth_type (READ | WRITE) top
Authorization type.
Only Digest
type is supported now.
auto_args (READ | WRITE) top
Automatic parsing request arguments from uri.
If it is True (default), Request object do automatic parsing request uri to its args variable.
auto_cookies (READ | WRITE) top
Automatic parsing cookies from request headers.
If it is True (default) and Cookie request header was set, SimpleCookie object was parsed to Request property cookies.
auto_data (READ | WRITE) top
Enabling Request.data property for smaller requests.
Default value is True.
auto_form (READ | WRITE) top
Automatic parsing arguments from request body.
If it is True (default) and method is POST, PUT or PATCH, and request mime type is one of form_mime_types, Request object do automatic parsing request body to its form variable.
auto_json (READ | WRITE) top
Automatic parsing JSON from request body.
If it is True (default), method is POST, PUT or PATCH and request mime type is one of json_mime_types, Request object do automatic parsing request body to json variable.
before (READ) top
Tuple of table with before-response handlers.
cached_size (READ | WRITE) top
Enabling cached_size for faster POST request.
Default value is 65365.
data_size (READ | WRITE) top
Size limit for Request.data property.
This value is which is compare to request Content-Type. Default value is 32768 as 30Kb.
debug (READ | WRITE) top
Application debug as another way how to set poor_Debug.
This setting will be rewrite by poor_Debug environment variable.
defaults (READ) top
Copy of table with default handlers.
document_index (READ | WRITE) top
Application document_root as another way how to set poor_DocumentRoot.
This setting will be rewrite by poor_DocumentRoot environ variable.
document_root (READ | WRITE) top
Application document_root as another way how to set poor_DocumentRoot.
This setting will be rewrite by poor_DocumentRoot environ variable.
errors (READ) top
Copy of table with exception handlers.
file_callback (READ | WRITE) top
File callback use as parameter when parsing request body.
Default is None. Values could be a class or factory which got filename from request body and have file compatible interface.
filters (READ) top
Copy of filter table.
Filter table contains regular expressions and convert functions, see Application.set_filter and Application.route.
Default filters are:
:int match number and convert it to int
:float match number and convert it to float
:word match one string word
:hex match hexadecimal value and convert it to str
:re: match user defined regular expression
none match any string without '/' character
For more details see /debug-info page of your application, where you see all filters with regular expression definition.
form_mime_types (READ) top
Copy of form mime type list.
Contains list of strings as form mime types, which is use for testing, when automatics Form object is create from request body.
json_mime_types (READ) top
Copy of json mime type list.
Contains list of strings as json mime types, which is use for testing, when automatics Json object is create from request body.
keep_blank_values (READ | WRITE) top
Keep blank values in request arguments.
If it is 1 (0 is default), automatic parsing request uri or body keep blank values as empty string.
name (READ) top
read_timeout (READ | WRITE) top
regular_routes (READ) top
Copy of table with regular expression handlers.
routes (READ) top
Copy of table with static handlers.
See Application.route.
secret_key (READ | WRITE) top
Application secret_key could be replace by poor_SecretKey in request.
Secret key is used by PoorSession class. It is generate from some server variables, and the best way is set to your own long key.
states (READ) top
Copy of table with http state handlers.
strict_parsing (READ | WRITE) top
Strict parse request arguments.
If it is 1 (0 is default), automatic parsing request uri or body raise with exception on parsing error.
def __call__(self, env, start_response) link | top
Callable define for Application instance.
This method run __request__ method.
def __init__(self, name='__main__') link | top
Application class is per name singleton.
That means, there could be exist only one instance with same name.
def __profile_request__(self, env, start_response) link | top
Profiler version of __request__.
This method is used if set_profile is used.
def __repr__(self) link | top
def __request__(self, env, start_response) link | top
Create Request instance and return wsgi response.
This method create Request object, call handlers from Application.before, uri handler (handler_from_table), default handler (Application.defaults) or 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
Append handler to call after each response.
Method for direct append function to list functions which 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
Append handler to call before each response.
Method adds function to list functions which is call 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
Append handler to call after each response.
This decorator append function to be called after each response, if you want to use it redefined all outputs.
@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
Append handler to call before each response.
This is decorator for 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
Set default handler.
This is decorator for default handler for http method (called before error_not_found).
@app.default(METHOD_GET_POST) def default_get_post(req): # this function will be called if no uri match in internal # uri table with method. It's similar like not_found error, # but without 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
Wrap 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 dictionary with application variables from system environment.
Application variables start with app_
prefix,
but in returned dictionary is 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 work with os.environ, so it works only with wsgi servers, which set not only request environ, but os.environ too. Apaches mod_wsgi don't do that, uWsgi and PoorHTTP do that.
def handler_from_before(self, req: poorwsgi.request.SimpleRequest) link | top
Internal method, which run all before (pre_proccess) handlers.
This method was call before end-point route handler.
def handler_from_default(self, req: poorwsgi.request.SimpleRequest) link | top
def handler_from_table(self, req: poorwsgi.request.Request) link | top
Call right handler from handlers table (fill with route function).
If no handler is fined, try to find directory or file if Document Root, resp. Document Index is set. Then try to call default handler for right method or call handler for status code 404 - not found.
def http_state(self, status_code: int, method: int = 7) link | top
Wrap 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
Pop handler for http state and method.
As Application.pop_route, for pop multi-method handler, you must call pop_http_state for each method.
def pop_http_state(self, status_code: int, method: int) link | top
Pop handler for http state and method.
As Application.pop_route, for pop multi-method handler, you must call pop_http_state for each method.
def pop_regular_route(self, uri: str, method: int) link | top
Pop handler and converters for uri and method from handlers table.
For more details see Application.pop_route.
def pop_route(self, uri: str, method: int) link | top
Pop handler for uri and method from handers table.
Method must be define unique, so METHOD_GET_POST could not be use. If you want to remove handler for both methods, you must call pop route for each method state.
def regular_route(self, ruri: str, method: int = 3) link | top
Wrap function to be handler for uri defined by regular expression.
Both of function, regular_route and set_regular_route store routes to special internal table, which is another to table of static routes.
# simple regular expression @app.regular_route(r'/user/\w+') def any_user(req): ... # regular expression with @app.regular_route(r'/user/(?P<user>\w+)') def user_detail(req, user): # named path args ...
Be sure with ordering of call this decorator or set_regular_route function. Regular expression routes are check with the same ordering, as you create internal table of them. First match stops any other searching.
def route(self, uri: str, method: int = 3) link | top
Wrap function to be handler for uri and specified method.
You can define uri as static path or as groups which are hand to handler as next 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 own regular expression filter @app.route('/<car:re:\w+>/<color:re:#[\da-fA-F]+>') def car(req, car, color): ...
If you can use some name of group which is python keyword, like class, you can use **kwargs syntax:
@app.route('/<class>/<len:int>') def classes(req, **kwargs): return ("'%s' class is %d lenght." % (kwargs['class'], kwargs['len']))
Be sure with ordering of call this decorator or set_route function with groups regular expression. Regular expression routes are check with the same ordering, as you create internal table of them. First match stops any other searching. In fact, if groups are detect, they will be transfer to normal regular expression, and will be add to second internal table.
def set_default(self, fun: Callable, method: int = 3) link | top
Set default handler.
Set fun default handler for 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
Create new filter or overwrite built-ins.
- name: str
Name of filter which is used in route or set_route method.
- regex: str
Regular expression which used for filter.
- converter: function
Converter function or class, which gets string in input. Default is str function, which call __str__ method on 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
Set profiler for __call__ function.
- runctx: function
function from profiler module
- dump: str
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
Set handler for uri defined by regular expression.
Another way to add fn as handler for uri defined by regular expression. See Application.regular_route documentation for details.
app.set_regular_route('/use/\w+/post', user_create, METHOD_POST)
This method is internally use, when groups are found in static route, adding by route or set_route method.
def set_route(self, uri: str, fun: Callable, method: int = 3) link | top
Set handler for uri and method.
Another way to add fun as handler for 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 status code is in Application.shandlers (fill with http_state function), call this handler.
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
module request link | top
Classes, which is used for managing requests.
Classes: | SimpleRequest, Request, EmptyForm, Args, Json |
---|
class Args link | top
Compatibility class for read values from QUERY_STRING.
Class is based on dictionary. It has getfirst and getlist methods, which can call function on 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
Get first item from list for key or default.
- default: any
Default value if key not exists.
- func: converter
Function which processed value.
- fce: deprecated converter name
Use 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 list of variable values for key or empty list.
- default: list or None
Default list if key not exists.
- func: converter
Function which processed each value.
- fce: deprecated converter name
Use func converter just like getvalue.
def getvalue(self, key: str, default: Any = None, func: Callable = poorwsgi.fieldstorage.<lambda>) link | top
Get but func is called for all values.
- Arguments:
- key: str
key name
- default: None
default value if key not found
- func: converter (lambda x: x)
Function or class which processed value. Default type of value is bytes for files and string for others.
class CachedInput link | top
Wrapper around wsgi.input file, which reads data block by block.
- timeout: float
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
Compatibility class for read values from JSON POST, PUT or PATCH request.
It has getfirst and getlist methods, which can call function on values.
Deprecated: this class will be deleted in next 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
Get first item from list for key or default.
- default: any
Default value if key not exists.
- func: converter
Function which processed value.
- fce: deprecated converter name
Use 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 list of variable values for key or empty list.
- default: list or None
Default list if key not exists.
- func: converter
Function which processed each value.
- fce: deprecated converter name
Use func converter just like getvalue.
def getvalue(self, key: str, default: Any = None, func: Callable = poorwsgi.fieldstorage.<lambda>) link | top
Get but func is called for all values.
- Arguments:
- key: str
key name
- default: None
default value if key not found
- func: converter (lambda x: x)
Function or class which processed value. Default type of value is bytes for files and string for others.
class JsonList link | top
Compatibility class for read values from JSON POST, PUT or PATCH request.
It has getfirst and getlist methods, which can call function on values.
Deprecated: this class will be deleted in next major version.
def getfirst(self, key=None, default: Any = None, func: Callable = request.<lambda>, fce: Optional[Callable] = None) link | top
Returns first variable value or default, if no one exist.
- key: None
Compatibility parametr is ignored.
- default: any
Default value if key not exists.
- func: converter
Function which processed value.
- fce: deprecated converter name
Use 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 list of values
- key: None
Compatibility parametr is ignored.
- default: list
Default value when self is empty.
- func: converter
Function which processed value.
- fce: deprecated converter name
Use func converter just like getvalue.
def getvalue(self, key=None, default: Any = None, func: Callable = request.<lambda>) link | top
Returns first item or defualt if no exists.
- key: None
Compatibility parametr is ignored.
- default: any
Default value if key not exists.
- func: converter (lambda x: x)
Function or class which processed value. Default type of value is bytes for files and string for others.
class Request link | top
HTTP request object with all server elements.
It could be compatible as soon 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 accept negotiations
values.accept_json (READ) top
application/json
mime type is in accept
negotiations values.accept_language (READ) top
accept_xhtml (READ) top
text/xhtml
mime type is in accept negotiations
values.api (READ | WRITE) top
app (READ) top
args (READ | WRITE) top
Extended dictionary (Args instance) of request arguments.
Argument are parsed from QUERY_STRING, which is typical, but not only for GET method. Arguments are parsed when Application.auto_args is set which is default.
This property could be set only once.
authorization (READ) top
charset (READ) top
Content-Type
charset header string, utf-8 if not set.content_length (READ) top
Content-Length
header value, -1 if not set.cookies (READ) top
SimpleCookie iterable object of all cookies from Cookie header.
This property was set if Application.auto_cookies is set to true, which is default. Otherwise cookies is None.
data (READ) top
Returns input data from wsgi.input file.
This works only, when auto_data configuration and Content-Length of request are lower then input_cache configuration value. Other requests like big file data uploads increase memory and time system requests.
db (READ | WRITE) top
debug (READ) top
poor_Debug
variable.document_index (READ) top
Value of poor_DocumentIndex variable.
Variable is used to generate index html page, when poor_DocumentRoot is set.
document_root (READ) top
end_time (READ) top
environ (READ) top
error_handler (READ | WRITE) top
This property is set only when error handler was called.
It was set by Application object when error handler is known before calling.
form (READ | WRITE) top
Dictionary like class (FieldStorage instance) of body arguments.
Arguments must be send in request body with mime type one of Application.form_mime_types. Method must be POST, PUT or PATCH. Request body is parsed when Application.auto_form is set, which default and when method is POST, PUT or PATCH.
This property could be set only once.
forwarded_for (READ) top
X-Forward-For
http header if exists.forwarded_host (READ) top
X-Forward-Host
http header without port if exists.forwarded_port (READ) top
X-Forward-Host
or X-Forward-Proto
header.forwarded_proto (READ) top
X-Forward-Proto
http header if 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 with XMLHttpRequest
value.json (READ) top
Json dictionary if request mime type is JSON.
Json types is defined in Application.json_mime_types, typical is
application/json
and request method must be POST, PUT or PATCH and
Application.auto_json must be set to true (default). Otherwise json
is EmptyForm.
When request data is present, that will by parsed with parse_json_request function.
method (READ) top
GET, HEAD, POST
, etc.method_number (READ) top
mime_type (READ) top
Content-Type
header or empty string if not set.path (READ) top
path_args (READ | WRITE) top
poor_environ (READ) top
Environ with poor_
variables.
It is environ from request, or os.environ
port (READ) top
server_port
property.protocol (READ) top
server_protocol
propertyquery (READ) top
referer (READ) top
remote_addr (READ) top
remote_host (READ) top
scheme (READ) top
secret_key (READ) top
Value of poor_SecretKey
variable.
Secret key is used by PoorSession class. It is generate from some server variables, and the best way is set programmatically by 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/0.9
. 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 point as uri_rule.
It was set by Application object when end point handler is known before calling all pre handlers. Typical use case is set some special attribute to handler, and read them in pre handler.
Property was set when any route is found for request uri. Sending file internaly when document_root is set, or by Error handlers leave uri_handler None.
uri_rule (READ | WRITE) top
Rule from one of application handler table.
This property could be set once, and that do Application object. There
are some internal uri_rules which is set typical if some internal
handler was called. There are: /*
for default, directory and file
handler and /debug-info
for debug handler. In other case, there be
url or regex.
user (READ | WRITE) top
user_agent (READ) top
def __del__(self) link | top
def __init__(self, environ, app) link | top
Object was created automatically in wsgi module.
It's input parameters are the same, which Application object gets from WSGI server plus file callback for auto request body parsing.
def construct_url(self, uri: str) link | top
This function returns a fully qualified URI string.
Url is create from the path specified by uri, using the information stored in the request to determine the scheme, server host name and port. The port number is not included in the string if it is the same as the default port 80.
def get_options(self) link | top
Returns dictionary with application variables from environment.
Application variables start with app_
prefix, but in returned
dictionary is 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
Read data from client (typical for XHR2 data POST).
If length is not set, or if is lower then zero, Content-Length was be use.
def read_chunk(self) link | top
Read chunk when Transfer-Encoding is chunked .
Method read line with chunk size first, then read chunk and return it, or raise ValueError when chunk size is in bad format.
Be sure that wsgi server allow readline from wsgi.input. For examples uWSGI has extra API 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 poor_DocumentIndex variable.
Variable is used to generate index html page, when poor_DocumentRoot is set.
document_root (READ) top
end_time (READ) top
environ (READ) top
error_handler (READ | WRITE) top
This property is set only when error handler was called.
It was set by Application object when error handler is known before calling.
forwarded_for (READ) top
X-Forward-For
http header if exists.forwarded_host (READ) top
X-Forward-Host
http header without port if exists.forwarded_port (READ) top
X-Forward-Host
or X-Forward-Proto
header.forwarded_proto (READ) top
X-Forward-Proto
http header if 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
Environ with poor_
variables.
It is environ from request, or os.environ
port (READ) top
server_port
property.protocol (READ) top
server_protocol
propertyquery (READ) top
referer (READ) top
remote_addr (READ) top
remote_host (READ) top
scheme (READ) top
secret_key (READ) top
Value of poor_SecretKey
variable.
Secret key is used by PoorSession class. It is generate from some server variables, and the best way is set programmatically by 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/0.9
. 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 point as uri_rule.
It was set by Application object when end point handler is known before calling all pre handlers. Typical use case is set some special attribute to handler, and read them in pre handler.
Property was set when any route is found for request uri. Sending file internaly when document_root is set, or by Error handlers leave uri_handler None.
uri_rule (READ | WRITE) top
Rule from one of application handler table.
This property could be set once, and that do Application object. There
are some internal uri_rules which is set typical if some internal
handler was called. There are: /*
for default, directory and file
handler and /debug-info
for debug handler. In other case, there be
url or 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.
Url is create from the path specified by uri, using the information stored in the request to determine the scheme, server host name and port. The port number is not included in the string if it is the same as the default port 80.
def get_options(self) link | top
Returns dictionary with application variables from environment.
Application variables start with app_
prefix, but in returned
dictionary is 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: back compatibility function.
This function will be deleted in next major version.
Use direct FieldStorageParser instead of this!.
def parse_json_request(raw: bytes, charset: str = 'utf-8') link | top
Try to parse request data.
Returned type could 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
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
class Declined link | top
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
class EmptyResponse link | top
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
class FileObjResponse link | top
FileResponse returns file object direct to WSGI server.
This means, that sendfile UNIX system call can be used.
Be careful not to use a single FileReponse instance multiple times! WSGI server closes file, which is returned by this response. So just like Response, instance of FileResponse can be used only once!
File content is returned from current position. So Content-Length is set from file system or from buffer, but minus position.
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
Return data content.
This property works only if file_obj is seekable.
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
class FileResponse link | top
FileResponse returns opened file direct to WSGI server.
This means, that sendfile UNIX system call can be used.
Be careful not to use a single FileReponse instance multiple times! WSGI server closes file, which is returned by this response. So just like Response, instance of FileResponse can be used only once!
This object adds Last-Modified header, if is not set.
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
Return data content.
This property works only if file_obj is seekable.
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
class GeneratorResponse link | top
For response, which use generator as returned value.
Even though you can figure out iterating your generator more times, just like Response, instance of GeneratorResponse can be used only once!
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
class HTTPException link | top
HTTP Exception to fast stop work.
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
status_code is one of HTTP_* status code from state module.
If response is set, that will use, otherwise the handler from Application will be call.
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
JSON Response for data from generator.
Data will be processed in generator way, so they need to be buffered. This class need simplejson module.
** kwargs from constructor are serialized to json structure.
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
class JSONResponse link | top
Simple application/json response.
- Arguments:
- data_: Any
Alternative way to add any data to json response.
- charset: str
charset
value forContent-Type
header.utf-8
by default.- headers: Headers
- status_code: int
- encoder_kwargs: dict
Keyword arguments for
json.dumps
function.- kwargs: keywords 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
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
def write(self, data: Union[str, bytes]) link | top
class NoContentResponse link | top
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
class NotModifiedResponse link | top
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
class PartialResponse link | top
Partial Response object which only compute Content-Range header.
This is for special cases, when you can know how to return right range, for example, when you want to return another 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
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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 mathod do nothing.
For creating Content-Range header, use special make_range method.
def make_range(self, ranges: List[Tuple[Optional[int], Optional[int]]], units='bytes', full='*') link | top
Just set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
def write(self, data: Union[str, bytes]) link | top
class RedirectResponse link | top
Redirect the browser to another location.
A short text is sent to the browser informing 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
or status_code
is true, MOVED_PERMANENTLY
status code will be sent to the client, otherwise it will be
MOVED_TEMPORARILY. Argument ``permanent`` and ``status_code`` as boolean
is deprecated. Use real status_code instead.
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
def write(self, data: Union[str, bytes]) link | top
class Response link | top
HTTP Response object.
This is base Response object which is process with PoorWSGI application.
As Response uses BytesIO as internal cache, which is closed by WSGI server, response can be used only once!.
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with 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
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
class TextResponse link | top
content_length (READ) top
Return content_length of response.
That is size of internal buffer.
data (READ) top
headers (READ | WRITE) top
ranges (READ) top
reason (READ) top
HTTP response is set automatically with setting status_code.
Setting response message is not good idea, but you can create own class based on Response, when you can override status_code setter.
status_code (READ | WRITE) top
Http status code, which is state.HTTP_OK (200) by default.
If you want to set this variable (which is very good idea in http_state
handlers), it is good solution to use some of HTTP_
constant from
state module.
def __call__(self, start_response: Callable) link | top
def __end_of_response__(self) link | top
Method for internal use only!.
This method was called from Application object at the end of request for returning right value to 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
Make response partial.
It adds Accept-Ranges headers with units value and set range to new value. If range is defined, and response support seek in buffer, or skip generator, it returns right range response.
Inconsistent ranges are skipped!
Response status_code MUST be HTTP_OK (200 OK). Only one range is supported at this moment. Other behaviour, like If-Range conditions depends on response or programmers support.
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 set Content-Range header values and units attribute.
Content-Range is set in __start_response__ method for HTTP_OK status. This method is need, when you want to make partial response by yourself. This method needs response with HTTP_PARTIAL_CONTENT status.
def write(self, data: Union[str, bytes]) link | top
def abort(arg: Union[int, response.BaseResponse]) link | top
Raise HTTPException with arg.
Raise simple error exception:
>>> abort(404) Traceback (most recent call last): ... poorwsgi.response.HTTPException: (404, {})
Raise exception with response:
>>> abort(Response(data=b'Created', status_code=201)) 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
Create response from values.
If data are:
str, bytes: | Response is returned. |
---|---|
list, dict: | JSONResponse is returned. List can't be list of bytes, otherwise GeneratorResponse is returned. |
Iterable: | GeneratorResponse is returned |
Data could be string, bytes, or bytes returns iterable object like 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 leave 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
Raise HTTPException with RedirectResponse response.
See RedirectResponse, with same interface for more information about response.
NOT_MODIFIED_DENY = {'Content-Language', 'Content-MD5', 'Content-Range', 'Content-Type', 'Content-Length', 'Content-Encoding'} top
NOT_MODIFIED_ONE_OF_REQUIRED = {'Date', 'Vary', 'ETag', 'Content-Location'} top
log = <Logger poorwsgi (WARNING)> top
module headers link | top
Classes, which is used for managing headers.
Classes: | |
---|---|
Functions: |
class ContentRange link | top
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
Class inherited from collections.Mapping.
As PEP 333, resp. RFC 2616 says, all headers names must be only US-ASCII character except control characters or separators. And headers values must be store in string encoded in ISO-8859-1. This class methods Headers.add and Headers.add_header do auto convert values from UTF-8 to ISO-8859-1 encoding if it is possible. So on every modification methods must be use UTF-8 string.
Some headers can be set twice. At this moment, response can contain only
more Set-Cookie
headers, but you can use add_header method to add more
headers with same name. Or you can create headers from tuples, which is
used in Request.
When more same named header is set in HTTP request, server join it's value to one.
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.
Headers object could be create from list, set or tuple of pairs name, value. Or from dictionary. All names or values must be iso-8859-1 encodable. If not, AssertionError will be raised.
If strict is False, headers names and values are not encoded to iso-8859-1. This is for input headers using 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
Set header name to value.
Duplicate names are not allowed instead of Set-Cookie
.
def add_header(self, name: str, value: Union[str, List[Tuple], NoneType] = None, **kwargs) link | top
Extended header setting.
- name: str
Header field to add.
- value: str or list of tuples
If value is list of tuples, render_negogation will be used.
- kwargs: dict
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-Encodding', [('gzip',1.0), ('*',0)])
All names must be US-ASCII string except control characters or separators.
def get(self, key, default=None) link | top
def get_all(self, name: str) link | top
Return tuple of all values of header identified by lower 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
Doing automatic conversion to iso-8859-1 strings.
Converts from utf-8 to iso-8859-1 string. That means, all input value of Headers class must be UTF-8 stings.
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
Return HTTP Date from 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
Return timestamp from HTTP Date
>>> 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
Return timestamp from HTTP Date
>>> http_to_time("Thu, 01 Jan 1970 00:00:00 GMT") 0
def parse_header(line) link | top
Parse a Content-type like header.
Return 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
Parse content negotiation headers to 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
Parse HTTP Range header.
Parse Range header value and return dictionary with units key and list tuples of range.
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
Render 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
Return HTTP Date from 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 legacy cgi.FieldStorage.
Classes: | |
---|---|
Functions: |
class FieldStorage link | top
Class inspired by cgi.FieldStorage.
Instead of FieldStorage from cgi module, this is only storage for fields, with some additional functionality in getfirst, getlist, getvalue or simple get method. They return values instead of __getitem__ ([]), which returns another FieldStorage.
Available attributes:
name: | variable name, the same name from input attribute. |
---|---|
value: | property which returns content of field |
type: | mime-type of variable. All variables have internal mime-type, if that is no file, mime-type is text/plain. |
type_options: | other content-type parameters, just like encoding. |
disposition: | content disposition header if is set |
disposition_options: | other content-disposition parameters if are set. |
filename: | if variable is file, filename is its name from form. |
length: | field length if was set in header, -1 by default. |
file: | file type instance, from you can read variable. This instance could be TemporaryFile as default for files, StringIO for normal variables or instance of your own file type class, create from file_callback. |
lists: | if variable is list of variables, this contains instances of other fields. |
FieldStorage is create by FieldStorageParser.
FieldStorage has context methods, so you cat read files like this: >>> field = FieldStorage("key") >>> field.file = StringIO("value") >>> with field: ... print(field.value) value
value (READ) top
Return content of field.
If field is file, return it's content.
If field is string value, return string.
If field is list of other fields (root FieldStorage), return that list.
>>> 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 methods with dict.
Return value of list of values if exists.
>>> 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
Get first item from list for key or default.
Use 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 list of variable values for key or empty list.
Use 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
Get but func is called for all values.
- Arguments:
- key: str
key name
- default: None
default value if key not found
- func: converter (lambda x: x)
Function or class which processed value. 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
Dictionary like keys() method.
>>> field = FieldStorage() >>> field.list = [FieldStorage("key", "value")] >>> field.keys() dict_keys(['key'])
class FieldStorageInterface link | top
FieldStorage Interface
Implements 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
Get first item from list for key or default.
- default: any
Default value if key not exists.
- func: converter
Function which processed value.
- fce: deprecated converter name
Use 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 list of variable values for key or empty list.
- default: list or None
Default list if key not exists.
- func: converter
Function which processed each value.
- fce: deprecated converter name
Use func converter just like getvalue.
def getvalue(self, key: str, default: Any = None, func: Callable = fieldstorage.<lambda>) link | top
Get but func is called for all values.
- Arguments:
- key: str
key name
- default: None
default value if key not found
- func: converter (lambda x: x)
Function or class which processed value. Default type of value is bytes for files and string for others.
class FieldStorageParser link | top
Class inspired by cgi.FieldStorage.
This is only parsing part of old FieldStorage. It contain methods for parsing POST form encoede in multipart/form-data or application/x-www-form-urlencoded which is default.
It generate FieldStorage or Field in depennd on encoding. But it do it only from request body. FieldStorage has internal StringIO for all values which are not stored in file. Some small binary files can be stored in BytesIO. 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. Read multipart/* until last part.
Arguments, all optional:
input_: | Request.input file object |
---|---|
headers: | header dictionary-like object |
outerboundary: | terminating multipart boundary (for internal use only) |
keep_blank_values: | 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: | 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 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: | int. If set, then parse throws a ValueError if there are more than n fields read by parse_qsl(). |
file_callback: | function returns file class for own handling creating files for write operations. By this, you can write file from request direct to destionation without temporary files. |
def _parse_content_type(self) link | top
Process content-type header
Honor any existing content-type header. But if there is no content-type header, use some sensible defaults. Assume 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 which erroneously forget to include a content-type header.
See below for what we do if there does exist a content-type header, but it happens to be something we don't understand.
def _skip_to_boundary(self) link | top
def _write(self, line, file) link | top
def make_file(self) link | top
Return readable and writable temporery file.
If filename and file_callback was set, file_callback is called instead of creating 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
Check 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 whith two static method for PoorSession.
If compress parameter is None, this class is use.
def compress(data, compresslevel=0) link | top
def decompress(data) link | top
class PoorSession link | top
Self-contained cookie with session data.
You cat store or read data from object via PoorSession.data variable which must be dictionary. Data is stored to cookie by pickle dump, and next hidden with app.secret_key. So it must be set on Application object or with poor_SecretKey environment variable. Be careful with stored object. You can add object with little python trick:
sess = PoorSession(app.secret_key) sess.data['class'] = obj.__class__ # write to cookie sess.data['dict'] = obj.__dict__.copy() obj = sess.data['class']() # read from cookie obj.__dict__ = sess.data['dict'].copy()
Or for beter solution, you can create export and import methods for you object like that:
class Obj(object): def import(self, d): self.attr1 = d['attr1'] self.attr2 = d['attr2'] def export(self): d = {'attr1': self.attr1, 'attr2': self.attr2} return d obj = Obj() sess = PoorSession(app.secret_key) sess.data['class'] = obj.__class__ # write to cookie sess.data['dict'] = obj.export() obj = sess.data['class']() # read from cookie obj.import(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: int
Cookie
Expires
time in seconds, if it 0, no expire is set- max_age: int
Cookie
Max-Age
attribute. If both expires and max-age are set, max_age has precedence.- domain: str
Cookie
Host
to which the cookie will be sent.- path: str
Cookie
Path
that must exist in the requested URL.- secure: bool
If
Secure
cookie attribute will be sent.- same_site: str
The
SameSite
attribute. When is set could be one ofStrict|Lax|None
. By default attribute is not set which isLax
by browser.- compress: compress module or class.
Could be
bz2
,gzip.zlib
, or any other, which have standard compress and decompress methods. Or it could beNone
to not use any compressing method.- sid: str
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 = PostSession(app.secret_key, **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 constructor, and than call load method.
def destroy(self) link | top
Destroy session. In fact, set cookie expires value to past (-1).
Be sure, that data can't be changed: https://stackoverflow.com/a/5285982/8379994
def header(self, headers: Union[poorwsgi.headers.Headers, poorwsgi.response.Response, NoneType] = None) link | top
def load(self, cookies: Optional[http.cookies.SimpleCookie]) link | top
def write(self) link | top
Store data to cookie value.
This method is called automatically in header method.
class SessionError link | top
def check_token(token: str, secret: str, client: str, timeout: Optional[int] = None) link | top
Check token, if it is right.
Arguments secret, client and expired must be same, when token was generated. If expired is set, than token must be younger than 2*expired.
def get_token(secret: str, client: str, timeout: Optional[int] = None, expired: int = 0) link | top
Create token from secret, and client string.
If timeout is set, token contains time align with twice of this value. Twice, because time of creating can be so near to computed time.
def hidden(text: Union[str, bytes], passwd: Union[str, bytes]) -> bytes link | top
(en|de)crypt text with sha hash of passwd via xor.
- Arguments:
- text: str or bytes
raw data to (en|de)crypt
- passwd: str or bytes
password
log = <Logger poorwsgi (WARNING)> top
module digest link | top
HTTP Authenticate Digest method.
This file could be used as known htdigest
tool.
python3 -m poorwsgi.digest --help # adding / updating user password python3 -m poorwsgi.digest -c auth.digest 'Secret Zone' user
class PasswordMap link | top
Simple memory object to store user password.
- Attributes:
- pathname: str
Full path to 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
Check Digest authorization credentials.
Return True if Authorization header is valid for realm. Username is checked too, if it is set.
def check_digest(realm, username=None) link | top
Check HTTP Digest Authenticate.
Allow only valid HTTP Digest authorization for realm. Username is checked too, if it is set. When no, HTTP_UNAUTHORIZED response was raised with realm and stale value if is need.
When user is valid, req.user attribute is set to 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
def main() link | top
log = <Logger poorwsgi (WARNING)> top
module results link | top
Default Poor WSGI 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
Return debug page.
When Application.debug is enable, 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
def html_escape(text: str) link | top
def human_methods_(m) link | top
def internal_server_error(req, *_) link | top
More debug 500 Internal Server Error server handler.
It was be called automatically when no handlers are not defined in dispatch_table.errors. If poor_Debug variable is to On, Tracaback 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
Return NotModifiedResponse.
Headers ETag, Content-Location is return from request. 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 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 PoorWSGI request to OpenAPIRequest.
Be careful with testing of big incoming request body property, which
returns Request.data depend on auto_data
and data_size
configuration properties. Request.data is available only when request
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
Return response data for validator.
Warning! This will not work for generator responses"