API Reference

Application Classes

class BaseApplication(version, name)

Base application for Application and Rewrite

Parameters:
  • version – Application version

  • name – Application name

Added in version 6.4: name argument.

Changed in version 7.0: version and name arguments must be provided to create an Application.

Added in version 7.8: request_factory and response_factory

Added in version 7.17: statushandler

cliarguments = None

A list of easycli.Argument or easycli.SubCommand.

climain(argv=None)

Provide a callable to call as the CLI entry point.

import sys


if __name__ == '__main__':
    sys.exit(app.climain(sys.argv))

You can use this method as the setuptools entry point for Automatic Script Creation

setup.py

from setuptools import setup


setup(
    name='foo',
    ...
    entry_points={
        'console_scripts': [
            'foo = foo:app.climain'
        ]
    }
)
events = None

A dictionary to hold registered functions to specific hooks.

hook(name, *a, **kw)

Only way to fire registered hooks.

Hooks can registered by when() by the function name.

app.hook('endresponse')

Extra parameters: *a, **kw will be passed to event handlers.

Normally, users no need to call this method.

ready()

Call the configure and then ready application hooks.

You need to call this method before using the instance as the WSGI application.

Typical usage:

from yhttp.core import Application, text


app = Application()

@app.route()
@text
def get(req):
    return 'Hello World!'

if __name__ != '__main__':
    app.ready()
request_factory

alias of Request

response_factory

alias of Response

settings = None

Instance of snam.Meld as the global configuration instance.

shutdown()

Call the shutdown hook().

statushandler = None

A callable(req, status, debug) to override the status response

when(func)

Return decorator to registers the func into events by its name.

Currently these hooks are suuported:

  • configure

  • ready

  • shutdown

  • startresponse

  • endresponse

Added in version 7.3: startresponse hook.

Added in version 7.18: configure hook.

The hook name will be choosed by the func.__name__, so if you need to aware when ready() is called write something like this:

@app.when
def configure(app):
    ...

@app.when
def ready(app):
    ...

@app.when
def shutdown(app):
    ...

@app.when
def startresponse(response):
    ...

@app.when
def endresponse(response):
    ...
class Application(version, name)

Bases: BaseApplication

WSGI Web Application.

Instance of this class can be used as a WSGI application.

Variables:
  • bodyguard_factory – A factory of Guard and or it’s subclasses to be used in Application.bodyguard() to instantiate a new guard for a handler. default: Guard.

  • queryguard_factory – A factory of Guard and or it’s subclasses to be used in Application.queryguard() to instantiate a new guard for a handler. default: Guard.

  • routes – A dictionionary to hold the regext routes handler mappings.

Parameters:
  • version – Application version

  • name – Application name

bodyguard(fields=None, strict=False, **kwargs)

A decorator factory to validate HTTP request’s body.

Added in version 5.1.

from yhttp.core import guard as g

@app.route()
@app.bodyguard(fields=(
    g.String('foo', length=(1, 8), pattern=r'\d+', optional=True),
    g.Integer('bar', range=(0, 9), optional=True),
), strict=True)
@json()
def post(req):
    ...

This method calls the bodyguard_factory to intantiate a BodyGuard class or it’s subclasses.

For list of arguments please refer to BodyGuard.

bodyguard_factory

alias of BodyGuard

delete_route(pattern, verb, flags=0)

Delete a route

Parameters:
  • pattern – Regular expression to match the routing table.

  • flags – Regular expression flags. see re.compile().

  • verb – The HTTP verb to match the routing table.

queryguard(fields=None, strict=False, **kwargs)

A decorator factory to validate the URL’s query string.

Added in version 5.1.

from yhttp.core import guard as g
from yhttp.core.multidict import MultiDict

def bar(req, field: g.Field, values: MultiDict):
    return 'bar default value'

@app.route()
@app.queryguard(fields=(
    g.String(
        'foo',
        length=(1, 8),
        pattern=r'\d+',
        optional=True,
        default='foo default value',
    ),
    g.Integer(
        'bar',
        range=(0, 9),
        optional=True,
        default=bar
   ),
), strict=True)
@json()
def post(req):
    ...

This method calls the queryguard_factory to intantiate a Guard class or it’s subclasses.

For list of arguments please refer to Guard.

queryguard_factory

alias of Guard

route(pattern='/', flags=0, verb=None, insert=None, exists='error', trailingslash=None)

Return a decorator to register a handler for given regex pattern.

if verb is None then the function name will used instead.

@app.route(r'/.*')
def get(req):
    ...

You can bypass this behavior by passing verb keyword argument:

@app.route(r'/', verb='get')
def somethingelse(req):
    ...

To catch any verb by the handler use *.

@app.route(r'/', verb='*')
def any(req):
    ...

Regular expression groups will be capture and dispatched as the positional arguments of the handler after req:

@app.route(r'/(\\d+)/(\\w*)')
def get(req, id, name):
    ...

This method returns a decorator for handler fucntions. So, you can use it like:

books = app.route(r'/books/(.*)')

@books
def get(req, id):
    ...

@books
def post(req, id):
    ...
Parameters:
  • pattern – Regular expression to match the request.

  • flags – Regular expression flags. see re.compile().

  • verb – If not given then handler.__name__ will be used to match HTYP verb, Use * to catch all verbs.

  • insert – If not given, route will be appended to the end of the routes. Otherwise it must be an integer indicating the place to insert the new route into routes attribute.

  • exists – Tell what to do if route already exists, possible values: error``(default) and ``remove to remove the existing route before appending and or inserting the new one.

  • trailingslash – String to determine the path trailing slash behaviour, if remove, trailing slash will be removed before calling the handler. if redirect, handler will not called and instead response with 302 Found with the current path wihtout the trailing slash and finally if None, do nothonig.

Added in version 2.9: insert

Added in version 6.1: exists

Added in version 8.2: trailingslash

staticdirectory(pattern, directory, default=None, autoindex=True, fallback=None, **kw)

Register a directory with a regular expression pattern.

So the files inside the directory are accessible by their names:

app.staticdirectory(r'/foo/', 'physical/path/to/foo')

You you can do:

curl localhost:8080/foo/a.txt

See also

Static Contents

Parameters:
  • pattern – Regular expression to match the requests.

  • directory – Static files are here.

  • default – if None, the app.settings.staticdir.default (which default is index.html) will be used as the default document.

  • autoindex – Automatic directory indexing, default True.

  • fallback – if True, the app.settings.staticdir.fallback (which default is index.html) will be used as the fallback document if the requested resource was not found. if str, the value will be used instead of app.settings.staticdir.fallback.

Added in version 2.13: The default and fallback keyword arguments.

Added in version 3.8: The autoindex keyword argument.

staticfile(pattern, filename, **kw)

Register a filename with a regular expression pattern to be served.

app.staticfile(r'/a\.txt', 'physical/path/to/a.txt')

See also

Static Contents

Rewrite Class

class Rewrite(default=None)

Bases: BaseApplication

Useful to change URL and route requests to other application(s).

Added in version 3.2.

import yhttp.core as y

root = y.Application()
foo = y.Application()
bar = y.Application()

app = y.Rewrite(default=root)
app.route(r'/foo/?', r'/', foo)
app.route(r'/bar/?(.*)', r'/b/\1', bar)
app.ready()

@root.route()
def get(req):
    return 'root'

@foo.route()
def get(req):
    return 'foo'

@bar.route(r'/b')
def get(req):
    return 'bar'
Parameters:

default – Fallback application.

ready()

Call the configure and then ready application hooks.

You need to call this method before using the instance as the WSGI application.

Typical usage:

from yhttp.core import Application, text


app = Application()

@app.route()
@text
def get(req):
    return 'Hello World!'

if __name__ != '__main__':
    app.ready()
route(pattern, repl, handler)

Register an application for specific url.

import yhttp.core as y

root = y.Application()
foo = y.Application()
bar = y.Application()

app = y.Rewrite(default=root)
app.route(r'/foo/([a-z]+)/(\d+)', r'/books/\2/\1', foo)
# Add other applications

app.ready()

See re.sub() for more info about pattern and repl arguments.

Parameters:
  • pattern – A regex pattern to match the environ['PATH_INFO'].

  • repl – URL Rewrite rule, See re.sub()

  • handler – An instance of BaseApplication.

shutdown()

Call the shutdown hook().

Request Class

class Request(app, environ, response)

Represent an HTTP request.

Application.__call__() instantiates this class on each call.

property body

Reads the request body.

property contentlength

HTTP Request Content-Length header value.

property contenttype

HTTP Request Content-Type header value without encoding.

property cookies

Return a dictionary representing the HTTP cookie data.

environ = None

WSIG environ dictionary

property files

Return a dictionary representing the submitted files.

Parse multipart form data from the environ dict and return a dictionary with the form-field name as a key(unicode) and multipart.MultipartPart instances as value, because the form-field was a file-upload or the value is too big to fit into memory limits.

Note

On the first access to this attribute, the Request.form() attribute will be initialized if any not-file fields are submitted.

Added in version 4.0.

property form

Return a MultiDict representing the submitted HTTP from.

Parse form data from the environ dict and return a dictionary with the form-field name as a key(unicode) and lists as values (multiple values per key are possible).

Note

Both urlencoded and multipart are supported.

Note

On the first access to this attribute, the Request.files() attribute will be initialized. if any file fields are submitted using the multipart/form content header.

Added in version 2.6: An easy way to get form values is: .. code-block::

req[‘field-name’]

The above expression is the same as: .. code-block:

req.form['field-name']

Changed in version 4.0: The multipart files are not represented by this attribute and will be accessible by Request.files() instead.

Changed in version 4.0: You may get all values for an identical field using:

req.form.getall('field-name')
property fullpath

Request full URI including query string.

getfiles(relax=False)

Return the request body as a MultiDict object.

This is actualy a wrapper around the Request.files. but raises statuses.lengthrequired and statuses.unprocessablecontent instead of programmatic exceptions if relax=False (the default behaviour).

if relax=True, it returns None on any failure.

getform(relax=False)

Return the request body as a MultiDict object.

This is actualy a wrapper around the Request.form. but raises statuses.lengthrequired and statuses.unprocessablecontent instead of programmatic exceptions if relax=False (the default behaviour).

if relax=True, it returns None on any failure.

getjson(relax=False)

Return the request body as a decoded JSON object.

This is actualy a wrapper around the Request.json. but raises statuses.lengthrequired and statuses.unprocessablecontent instead of programmatic ujson exceptions if relax=False (the default behaviour).

if relax=True, it returns None on any failure.

property headers

HTTP Request headers set.

see HeadersMask class to figure out how it works.

property json

Return a dictionary representing the submitted JSON document.

Note

Content-Type header must be aplication/json.

Added in version 4.0.

property locales

List of agent’s locales ordered based on priority.

It will be ['*'] if Accept-Languages header is not presents in the request.

Added in version 7.8.

property path

Request URL without query string and scheme://domain.ext.

property query

Return A dictionary representing the submitted query string.

response = None

The Response instance associated to this request.

property scheme

Return HTTP Request Scheme (http|https).

property verb

HTTP method.

HeadersMask Class

class HeadersMask(environ)

A simple proxy over Request.environ.

Useful to get headers by their original name without the HTTP_ prefix, which is the python’s WSGI servers default behavior.

@app.route()
def get(req):
    foo = req.headers['foo']
    bar = req.headers.get('bar')
    if 'baz' in req.headers:
        baz = True

     ...

Response Class

class Response(app, environ, startresponse)

Represent the HTTP response.

Which accessible by Request.response inside handlers.

Changed in version 9: type attribute renamed to contenttype

body = None

Response body

charset = None

Response encoding, None for binary

conclude()

Conclude the response.

Calls WSGI start_response callback and encode response body to transfer to the client.

Returns:

response body

contenttype = None

Response content type without charset.

cookies = None

An instance of CookieSet class

headers = None

An instance of HeaderSet class.

length = None

Response content length

start()

Start the response.

Usualy Application calls this method when response is ready to transfered to user.

startstream()

Start streaming the response.

Transfer data chunk by chunk instead of what conclude() does.

status = '200 OK'

HTTP Status code

HeaderSet Class

class HeaderSet(items=None)

A mutable case-insensitive ordered dictionary to keep HTTP headers.

@app.route()
def get(req):
    req.response.headers.add('x-foo', 'a', 'b')
    req.response.headers['x-bar'] = 'bar'
    req.response.headers += ['x-baz: qux']

CookieSet Class

class CookieSet(input=None)

CookieSet class just extends the http.cookies.SimpleCookie class to create a list of HTTP headers, because the class:http.cookies.SimpleCookie class just outputs a concatenated strings.

Added in version 7.16.

tolist(attrs=None, header='Set-Cookie:')

Return a header list suitable for WSGI start_response function.

MultiDict

class MultiDict(backend=None, *args, **kwargs)

A dict that remembers old values for each key.

HTTP headers and query strings may repeat with differing values, such as Set-Cookie. We need to remember all values.

get(k[, d]) D[k] if k in D, else d.  d defaults to None.
keys() a set-like object providing a view on D's keys

contenttype decorators

contenttype(contenttype=None, charset=None, dump=None)

Yield a decorator to set response content type and encoding.

import json

from yhttp.core import contenttype

@app.route()
@contenttype('application/json', 'utf8', json.dumps)
def get(req):
    return {'foo': 'bar'}

There are ready to use contenttype decorators which can importes from yhttp.core package, like: json().

You may create your very own content type decorator by calling this function with desired arguments, for example:

invoice = contenttype('application/pdf', None, dump=makeinvoicepdf)

@app.route('/invoices/(\d+)')
@invoice
def get(req, id):
    ...

The json() decorator is created with something like:

json = contenttype('application/json', 'utf8', dump=json.dumps)
Parameters:
  • contenttype – HTTP Content-Type, example: application/json

  • charset – Character set, example: utf8

  • dump – A callable(body) -> body to transform the body to appropriate content type.

Returns:

decorator for HTTP handlers.

binary(handler)

Sets the Response.contenttype to application/octet-stream.

Handlers must return bytes when this decorator is used.

from yhttp.core import binary


@app.route()
@binary
def get(req):
    return b'binarydata'
json(handler)

Sets the Response.contenttype to application/json;charset=utf-8 and encode the returned value by handler to json byte-string format.

Handlers must return dict when this decorator is used.

from yhttp.core import json


@app.route()
@json
def get(req):
    return {'foo': 'bar'}
text(handler)

Sets the Response.contenttype to text/text; charset=utf-8.

Handlers must return str when this decorator is used.

Added in version 2.8.

from yhttp.core import text


@app.route()
@text
def get(req):
    return 'Unicode String'
html(handler)

Sets the Response.contenttype to text/html; charset=utf-8.

Handlers must return str when this decorator is used.

Added in version 2.8.

from yhttp.core import html


@app.route()
@html
def get(req):
    return 'Unicode String'

gurad Module

class BodyGuard(*args, contenttypes=None, **kwargs)
The guard.BodyGuard class is used to validate the HTTP

request’s body.

see: Application.bodyguard() for more info.

for other parameters and class attributes refer to guard.Guard class.

Parameters:

contenttypes – A tuple of strings to specify allowed content-types.

statusfactory_invalidcontenttype = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 400)

A callable to create an instance of statuses.HTTPStatus when the request’s content-type is not supported.

validate(req, values)

Validates the submitted request

Parameters:
  • req – Current yhttp Request object.

  • values – A MultiDict representing the submitted data.

class Boolean(name, optional=False, default=None, callback=None)

Represent the guard for boolean field.

class Field(name, optional=False, default=None, callback=None)

Base class for all fields such as String

Parameters:
  • optional – If True, the Field.statuscode_missing is not raised when the field is not submitted by the client. default: False.

  • default – A scalar or callable(req, field, valuesdict) as the default value for field if not submitted. this argument implies the optional. default: None.

__call__(*, optional=None, default=None, callback=None, **kwargs)

Copy and override the field.

bar = guard.String('bar')

@app.route
@app.queryguard((
    bar,
    bar(name='baz', optional=True)
))
def get(req, *, bar=None, baz=None):
    ...
status_contenttype = 'text/plain'

contenttype argument of the statuses.HTTPStatus when constructing an instance with statusfactory_* factories.

statusfactory_missing = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 400)

A callable to create an instance of statuses.HTTPStatus when the field is missing in the request.

class File(name, extensions=None, length=None, pattern=None, **kwargs)

Represent the guard for multipart file field.

It just checks the field with that name is exists in the request.

Parameters:
  • name – str, the field name.

  • extensions – list[str], allowd file extensions

__call__(*, length=None, pattern=None, **kwargs)

Copy and override the field.

bar = guard.String('bar')

@app.route
@app.queryguard((
    bar,
    bar(name='baz', optional=True)
))
def get(req, *, bar=None, baz=None):
    ...
statusfactory_badfileextension = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 400)

A callable to create an instance of statuses.HTTPStatus when the received file’s extension is not acceptable.

class Guard(fields=None, strict=False)

The guard.Guard class is used to validate the HTTP requests.

see: Application.bodyguard() for more info.

Parameters:
  • strict – If True, it raises Guard.statuscode_unknownfields when one or more fields are not in the given fields argument.

  • fields – A tuple of Gurad.Field subclass instances to define the allowed fields and field attributes.

status_contenttype = 'text/plain'

contenttype argument of the statuses.HTTPStatus when constructing an instance with statusfactory_* factories.

statusfactory_unknownfields = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 400)

A callable to create an instance of statuses.HTTPStatus when the field is not desired.

validate(req, values)

Validates the submitted data

Parameters:
  • req – Current yhttp Request object.

  • values – A MultiDict representing the submitted data.

class Integer(name, range=None, **kwargs)

Represent the guard for integer field.

Parameters:
  • name – str, the field name.

  • range(int, int), a tuple of (min, max) to specify the minimum and maximum allowed value.

__call__(*, range=None, **kwargs)

Copy and override the field.

bar = guard.String('bar')

@app.route
@app.queryguard((
    bar,
    bar(name='baz', optional=True)
))
def get(req, *, bar=None, baz=None):
    ...
statusfactory_outofrange = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 400)

A callable to create an instance of statuses.HTTPStatus when value is not in specified range.

class NonStringField(name, optional=False, default=None, callback=None)
statusfactory_badtype = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 400)

A callable to create an instance of statuses.HTTPStatus when the type cast to integer int(value) is raises ValueError.

class String(name, length=None, pattern=None, **kwargs)

Represent the guard for string field.

Parameters:
  • name – str, the field name.

  • length(int, int), a tuple of (min, max) to specify the minimum and maximum allowed length for the value.

  • pattern – A regex pattern to specify the data format for the field.

__call__(*, length=None, pattern=None, **kwargs)

Copy and override the field.

bar = guard.String('bar')

@app.route
@app.queryguard((
    bar,
    bar(name='baz', optional=True)
))
def get(req, *, bar=None, baz=None):
    ...
statusfactory_badformat = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 400)

A callable to create an instance of statuses.HTTPStatus when value format is not match with given pattern.

statusfactory_badlength = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 400)

A callable to create an instance of statuses.HTTPStatus when value length is not permitted.

statuses Module

HTTPStatus Class

exception HTTP2xx(code, headers=None, keepheaders=False)

Base class for all HTTP 2xx statuses.

No body will be written when using this class or subclasses.

exception HTTP3xx(code, headers=None, keepheaders=False)

Base class for all HTTP 3xx statuses.

No body will be written when using this class or subclasses.

exception HTTP4xx(*args, message=None, contenttype='text/plain', **kw)

Base class for all HTTP 4xx bad request statuses.

exception HTTP5xx(*args, error=None, **kw)

Base class for all HTTP 5xx error statuses.

exception HTTPStandardStatus(code, headers=None, keepheaders=False)

Base class for all HTTP standard statuses.

So, no need to pass the status text to constructor. it tries to find the propper status text from the Python’s builtin http.StatusCode enum. The rest of arguments are the same as the parent class: HTTPSTatus.

Added in version 8.1.

statustexts = {100: 'Continue', 101: 'Switching Protocols', 102: 'Processing', 103: 'Early Hints', 200: 'OK', 201: 'Created', 202: 'Accepted', 203: 'Non-Authoritative Information', 204: 'No Content', 205: 'Reset Content', 206: 'Partial Content', 207: 'Multi-Status', 208: 'Already Reported', 226: 'IM Used', 300: 'Multiple Choices', 301: 'Moved Permanently', 302: 'Found', 303: 'See Other', 304: 'Not Modified', 305: 'Use Proxy', 307: 'Temporary Redirect', 308: 'Permanent Redirect', 400: 'Bad Request', 401: 'Unauthorized', 402: 'Payment Required', 403: 'Forbidden', 404: 'Not Found', 405: 'Method Not Allowed', 406: 'Not Acceptable', 407: 'Proxy Authentication Required', 408: 'Request Timeout', 409: 'Conflict', 410: 'Gone', 411: 'Length Required', 412: 'Precondition Failed', 413: 'Request Entity Too Large', 414: 'Request-URI Too Long', 415: 'Unsupported Media Type', 416: 'Requested Range Not Satisfiable', 417: 'Expectation Failed', 418: "I'm a Teapot", 421: 'Misdirected Request', 422: 'Unprocessable Entity', 423: 'Locked', 424: 'Failed Dependency', 425: 'Too Early', 426: 'Upgrade Required', 428: 'Precondition Required', 429: 'Too Many Requests', 431: 'Request Header Fields Too Large', 451: 'Unavailable For Legal Reasons', 500: 'Internal Server Error', 501: 'Not Implemented', 502: 'Bad Gateway', 503: 'Service Unavailable', 504: 'Gateway Timeout', 505: 'HTTP Version Not Supported', 506: 'Variant Also Negotiates', 507: 'Insufficient Storage', 508: 'Loop Detected', 510: 'Not Extended', 511: 'Network Authentication Required'}

A dictionary of {code: text} to map the status code to text.

exception HTTPStatus(code, text, headers=None, keepheaders=False)

Base class for all HTTP statuses.

Parameters:
  • code – HTTP status code.

  • text – HTTP status text.

  • keepheaders – If set, appliation keeps the Response.headers when preparing the response. otherwise, all headers which set by the handler will be deleted before sending the response to the client.

  • headers – Some extra HTTP headers to be added to the Response.headers when preparing the response regardless of the keepheaders argument.

Changed in version 8.1.

badgateway = functools.partial(<class 'yhttp.core.statuses.HTTP5xx'>, 502)

HTTP 502 Bad Gateway exception factory

badrequest = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 400)

HTTP 400 Bad Request exception factory

conflict = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 409)

HTTP 409 Conflict exception factory

created = functools.partial(<class 'yhttp.core.statuses.HTTP2xx'>, 201, keepheaders=True)

HTTP 201 Created exception factory

forbidden = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 403)

HTTP 403 Forbidden exception factory

found(location, **kw)

HTTP 302 Found exception factory

gatewaytimeout = functools.partial(<class 'yhttp.core.statuses.HTTP5xx'>, 504)

HTTP 504 Gateway Timeout exception factory

gone = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 410)

HTTP 410 Gone exception factory

internalservererror = functools.partial(<class 'yhttp.core.statuses.HTTP5xx'>, 500)

HTTP 500 Internal Server Error exception factory

lengthrequired = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 411)

HTTP 411 Length Required

methodnotallowed = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 405)

HTTP 405 Method Not Allowed exception factory

movedpermanently(location, **kw)

HTTP 301 Moved Permanently exception factory

nocontent = functools.partial(<class 'yhttp.core.statuses.HTTP2xx'>, 204, keepheaders=True)

HTTP 204 No Content exception factory

notfound = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 404)

HTTP 404 Not Found exception factory

notmodified = functools.partial(<class 'yhttp.core.statuses.HTTP3xx'>, 304)

HTTP 304 Not Modified exception factory

ok = functools.partial(<class 'yhttp.core.statuses.HTTP2xx'>, 200, keepheaders=True)

HTTP 200 OK

preconditionfailed = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 412)

HTTP 412 Precondition Failed exception factory

serviceunavailable = functools.partial(<class 'yhttp.core.statuses.HTTP5xx'>, 503)

HTTP 503 Service Unavailable exception factory

unauthorized = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 401)

HTTP 401 Unauthorized exception factory

unprocessablecontent = functools.partial(<class 'yhttp.core.statuses.HTTP4xx'>, 422)

HTTP 422 Unprocessable Content