You can change the behavior of protocol by using custom protocol.
If you want to use custom protocol, you should put subclass of protocol class in the protocol keyword argument of sanic.run()
. The constructor of custom protocol class gets following keyword arguments from Sanic.
-
loop
loop
is an asyncio compatible event loop. -
connections
connections
is aset object
to store protocol objects. When Sanic receivesSIGINT
orSIGTERM
, Sanic executesprotocol.close_if_idle()
for aprotocol objects
stored in connections. -
signal
signal
is asanic.server.Signal object
withstopped attribute
. When Sanic receivesSIGINT
orSIGTERM
,signal.stopped
becomesTrue
. -
request_handler
request_handler
is a coroutine that takes asanic.request.Request
object and aresponse callback
as arguments. -
error_handler
error_handler
is asanic.exceptions.Handler
object. -
request_timeout
request_timeout
is seconds for timeout. -
request_max_size
request_max_size
is bytes of max request size.
By default protocol, an error occurs, if the handler does not return an HTTPResponse object
.
In this example, By rewriting write_response()
, if the handler returns str
, it will be converted to an HTTPResponse object
.
from sanic import Sanic
from sanic.server import HttpProtocol
from sanic.response import text
app = Sanic(__name__)
class CustomHttpProtocol(HttpProtocol):
def __init__(self, *, loop, request_handler, error_handler,
signal, connections, request_timeout, request_max_size):
super().__init__(
loop=loop, request_handler=request_handler,
error_handler=error_handler, signal=signal,
connections=connections, request_timeout=request_timeout,
request_max_size=request_max_size)
def write_response(self, response):
if isinstance(response, str):
response = text(response)
self.transport.write(
response.output(self.request.version)
)
self.transport.close()
@app.route('/')
async def string(request):
return 'string'
@app.route('/1')
async def response(request):
return text('response')
app.run(host='0.0.0.0', port=8000, protocol=CustomHttpProtocol)