O Tornado é um framework web assíncrono de alta performance escrito em Python. Ele permite que desenvolvedores construam aplicações web escaláveis, flexíveis e com suporte a milhares de conexões simultâneas. Além disso, o Tornado é ideal para aplicações que exigem manipulação de eventos em tempo real, como chats e notificações push.

Neste artigo, vamos explorar os principais recursos do Tornado e como usá-los para construir aplicações web modernas e escaláveis.

Configuração do ambiente de desenvolvimento do Tornado

Antes de começar a trabalhar com o Tornado, é necessário configurar o ambiente de desenvolvimento. Para isso, é necessário instalar o Python e o Tornado usando o gerenciador de pacotes pip. Abra o terminal e execute o seguinte comando:

pip install tornado

Depois de instalar o Tornado, você pode verificar se a instalação foi bem-sucedida importando-o no interpretador Python:

import tornado

Se não ocorrerem erros, a instalação foi bem-sucedida.

Como criar um aplicativo web básico usando o Tornado

Vamos começar criando um aplicativo web básico usando o Tornado. O primeiro passo é importar o módulo tornado.ioloop e criar um objeto IOLoop:

import tornado.ioloop

if __name__ == "__main__":
    tornado.ioloop.IOLoop.current().start()

Em seguida, vamos criar uma classe chamada MainHandler que herda de tornado.web.RequestHandler. Essa classe é responsável por manipular as requisições HTTP feitas para o aplicativo:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Olá, mundo")

if __name__ == "__main__":
    app = tornado.web.Application([(r"/", MainHandler)])
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Nesse exemplo, a classe MainHandler recebe as requisições GET feitas para a rota “/” e responde com a stringOlá, mundo“. O objeto Application é usado para agrupar as rotas do aplicativo e o método listen é usado para iniciar o servidor HTTP na porta 8888.

Trabalhando com rotas e manipuladores em Tornado

O Tornado usa um sistema de rotas para mapear as requisições HTTP para os manipuladores correspondentes. Cada rota é definida usando uma expressão regular que especifica o padrão de URL e um manipulador que processa a requisição. Veja um exemplo:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Olá, mundo")

class AboutHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Sobre nós")

if __name__ == "__main__":
    app = tornado.web.Application([(r"/", MainHandler), (r"/about", AboutHandler)])
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Nesse exemplo, definimos duas rotas: uma para a raiz do aplicativo e outra para a página “Sobre nós“. Ambas as rotas são manipuladas por classes distintas: MainHandler e AboutHandler.

Como integrar bancos de dados com o Tornado

O Tornado oferece suporte a uma variedade de bancos de dados, incluindo MySQL, PostgreSQL, MongoDB e Redis. Para usar um banco de dados em seu aplicativo Tornado, você deve primeiro instalar o driver correspondente usando o pip. Por exemplo, para instalar o driver do MySQL, você pode executar o seguinte comando:

pip install mysql-connector-python

Em seguida, você pode se conectar ao banco de dados e executar consultas SQL usando o módulo tornado.gen. Veja um exemplo:

import tornado.ioloop
import tornado.web
import tornado.gen
import mysql.connector

class MainHandler(tornado.web.RequestHandler):
    @tornado.gen.coroutine
    def get(self):
        conn = mysql.connector.connect(user='root', password='senha', host='127.0.0.1', database='mydatabase')
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM mytable")
        result = cursor.fetchall()
        self.write(str(result))
        conn.close()

if __name__ == "__main__":
    app = tornado.web.Application([(r"/", MainHandler)])
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Nesse exemplo, usamos o módulo tornado.gen para executar a consulta SQL assincronamente. A função coroutine indica que a função get é assíncrona e que pode pausar a execução para esperar a conclusão de operações de entrada/saída.

Autenticação e autorização em Tornado

O Tornado oferece suporte a diferentes esquemas de autenticação, incluindo Basic Auth, Digest Auth, OAuth e JWT. Você pode usar esses esquemas para proteger recursos do aplicativo e controlar o acesso de usuários e serviços externos.

Por exemplo, para usar a autenticação Basic Auth, você pode adicionar um método prepare na classe do manipulador e verificar as credenciais do usuário a cada requisição:

import tornado.ioloop
import tornado.web
import base64

class MainHandler(tornado.web.RequestHandler):
    def prepare(self):
        auth_header = self.request.headers.get('Authorization')
        if auth_header:
            auth_decoded = base64.b64decode(auth_header.split()[1]).decode('utf-8')
            username, password = auth_decoded.split(':')
            if username == 'admin' and password == 'secret':
                return
        self.set_status(401)
        self.set_header('WWW-Authenticate', 'Basic realm=Restricted')

    def get(self):
        self.write("Página protegida")

if __name__ == "__main__":
    app = tornado.web.Application([(r"/", MainHandler)])
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Nesse exemplo, usamos o método prepare para verificar se as credenciais de autenticação estão presentes na requisição. Se as credenciais estiverem corretas, a requisição é processada normalmente. Caso contrário, a resposta HTTP 401 Unauthorized é enviada ao cliente.

Implementando recursos assíncronos com Tornado

O Tornado é conhecido por sua capacidade de suportar operações assíncronas de entrada/saída, o que significa que ele pode lidar com milhares de conexões simultâneas sem bloquear o thread principal. Para aproveitar essa capacidade, é importante usar a função coroutine do Tornado e outras ferramentas de programação assíncrona do Python.

Por exemplo, para lidar com uma solicitação assíncrona de I/O em uma chamada de API, podemos usar o método gen.coroutine e a função yield, como mostra o exemplo abaixo:

import tornado.ioloop
import tornado.web
import tornado.gen
import requests

class AsyncHandler(tornado.web.RequestHandler):
    @tornado.gen.coroutine
    def get(self):
        response = yield tornado.gen.Task(requests.get, 'https://www.example.com')
        self.write(response.text)

if __name__ == "__main__":
    app = tornado.web.Application([(r"/", AsyncHandler)])
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Neste exemplo, a chamada de API é tratada assincronamente, sem bloquear o thread principal, usando a função coroutine e a função yield para esperar a resposta do servidor.

Conclusão

O Tornado é um framework Python leve e de alto desempenho para desenvolvimento de aplicações web, que oferece suporte a programação assíncrona e é amplamente usado em aplicações de grande escala. Ele oferece várias funcionalidades para lidar com operações de entrada/saída assíncronas, além de suportar diferentes esquemas de autenticação e integração com bancos de dados. Com sua arquitetura assíncrona, ele é uma escolha ideal para construir aplicativos escaláveis e de alta performance.

Referências