API Reference¶
Application Classes¶
- class BaseApplication(version, name)¶
Base application for
ApplicationandRewrite- Parameters:
version – Application version
name – Application name
Added in version 6.4:
nameargument.Changed in version 7.0:
versionandnamearguments must be provided to create an Application.Added in version 7.8:
request_factoryandresponse_factoryAdded in version 7.17:
statushandler- cliarguments = None¶
A list of
easycli.Argumentoreasycli.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.pyfrom setuptools import setup setup( name='foo', ... entry_points={ 'console_scripts': [ 'foo = foo:app.climain' ] } )
See also
- 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, **kwwill be passed to event handlers.Normally, users no need to call this method.
- ready()¶
Call the
configureand thenreadyapplication 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()
- settings = None¶
Instance of
pymlconf.Rootas the global configuration instance.
- statushandler = None¶
A
callable(req, status, debug)to override the status response
- when(func)¶
Return decorator to registers the
funcintoeventsby its name.Currently these hooks are suuported:
configure
ready
shutdown
startresponse
endresponse
Added in version 7.3:
startresponsehook.Added in version 7.18:
configurehook.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:
BaseApplicationWSGI Web Application.
Instance of this class can be used as a WSGI application.
- Variables:
bodyguard_factory – A factory of
Guardand or it’s subclasses to be used inApplication.bodyguard()to instantiate a new guard for a handler. default:Guard.queryguard_factory – A factory of
Guardand or it’s subclasses to be used inApplication.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_factoryto intantiate aBodyGuardclass or it’s subclasses.For list of arguments please refer to
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_factoryto intantiate aGuardclass or it’s subclasses.For list of arguments please refer to
Guard.
- route(pattern='/', flags=0, verb=None, insert=None, exists='error')¶
Return a decorator to register a handler for given regex pattern.
if
verbisNonethen the function name will used instead.@app.route(r'/.*') def get(req): ...
You can bypass this behavior by passing
verbkeyword 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): ...
See also
- 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 intoroutesattribute.exists – Tell what to do if route already exists, possible values:
error``(default) and ``removeto remove the existing route before appending and or inserting the new one.
Added in version 2.9:
insertAdded in version 6.1:
exists
- 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.txtSee also
- Parameters:
pattern – Regular expression to match the requests.
directory – Static files are here.
default – if None, the
app.settings.staticdir.default(which default isindex.html) will be used as the default document.autoindex – Automatic directory indexing, default True.
fallback – if
True, theapp.settings.staticdir.fallback(which default isindex.html) will be used as the fallback document if the requested resource was not found. ifstr, the value will be used instead ofapp.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
Rewrite Class¶
- class Rewrite(default=None)¶
Bases:
BaseApplicationUseful 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
configureand thenreadyapplication 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 aboutpatternandreplarguments.- 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
shutdownhook().
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-Lengthheader value.
- property contenttype¶
HTTP Request
Content-Typeheader 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.MultipartPartinstances 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
MultiDictrepresenting 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 themultipart/formcontent 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
MultiDictobject.This is actualy a wrapper around the
Request.files. but raisesstatuses.lengthrequiredandstatuses.unprocessablecontentinstead of programmatic exceptions ifrelax=False(the default behaviour).if
relax=True, it returnsNoneon any failure.
- getform(relax=False)¶
Return the request body as a
MultiDictobject.This is actualy a wrapper around the
Request.form. but raisesstatuses.lengthrequiredandstatuses.unprocessablecontentinstead of programmatic exceptions ifrelax=False(the default behaviour).if
relax=True, it returnsNoneon any failure.
- getjson(relax=False)¶
Return the request body as a decoded JSON object.
This is actualy a wrapper around the
Request.json. but raisesstatuses.lengthrequiredandstatuses.unprocessablecontentinstead of programmaticujsonexceptions ifrelax=False(the default behaviour).if
relax=True, it returnsNoneon any failure.
- property headers¶
HTTP Request headers set.
see
HeadersMaskclass to figure out how it works.
- property json¶
Return a dictionary representing the submitted JSON document.
Note
Content-Typeheader must beaplication/json.Added in version 4.0.
- property locales¶
List of agent’s locales ordered based on priority.
It will be
['*']ifAccept-Languagesheader 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.
- 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.responseinside handlers.- body = None¶
Response body
- charset = None¶
Response encoding,
Nonefor binary
- conclude()¶
Conclude the response.
Calls WSGI start_response callback and encode response body to transfer to the client.
- Returns:
response body
- property contenttype¶
Response content type incuding charset.
- length = None¶
Response content length
- start()¶
Start the response.
Usualy
Applicationcalls 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
- type = None¶
Response content type without charset.
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']
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¶
HTTPStatus Class¶
- class HTTPStatus(code, text, keepheaders=False, headers=None, body=<function _traceback>, encoder=None)¶
Base class for all HTTP Exceptions.
- Parameters:
code – HTTP status code.
text – HTTP status text.
keepheaders – If set, appliation keeps the
Response.headerswhen exception is occured.headers – Some extra HTTP headers to be added to the
Response.headerswhen exception is raised.body –
- Additional description of what happened which will be rendered
inside the response body when raising this HTTP status. available options:
callable(status: HTTPStatus, debug: bool) -> str,strandNone. ifNonespecified, then no body will be rendered at all. default behaviour is to render the traceback ifapp.settings.debugisTrue.
encoder – Specify how to encode the provided body, available options:
None,jsonand or acallable(body: Any, response)to encode and set appropriateresponse.typeandresponse.body.
Added in version 7.7:
bodyandencoderarguments.
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.corepackage, 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) -> bodyto transform the body to appropriate content type.
- Returns:
decorator for HTTP handlers.
- binary(handler)¶
Sets the
Response.contenttypetoapplication/octet-stream.Handlers must return
byteswhen this decorator is used.from yhttp.core import binary @app.route() @binary def get(req): return b'binarydata'
- json(handler)¶
Sets the
Response.contenttypetoapplication/json;charset=utf-8and encode the returned value by handler to json byte-string format.Handlers must return
dictwhen this decorator is used.from yhttp.core import json @app.route() @json def get(req): return {'foo': 'bar'}
- text(handler)¶
Sets the
Response.contenttypetotext/text; charset=utf-8.Handlers must return
strwhen 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.contenttypetotext/html; charset=utf-8.Handlers must return
strwhen 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.BodyGuardclass is used to validate the HTTP request’s body.
see:
Application.bodyguard()for more info.Added in version 7.20.
for other parameters and class attributes refer to
guard.Guardclass.- Parameters:
contenttypes – A tuple of strings to specify allowed
content-types.- Variables:
statuscode_contenttype – int, the status code to raise when the request’s
content-typeis not starts with one ofcontent-typesspecified withincontenttypesargument.
- The
- class Boolean(name, optional=False, default=None, callback=None)¶
Represent the guard for boolean field.
- Parameters:
name – str, the field name.
- Variables:
statuscode_badtype – int, the status code to raise when the type cast to integer
bool(value)is raisesValueError. default:400.
Added in version 7.2.
- class Field(name, optional=False, default=None, callback=None)¶
Base class for all fields such as
String- Parameters:
optional – If
True, theField.statuscode_missingis 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 theoptional. default:None.
- Variables:
statuscode_missing – int, the status code to raise when the field is not submitted by the user when
strict=True. default:400.
Added in version 5.2:
defaultargument.- __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): ...
- class File(name, extensions=None, length=None, pattern=None, **kwargs)¶
Represent the guard for multipart file field.
Added in version 7.4.
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
- Variables:
statuscode_badextension – int, the status code to raise when the file extension is not allowed. default:
400.
Added in version 7.5:
extensionsargument andstatuscode_badextensionclass attribute.- __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): ...
- class Guard(fields=None, strict=False)¶
The
guard.Guardclass is used to validate the HTTP requests.see:
Application.bodyguard()for more info.Added in version 5.1.
- Parameters:
strict – If
True, it raisesGuard.statuscode_unknownfieldswhen one or more fields are not in the givenfieldsargument.fields – A tuple of
Gurad.Fieldsubclass instances to define the allowed fields and field attributes.
- Variables:
statuscode_unknownfields – int, the status code to raise when an unknown field(s) is/are found.
- 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.
- Variables:
statuscode_badtype – int, the status code to raise when the type cast to integer
int(value)is raisesValueError. default:400.statuscode_outofrange – int, the status code to raise when value is not in specified range.
- __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): ...
- 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.
- Variables:
statuscode_badlength – int, the status code to raise when value length is not permitted. default:
400.statuscode_badformat – int, the status code to raise when value format is not match with given pattern. default:
400.
- __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): ...
statuses Module¶
- exception HTTPStatus(code, text, keepheaders=False, headers=None, body=<function _traceback>, encoder=None)¶
Base class for all HTTP Exceptions.
- Parameters:
code – HTTP status code.
text – HTTP status text.
keepheaders – If set, appliation keeps the
Response.headerswhen exception is occured.headers – Some extra HTTP headers to be added to the
Response.headerswhen exception is raised.body –
- Additional description of what happened which will be rendered
inside the response body when raising this HTTP status. available options:
callable(status: HTTPStatus, debug: bool) -> str,strandNone. ifNonespecified, then no body will be rendered at all. default behaviour is to render the traceback ifapp.settings.debugisTrue.
encoder – Specify how to encode the provided body, available options:
None,jsonand or acallable(body: Any, response)to encode and set appropriateresponse.typeandresponse.body.
Added in version 7.7:
bodyandencoderarguments.
- badgateway = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 502, 'Bad Gateway')¶
HTTP 502 Bad Gateway exception factory
- badrequest = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 400, 'Bad Request')¶
HTTP 400 Bad Request exception factory
- conflict = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 409, 'Conflict')¶
HTTP 409 Conflict exception factory
- created = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 201, 'Created', keepheaders=True)¶
HTTP 201 Created exception factory
- forbidden = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 403, 'Forbidden')¶
HTTP 403 Forbidden exception factory
- found(location, **kw)¶
HTTP 302 Found exception factory
- gatewaytimeout = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 504, 'Gateway Timeout')¶
HTTP 504 Gateway Timeout exception factory
- gone = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 410, 'Gone')¶
HTTP 410 Gone exception factory
- internalservererror = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 500, 'Internal Server Error')¶
HTTP 500 Internal Server Error exception factory
- lengthrequired = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 411, 'Length Required')¶
HTTP 411 Length Required
- methodnotallowed = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 405, 'Method Not Allowed')¶
HTTP 405 Method Not Allowed exception factory
- movedpermanently(location, **kw)¶
HTTP 301 Moved Permanently exception factory
- nocontent = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 204, 'No Content', keepheaders=True, body=None)¶
HTTP 204 No Content exception factory
- notfound = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 404, 'Not Found')¶
HTTP 404 Not Found exception factory
- notmodified = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 304, 'Not Modified', body=None)¶
HTTP 304 Not Modified exception factory
- ok = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 200, 'OK', keepheaders=True)¶
HTTP 200 OK
- preconditionfailed = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 412, 'Precondition Failed')¶
HTTP 412 Precondition Failed exception factory
HTTP 503 Service Unavailable exception factory
- status¶
Alias for
HTTPStatus
- statuscode(code)¶
Set the
Response.statustocode.@app.route() @statuscode('201 Created') def post(req): ... with Given(app, verb='POST'): assert status == '201 Created'
Added in version 2.5.
- unauthorized = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 401, 'Unauthorized')¶
HTTP 401 Unauthorized exception factory
- unprocessablecontent = functools.partial(<class 'yhttp.core.statuses.HTTPStatus'>, 422, 'Unprocessable Content')¶
HTTP 422 Unprocessable Content