diff --git a/docs/sanic/examples.rst b/docs/sanic/examples.rst index 965c684f..68c2fccd 100644 --- a/docs/sanic/examples.rst +++ b/docs/sanic/examples.rst @@ -115,5 +115,25 @@ to secure your ``sanic`` api endpoints. .. literalinclude:: ../../examples/authorized_sanic.py +Sanic Websocket +~~~~~~~~~~~~~~~ +``Sanic`` provides an ability to easily add a route and map it to a ``websocket`` handlers. +.. literalinclude:: ../../examples/websocket.html +.. literalinclude:: ../../examples/websocket.py + +vhost Suppport +~~~~~~~~~~~~~~ + +.. literalinclude:: ../../examples/vhosts.py + +Unit Testing With Parallel Test Run Support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following example shows you how to get up and running with unit testing ``sanic`` application with parallel test +execution support provided by the ``pytest-xdist`` plugin. + +.. literalinclude:: ../../examples/pytest_xdist.py + +For more examples and useful samples please visit the `Huge-Sanic's GitHub Page `_ diff --git a/sanic/router.py b/sanic/router.py index 78a90346..6bb3360c 100644 --- a/sanic/router.py +++ b/sanic/router.py @@ -331,6 +331,17 @@ class Router: @staticmethod def check_dynamic_route_exists(pattern, routes_to_check, parameters): + """ + Check if a URL pattern exists in a list of routes provided based on + the comparison of URL pattern and the parameters. + + :param pattern: URL parameter pattern + :param routes_to_check: list of dynamic routes either hashable or + unhashable routes. + :param parameters: List of :class:`Parameter` items + :return: Tuple of index and route if matching route exists else + -1 for index and None for route + """ for ndx, route in enumerate(routes_to_check): if route.pattern == pattern and route.parameters == parameters: return ndx, route diff --git a/sanic/server.py b/sanic/server.py index 70aba8a9..e3879a80 100644 --- a/sanic/server.py +++ b/sanic/server.py @@ -42,6 +42,10 @@ class Signal: class HttpProtocol(asyncio.Protocol): + """ + This class provides a basic HTTP implementation of the sanic framework. + """ + __slots__ = ( # event loop, connection "loop", @@ -144,6 +148,13 @@ class HttpProtocol(asyncio.Protocol): @property def keep_alive(self): + """ + Check if the connection needs to be kept alive based on the params + attached to the `_keep_alive` attribute, :attr:`Signal.stopped` + and :func:`HttpProtocol.parser.should_keep_alive` + + :return: ``True`` if connection is to be kept alive ``False`` else + """ return ( self._keep_alive and not self.signal.stopped @@ -216,8 +227,13 @@ class HttpProtocol(asyncio.Protocol): self.write_error(ServiceUnavailable("Response Timeout")) def keep_alive_timeout_callback(self): - # Check if elapsed time since last response exceeds our configured - # maximum keep alive timeout value + """ + Check if elapsed time since last response exceeds our configured + maximum keep alive timeout value and if so, close the transport + pipe and let the response writer handle the error. + + :return: None + """ time_elapsed = current_time - self._last_response_time if time_elapsed < self.keep_alive_timeout: time_left = self.keep_alive_timeout - time_elapsed @@ -337,6 +353,12 @@ class HttpProtocol(asyncio.Protocol): self.execute_request_handler() def execute_request_handler(self): + """ + Invoke the request handler defined by the + :func:`sanic.app.Sanic.handle_request` method + + :return: None + """ self._response_timeout_handler = self.loop.call_later( self.response_timeout, self.response_timeout_callback ) @@ -351,6 +373,17 @@ class HttpProtocol(asyncio.Protocol): # Responding # -------------------------------------------- # def log_response(self, response): + """ + Helper method provided to enable the logging of responses in case if + the :attr:`HttpProtocol.access_log` is enabled. + + :param response: Response generated for the current request + + :type response: :class:`sanic.response.HTTPResponse` or + :class:`sanic.response.StreamingHTTPResponse` + + :return: None + """ if self.access_log: extra = {"status": getattr(response, "status", 0)} @@ -505,6 +538,20 @@ class HttpProtocol(asyncio.Protocol): logger.debug("Connection lost before server could close it.") def bail_out(self, message, from_error=False): + """ + In case if the transport pipes are closed and the sanic app encounters + an error while writing data to the transport pipe, we log the error + with proper details. + + :param message: Error message to display + :param from_error: If the bail out was invoked while handling an + exception scenario. + + :type message: str + :type from_error: bool + + :return: None + """ if from_error or self.transport.is_closing(): logger.error( "Transport closed @ %s and exception " diff --git a/tests/test_routes.py b/tests/test_routes.py index 6839b285..525dacad 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -22,7 +22,7 @@ def test_versioned_routes_get(app, method): return text('OK') else: print(func) - raise + raise Exception("Method: {} is not callable".format(method)) client_method = getattr(app.test_client, method)