add documentation for cookies, exception, blueprint and handlers

Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
This commit is contained in:
Harsha Narayana 2018-12-08 11:57:10 +05:30
parent 1623d397be
commit e6fba01682
No known key found for this signature in database
GPG Key ID: 8AF211CB60D4B28C
4 changed files with 227 additions and 21 deletions

View File

@ -38,11 +38,17 @@ class Blueprint:
version=None, version=None,
strict_slashes=False, strict_slashes=False,
): ):
"""Create a new blueprint """
In *Sanic* terminology, a **Blueprint** is a logical collection of
URLs that perform a specific set of tasks which can be identified by
a unique name.
:param name: unique name of the blueprint :param name: unique name of the blueprint
:param url_prefix: URL to be prefixed before all route URLs :param url_prefix: URL to be prefixed before all route URLs
:param strict_slashes: strict to trailing slash :param host: IP Address of FQDN for the sanic server to use.
:param version: Blueprint Version
:param strict_slashes: Enforce the API urls are requested with a
training */*
""" """
self.name = name self.name = name
self.url_prefix = url_prefix self.url_prefix = url_prefix
@ -59,8 +65,9 @@ class Blueprint:
@staticmethod @staticmethod
def group(*blueprints, url_prefix=""): def group(*blueprints, url_prefix=""):
"""Create a list of blueprints, optionally """
grouping them under a general URL prefix. Create a list of blueprints, optionally grouping them under a
general URL prefix.
:param blueprints: blueprints to be registered as a group :param blueprints: blueprints to be registered as a group
:param url_prefix: URL route to be prepended to all sub-prefixes :param url_prefix: URL route to be prepended to all sub-prefixes
@ -83,7 +90,14 @@ class Blueprint:
return bps return bps
def register(self, app, options): def register(self, app, options):
"""Register the blueprint to the sanic app.""" """
Register the blueprint to the sanic app.
:param app: Instance of :class:`sanic.app.Sanic` class
:param options: Options to be used while registering the
blueprint into the app.
*url_prefix* - URL Prefix to override the blueprint prefix
"""
url_prefix = options.get("url_prefix", self.url_prefix) url_prefix = options.get("url_prefix", self.url_prefix)
@ -160,6 +174,15 @@ class Blueprint:
:param uri: endpoint at which the route will be accessible. :param uri: endpoint at which the route will be accessible.
:param methods: list of acceptable HTTP methods. :param methods: list of acceptable HTTP methods.
:param host: IP Address of FQDN for the sanic server to use.
:param strict_slashes: Enforce the API urls are requested with a
training */*
:param stream: If the route should provide a streaming support
:param version: Blueprint Version
:param name: Unique name to identify the Route
:return a decorated method that when invoked will return an object
of type :class:`FutureRoute`
""" """
if strict_slashes is None: if strict_slashes is None:
strict_slashes = self.strict_slashes strict_slashes = self.strict_slashes
@ -196,9 +219,10 @@ class Blueprint:
or class instance with a view_class method. or class instance with a view_class method.
:param uri: endpoint at which the route will be accessible. :param uri: endpoint at which the route will be accessible.
:param methods: list of acceptable HTTP methods. :param methods: list of acceptable HTTP methods.
:param host: :param host: IP Address of FQDN for the sanic server to use.
:param strict_slashes: :param strict_slashes: Enforce the API urls are requested with a
:param version: training */*
:param version: Blueprint Version
:param name: user defined route name for url_for :param name: user defined route name for url_for
:return: function or class instance :return: function or class instance
""" """
@ -233,6 +257,11 @@ class Blueprint:
"""Create a blueprint websocket route from a decorated function. """Create a blueprint websocket route from a decorated function.
:param uri: endpoint at which the route will be accessible. :param uri: endpoint at which the route will be accessible.
:param host: IP Address of FQDN for the sanic server to use.
:param strict_slashes: Enforce the API urls are requested with a
training */*
:param version: Blueprint Version
:param name: Unique name to identify the Websocket Route
""" """
if strict_slashes is None: if strict_slashes is None:
strict_slashes = self.strict_slashes strict_slashes = self.strict_slashes
@ -254,6 +283,9 @@ class Blueprint:
:param handler: function for handling uri requests. Accepts function, :param handler: function for handling uri requests. Accepts function,
or class instance with a view_class method. or class instance with a view_class method.
:param uri: endpoint at which the route will be accessible. :param uri: endpoint at which the route will be accessible.
:param host: IP Address of FQDN for the sanic server to use.
:param version: Blueprint Version
:param name: Unique name to identify the Websocket Route
:return: function or class instance :return: function or class instance
""" """
self.websocket(uri=uri, host=host, version=version, name=name)(handler) self.websocket(uri=uri, host=host, version=version, name=name)(handler)
@ -272,7 +304,14 @@ class Blueprint:
return decorator return decorator
def middleware(self, *args, **kwargs): def middleware(self, *args, **kwargs):
"""Create a blueprint middleware from a decorated function.""" """
Create a blueprint middleware from a decorated function.
:param args: Positional arguments to be used while invoking the
middleware
:param kwargs: optional keyword args that can be used with the
middleware.
"""
def register_middleware(_middleware): def register_middleware(_middleware):
future_middleware = FutureMiddleware(_middleware, args, kwargs) future_middleware = FutureMiddleware(_middleware, args, kwargs)
@ -288,7 +327,17 @@ class Blueprint:
return register_middleware return register_middleware
def exception(self, *args, **kwargs): def exception(self, *args, **kwargs):
"""Create a blueprint exception from a decorated function.""" """
This method enables the process of creating a global exception
handler for the current blueprint under question.
:param args: List of Python exceptions to be caught by the handler
:param kwargs: Additional optional arguments to be passed to the
exception handler
:return a decorated method to handle global exceptions for any
route registered under this blueprint.
"""
def decorator(handler): def decorator(handler):
exception = FutureException(handler, args, kwargs) exception = FutureException(handler, args, kwargs)
@ -319,9 +368,20 @@ class Blueprint:
def get( def get(
self, uri, host=None, strict_slashes=None, version=None, name=None self, uri, host=None, strict_slashes=None, version=None, name=None
): ):
"""
Add an API URL under the **GET** *HTTP* method
:param uri: URL to be tagged to **GET** method of *HTTP*
:param host: Host IP or FQDN for the service to use
:param strict_slashes: Instruct :class:`sanic.app.Sanic` to check if the request
URLs need to terminate with a */*
:param version: API Version
:param name: Unique name that can be used to identify the Route
:return: Object decorated with :func:`route` method
"""
return self.route( return self.route(
uri, uri,
methods=["GET"], methods=frozenset({"GET"}),
host=host, host=host,
strict_slashes=strict_slashes, strict_slashes=strict_slashes,
version=version, version=version,
@ -337,9 +397,20 @@ class Blueprint:
version=None, version=None,
name=None, name=None,
): ):
"""
Add an API URL under the **POST** *HTTP* method
:param uri: URL to be tagged to **POST** method of *HTTP*
:param host: Host IP or FQDN for the service to use
:param strict_slashes: Instruct :class:`sanic.app.Sanic` to check if the request
URLs need to terminate with a */*
:param version: API Version
:param name: Unique name that can be used to identify the Route
:return: Object decorated with :func:`route` method
"""
return self.route( return self.route(
uri, uri,
methods=["POST"], methods=frozenset({"POST"}),
host=host, host=host,
strict_slashes=strict_slashes, strict_slashes=strict_slashes,
stream=stream, stream=stream,
@ -356,9 +427,20 @@ class Blueprint:
version=None, version=None,
name=None, name=None,
): ):
"""
Add an API URL under the **PUT** *HTTP* method
:param uri: URL to be tagged to **PUT** method of *HTTP*
:param host: Host IP or FQDN for the service to use
:param strict_slashes: Instruct :class:`sanic.app.Sanic` to check if the request
URLs need to terminate with a */*
:param version: API Version
:param name: Unique name that can be used to identify the Route
:return: Object decorated with :func:`route` method
"""
return self.route( return self.route(
uri, uri,
methods=["PUT"], methods=frozenset({"PUT"}),
host=host, host=host,
strict_slashes=strict_slashes, strict_slashes=strict_slashes,
stream=stream, stream=stream,
@ -369,9 +451,20 @@ class Blueprint:
def head( def head(
self, uri, host=None, strict_slashes=None, version=None, name=None self, uri, host=None, strict_slashes=None, version=None, name=None
): ):
"""
Add an API URL under the **HEAD** *HTTP* method
:param uri: URL to be tagged to **HEAD** method of *HTTP*
:param host: Host IP or FQDN for the service to use
:param strict_slashes: Instruct :class:`sanic.app.Sanic` to check if the request
URLs need to terminate with a */*
:param version: API Version
:param name: Unique name that can be used to identify the Route
:return: Object decorated with :func:`route` method
"""
return self.route( return self.route(
uri, uri,
methods=["HEAD"], methods=frozenset({"HEAD"}),
host=host, host=host,
strict_slashes=strict_slashes, strict_slashes=strict_slashes,
version=version, version=version,
@ -381,9 +474,20 @@ class Blueprint:
def options( def options(
self, uri, host=None, strict_slashes=None, version=None, name=None self, uri, host=None, strict_slashes=None, version=None, name=None
): ):
"""
Add an API URL under the **OPTIONS** *HTTP* method
:param uri: URL to be tagged to **OPTIONS** method of *HTTP*
:param host: Host IP or FQDN for the service to use
:param strict_slashes: Instruct :class:`sanic.app.Sanic` to check if the request
URLs need to terminate with a */*
:param version: API Version
:param name: Unique name that can be used to identify the Route
:return: Object decorated with :func:`route` method
"""
return self.route( return self.route(
uri, uri,
methods=["OPTIONS"], methods=frozenset({"OPTIONS"}),
host=host, host=host,
strict_slashes=strict_slashes, strict_slashes=strict_slashes,
version=version, version=version,
@ -399,9 +503,20 @@ class Blueprint:
version=None, version=None,
name=None, name=None,
): ):
"""
Add an API URL under the **PATCH** *HTTP* method
:param uri: URL to be tagged to **PATCH** method of *HTTP*
:param host: Host IP or FQDN for the service to use
:param strict_slashes: Instruct :class:`sanic.app.Sanic` to check if the request
URLs need to terminate with a */*
:param version: API Version
:param name: Unique name that can be used to identify the Route
:return: Object decorated with :func:`route` method
"""
return self.route( return self.route(
uri, uri,
methods=["PATCH"], methods=frozenset({"PATCH"}),
host=host, host=host,
strict_slashes=strict_slashes, strict_slashes=strict_slashes,
stream=stream, stream=stream,
@ -412,9 +527,20 @@ class Blueprint:
def delete( def delete(
self, uri, host=None, strict_slashes=None, version=None, name=None self, uri, host=None, strict_slashes=None, version=None, name=None
): ):
"""
Add an API URL under the **DELETE** *HTTP* method
:param uri: URL to be tagged to **DELETE** method of *HTTP*
:param host: Host IP or FQDN for the service to use
:param strict_slashes: Instruct :class:`sanic.app.Sanic` to check if the request
URLs need to terminate with a */*
:param version: API Version
:param name: Unique name that can be used to identify the Route
:return: Object decorated with :func:`route` method
"""
return self.route( return self.route(
uri, uri,
methods=["DELETE"], methods=frozenset({"DELETE"}),
host=host, host=host,
strict_slashes=strict_slashes, strict_slashes=strict_slashes,
version=version, version=version,

View File

@ -106,6 +106,18 @@ class Cookie(dict):
return super().__setitem__(key, value) return super().__setitem__(key, value)
def encode(self, encoding): def encode(self, encoding):
"""
Encode the cookie content in a specific type of encoding instructed
by the developer. Leverages the :func:`str.encode` method provided
by python.
This method can be used to encode and embed ``utf-8`` content into
the cookies.
:param encoding: Encoding to be used with the cookie
:return: Cookie encoded in a codec of choosing.
:except: UnicodeEncodeError
"""
output = ["%s=%s" % (self.key, _quote(self.value))] output = ["%s=%s" % (self.key, _quote(self.value))]
for key, value in self.items(): for key, value in self.items():
if key == "max-age": if key == "max-age":

View File

@ -123,7 +123,7 @@ _sanic_exceptions = {}
def add_status_code(code): def add_status_code(code):
""" """
Decorator used for adding exceptions to _sanic_exceptions. Decorator used for adding exceptions to :class:`SanicException`.
""" """
def class_decorator(cls): def class_decorator(cls):

View File

@ -19,6 +19,17 @@ from sanic.response import html, text
class ErrorHandler: class ErrorHandler:
"""
Provide :class:`sanic.app.Sanic` application with a mechanism to handle
and process any and all uncaught exceptions in a way the application
developer will set fit.
This error handling framework is built into the core that can be extended
by the developers to perform a wide range of tasks from recording the error
stats to reporting them to an external service that can be used for realtime
alerting system.
"""
handlers = None handlers = None
cached_handlers = None cached_handlers = None
_missing = object() _missing = object()
@ -58,9 +69,32 @@ class ErrorHandler:
) )
def add(self, exception, handler): def add(self, exception, handler):
"""
Add a new exception handler to an already existing handler object.
:param exception: Type of exception that need to be handled
:param handler: Reference to the method that will handle the exception
:type exception: :class:`sanic.exceptions.SanicException` or :class:`Exception`
:type handler: ``function``
:return: None
"""
self.handlers.append((exception, handler)) self.handlers.append((exception, handler))
def lookup(self, exception): def lookup(self, exception):
"""
Lookup the existing instance of :class:`ErrorHandler` and fetch the
registered handler for a specific type of exception.
This method leverages a dict lookup to speedup the retrieval process.
:param exception: Type of exception
:type exception: :class:`sanic.exceptions.SanicException` or :class:`Exception`
:return: Registered function if found ``None`` otherwise
"""
handler = self.cached_handlers.get(type(exception), self._missing) handler = self.cached_handlers.get(type(exception), self._missing)
if handler is self._missing: if handler is self._missing:
for exception_class, handler in self.handlers: for exception_class, handler in self.handlers:
@ -75,9 +109,14 @@ class ErrorHandler:
"""Fetches and executes an exception handler and returns a response """Fetches and executes an exception handler and returns a response
object object
:param request: Request :param request: Instance of :class:`sanic.request.Request`
:param exception: Exception to handle :param exception: Exception to handle
:return: Response object
:type request: :class:`sanic.request.Request`
:type exception: :class:`sanic.exceptions.SanicException` or :class:`Exception`
:return: Wrap the return value obtained from :func:`default`
or registered handler for that type of exception.
""" """
handler = self.lookup(exception) handler = self.lookup(exception)
response = None response = None
@ -109,6 +148,19 @@ class ErrorHandler:
""" """
def default(self, request, exception): def default(self, request, exception):
"""
Provide a default behavior for the objects of :class:`ErrorHandler`.
If a developer chooses to extent the :class:`ErrorHandler` they can
provide a custom implementation for this method to behave in a way
they see fit.
:param request: Incoming request
:param exception: Exception object
:type request: :class:`sanic.request.Request`
:type exception: :class:`sanic.exceptions.SanicException` or :class:`Exception`
:return:
"""
self.log(format_exc()) self.log(format_exc())
try: try:
url = repr(request.url) url = repr(request.url)
@ -133,7 +185,23 @@ class ErrorHandler:
class ContentRangeHandler: class ContentRangeHandler:
"""Class responsible for parsing request header""" """
A mechanism to parse and process the incoming request headers to
extract the content range information.
:param request: Incoming api request
:param stats: Stats related to the content
:type request: :class:`sanic.request.Request`
:type stats: :class:`posix.stat_result`
:ivar start: Content Range start
:ivar end: Content Range end
:ivar size: Length of the content
:ivar total: Total size identified by the :class:`posix.stat_result`
instance
:ivar ContentRangeHandler.headers: Content range header ``dict``
"""
__slots__ = ("start", "end", "size", "total", "headers") __slots__ = ("start", "end", "size", "total", "headers")