Skip to main content

Sanic Overview

Sanic is an open-source Python web framework that is built on top of uvloop, a fast asynchronous networking library.

It is designed to be lightweight and efficient, making it an excellent choice for developing high-performance web applications. Sanic leverages Python's async and await syntax to handle requests asynchronously, allowing it to handle a large number of concurrent requests with ease.

History

Sanic was first released in 2016 by the Sanic Community. It was inspired by the Flask web framework and was created to address the limitations of Flask in terms of performance and scalability. Sanic quickly gained popularity among developers due to its speed and simplicity, and it has since become one of the most widely used web frameworks in the Python ecosystem.

Features

Sanic comes with a wide range of features that make it a powerful tool for building web applications. Some of the key features of Sanic include:

  1. Asynchronous Request Handling: Sanic utilizes Python's async and await syntax to handle requests asynchronously. This means that multiple requests can be processed concurrently, resulting in improved performance and scalability.

  2. Fast Execution: Sanic is built on top of uvloop, which is a fast asynchronous networking library. This allows Sanic to handle a large number of requests quickly and efficiently.

  3. Routing: Sanic provides a simple and intuitive way to define URL routes and bind them to specific handler functions. This makes it easy to create RESTful APIs and handle different types of HTTP requests.

    from sanic import Sanic
    from sanic.response import text

    app = Sanic()

    @app.route('/')
    async def hello(request):
    return text('Hello, Sanic!')

    if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

    In the above code snippet, we define a route for the root URL ("/") and bind it to the hello handler function. When a request is made to the root URL, the hello function is executed, and it returns the response "Hello, Sanic!".

  4. Middleware Support: Sanic allows you to define middleware functions that can intercept and modify both incoming requests and outgoing responses. This is useful for tasks such as authentication, request logging, error handling, etc.

    from sanic import Sanic
    from sanic.response import text

    app = Sanic()

    async def custom_middleware(request):
    print('Before request')
    response = await request.next()
    print('After response')
    return response

    app.middleware(custom_middleware)

    @app.route('/')
    async def hello(request):
    return text('Hello, Sanic!')

    if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

    In the above example, we define a custom middleware function custom_middleware that prints a message before the request is processed and after the response is sent. The middleware decorator is used to register this middleware function with the Sanic application.

  5. WebSocket Support: Sanic provides built-in support for WebSocket communication, allowing you to easily implement real-time features in your web applications.

    from sanic import Sanic
    from sanic.websocket import WebSocketProtocol

    app = Sanic()

    @app.websocket('/ws')
    async def websocket_handler(request, ws):
    while True:
    message = await ws.recv()
    await ws.send('You said: ' + message)

    if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000, protocol=WebSocketProtocol)

    In the above example, we define a WebSocket route ("/ws") and bind it to the websocket_handler function. The function receives a WebSocket object ws, which can be used to send and receive messages.

  6. Template Rendering: Sanic supports various template engines, such as Jinja2 and Mako, allowing you to generate dynamic HTML pages easily.

    from sanic import Sanic
    from sanic.response import html
    from jinja2 import Template

    app = Sanic()

    @app.route('/')
    async def index(request):
    template = Template('<h1>Hello, {{ name }}!</h1>')
    rendered_template = template.render(name='Sanic')
    return html(rendered_template)

    if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

    In the above code snippet, we define a Jinja2 template that displays a personalized greeting. The template is rendered with the name "Sanic" and returned as an HTML response.

  7. Request Validation: Sanic provides a simple way to validate incoming requests using request parameters, headers, and other attributes.

    from sanic import Sanic
    from sanic.exceptions import InvalidUsage
    from sanic.request import RequestParameters

    app = Sanic()

    @app.route('/')
    async def hello(request):
    name = request.args.get('name')
    if not name:
    raise InvalidUsage('Name is required.')
    return text('Hello, ' + name)

    if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

    In the above example, we validate the request by checking if the name parameter is present. If it is not provided, an exception is raised, and an error message is returned.

Examples

Here are a few examples that demonstrate the usage of Sanic:

  1. Basic Hello World Example:

    from sanic import Sanic
    from sanic.response import text

    app = Sanic()

    @app.route('/')
    async def hello(request):
    return text('Hello, Sanic!')

    if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

    Output:

    Hello, Sanic!
  2. Asynchronous Request Handling:

    from sanic import Sanic
    from sanic.response import text
    import asyncio

    app = Sanic()

    @app.route('/')
    async def hello(request):
    await asyncio.sleep(1) # Simulating some asynchronous task
    return text('Hello, Sanic!')

    if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

    Output:

    Hello, Sanic!
  3. Middleware Example:

    from sanic import Sanic
    from sanic.response import text

    app = Sanic()

    async def custom_middleware(request):
    print('Before request')
    response = await request.next()
    print('After response')
    return response

    app.middleware(custom_middleware)

    @app.route('/')
    async def hello(request):
    return text('Hello, Sanic!')

    if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

    Output:

    Before request
    After response
  4. WebSocket Example:

    from sanic import Sanic
    from sanic.websocket import WebSocketProtocol

    app = Sanic()

    @app.websocket('/ws')
    async def websocket_handler(request, ws):
    while True:
    message = await ws.recv()
    await ws.send('You said: ' + message)

    if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000, protocol=WebSocketProtocol)

    Output:

    You said: Hello
    You said: Sanic

For more information, you can visit the official Sanic website.