Venho aqui para falar de um microframework chamado Flask.
Simples, flexível e poderoso, é capaz de manter desde o projeto mais simples até CMS no estilo Django ou grandes aplicações como em Pylons.
A instalação é também extremamente simples, já que se encontra no PyPI:
bash$ easy_install Flask
Como exemplo vou mostrar uma aplicação ao estilo Flask, registrando as URLs com decorador
route
, mas para aplicações mais complexas sugiro criar um arquivo url_rules.py
que importe o objeto aplicação e use o método add_url_rule
em vez do decorador.Nossa aplicação simples exibirá o conteúdo dos arquivos em
/proc/
dos sistemas Unix (por falta de ideia melhor).Podemos começar importanto os recursos necessários:
from flask import Flask, make_response
Flask
: classe da aplicaçãomake_response
: função capaz de criar um objeto de resposta HTTP
Para a leitura dos arquivos e diretórios vamos precisar do módulo
os
:import os
Vamos agora criar duas funções, uma que retorne a listagem de arquivos para um diretório e outra que retorne o conteúdo de um arquivo:
def list_dir(path):
filelist = os.listdir(path)
filelist.sort()
return '\n'.join(filelist)
def read_file(path):
data = 'NO DATA'
with open(path, 'r') as fd:
data = fd.read()
return data
Agora é possível criar a aplicação:
app = Flask(__name__)
app.debug = True
Podemos então criar uma função que receba o caminho do arquivo/diretório a ser lido e retorne para o navegador.
Caso seja necessário editar os cabeçalhos ou lidar com qualquer peculiaridade do objeto de resposta HTTP, é possível instanciá-lo manualmente. Caso contrário, retornar uma simples string já faz com que ela seja entendida como o conteúdo do objeto.
Se uma tupla for retornada, o primeiro valor será o conteúdo e o segundo o status de retorno.
Sabendo disso, podemos definir a função:
@app.route('/<path:filename>/')
def read_proc(filename):
real_path = os.path.join('/proc', filename)
data = 'NO DATA'
try:
if os.path.isfile(real_path):
data = read_file(real_path)
elif os.path.isdir(real_path):
data = list_dir(real_path)
else:
return 'NOT FOUND', 404
# Criando HTTP response apenas para editar headers
response = make_response(data)
response.headers['Content-Type'] = 'text/plain'
return response
except IOError:
# Você não pode ler este arquivo/diretório!
return 'BAD REQUEST', 400
A rota indica que o argumento filename receberá como parâmetro toda a URL passada (
path:
indica uma string com /
).Para a raiz da aplicação, poderíamos usar as funções
redirect
e url_for
, por exemplo:@app.route('/')
def index():
return redirect(url_for('read_proc', filename='cpuinfo'))
O que redirecionaria para a URL referente à função
read_proc
, passando 'cpuinfo'
como parâmetro, mas faz mais sentido retornar o resultado da função:@app.route('/')
def index():
return read_proc('')
Agora só falta colocar a aplicação para rodar:
if __name__ == '__main__':
app.run(host='0.0.0.0')
Execute o script e acesse no navegador: http://localhost:5000/ – você verá a listagem do diretório
/proc/
.Acesse no navegador: http://localhost:5000/cpuinfo/ e você verá o conteúdo do arquivo
/proc/cpuinfo
.Pretendo em uma próxima oportunidade demonstrar com construir uma estrutura mais complexa usando um arquivo com roteamente em vez de decorador.
Para mais diversão, leia a documentação e fascine-se também com a quantidade de vezes que a expressão «you don’t have to deal with that» se repete.
[]’s
Cacilhας, La Batalema