Nesse post aprenderemos a criar uma aplicação RESTful API em Python utilizando o framework Flask.
Índice
- Por que criar uma aplicação RESTful API em Python?
- O framework Flask?
- Criando um ambiente virtual
- Estrutura de diretórios
- Instalando a extensão Flask-RESTful
- Exemplo completo
- Resumo
Por que criar uma aplicação RESTful API em Python?
O Python é uma das linguagens mais populares da atualidade, podendo ser utilizada para automatização de tarefas, big data, inteligência artificial, e como veremos nesse artigo, também para a criação de aplicações web.
E como é considerada uma das linguagens de programação mais fáceis de se aprender, acaba sendo o caminho natural para iniciantes que querem entrar no mundo da programação.
O framework Flask?
O Flask é um micro framework para a criação de aplicações web em Python.
E caso queiramos estender as funcionalidades da nossa API, com o framework Flask somos livres para escolher as extensões que mais se adequem ao nosso projeto, adicionando funcionalidades como autenticação, validação de formulários, conexão a banco de dados, entre outras, e o melhor de tudo, todas são totalmente funcionais e de fácil integração.
Criando um ambiente virtual
Recomendamos sempre criar um ambiente virtual para novas aplicações, de forma que as bibliotecas e módulos a serem instalados não interfiram com outras versões já presentes no nosso sistema operativo.
Aqui vai o link para a documentação oficial da linguagem Python, onde você encontrará mais detalhes sobre ambientes virtuais em Python.
No exemplo abaixo estamos criando o diretório venv
para armazenar os arquivos do nosso novo ambiente virtual. É bastante comum chamá-lo venv, do inglês virtual environment.
python3 -m venv venv
Não se esqueça de ativar o novo ambiente virtual com o comando:
source venv/bin/activate
Se tudo funcionou bem, você deveria ver o prefixo (venv) antes do seu nome de usuário no prompt de comandos.
Estrutura de diretórios
Diferentemente de outros frameworks, com Flask você é livre para organizar o código-fonte da forma que melhor atenda às suas necessidades.
Neste artigo dividiremos a nossa aplicação em 3 partes principais: as rotas, os recursos e uma terceira parte para componentes comuns à aplicação.
api
├── __init__.py
├── app.py
├── common
│ ├── __init__.py
│ └── util.py
└── resources
├── __init__.py
└── user.py
Criando a estrutura de diretórios:
mkdir -p api/{resources,common}
Instalando a extensão Flask-RESTful
pip install Flask-RESTful
A extensão Flask-RESTful instala automaticamente o framework Flask.
Para comprovar que o nosso ambiente está funcionando corretamente, criaremos o seguinte arquivo em api/app.py
.
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(HelloWorld, '/')
if __name__ == '__main__':
app.run(debug=True)
Em seguida executamos o seguinte comando, dentro do diretório api, para iniciar a nossa aplicação:
flask --app main run
Se tudo funcionou como o planejado, deveríamos ver algo parecido a:
(venv) fabio@mackbook api % python app.py
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: 114-087-278
E se abrimos uma nova aba no nosso navegador apontando a 127.0.0.1:5000:
Exemplo completo
Com suporte a CRUD (ações de criar, ler, atualizar e deletar).
Arquivo api/app.py
from flask import Flask
from flask_restful import Api
from resources.user import User, UserList
app = Flask(__name__)
api = Api(app)
api.add_resource(UserList, '/users')
api.add_resource(User, '/users/<user_id>')
if __name__ == '__main__':
app.run(debug=True)
Arquivo api/resources/user.py
from flask_restful import abort, request, Resource
USERS = {
'usuario1': {'nome': 'Joao'},
'usuario2': {'nome': 'Maria'},
}
def abort_if_user_doesnt_exist(user_id):
if user_id not in USERS:
abort(404, message="Usuário {} não existe.".format(user_id))
class User(Resource):
def get(self, user_id):
abort_if_user_doesnt_exist(user_id)
return USERS[user_id]
def delete(self, user_id):
abort_if_user_doesnt_exist(user_id)
del USERS[user_id]
return '', 204
def put(self, user_id):
json_data = request.get_json()
USERS[user_id] = json_data
return json_data, 201
class UserList(Resource):
def get(self):
return USERS
def post(self):
json_data = request.get_json()
user_id = int(max(USERS.keys()).lstrip('usuario')) + 1
user_id = 'usuario%i' % user_id
USERS[user_id] = json_data
return USERS[user_id], 201
Executamos novamente a nossa aplicação, e desta vez testaremos todas as ações suportadas.
python api/app.py
Listar todos os usuários:
curl localhost:5000/users
{
"usuario1": {
"nome": "Joao"
},
"usuario2": {
"nome": "Maria"
}
}
Filtrar usuário por id:
curl localhost:5000/users/usuario2
{
"nome": "Maria"
}
Criar usuário:
curl -H 'Content-Type: application/json' -X POST -d '{"nome": "Pedro"}' localhost:5000/users
{
"nome": "Pedro"
}
Atualizar usuário:
curl -H 'Content-Type: application/json' -X PUT -d '{"nome": "Ana"}' localhost:5000/users/usuario2
{
"nome": "Ana"
}
Deletar usuário:
curl -H 'Content-Type: application/json' -X DELETE localhost:5000/users/usuario1
Listamos todos usuários uma vez mais, comprovando que o usuário 1 já não existe na nossa aplicação.
curl localhost:5000/users
{
"usuario2": {
"nome": "Ana"
},
"usuario3": {
"nome": "Pedro"
}
}
Resumo
Com isso finalizamos o nosso artigo sobre como criar uma aplicação RESTful API em Python utilizando o framework Flask.
Deixamos aqui uma lista de extensões e bibliotecas para turbinar a sua nova API:
- Banco de dados: Flask-SQLAlchemy e SQLAlchemy
- Suporte a autenticação baseada em sessão: Flask-Session
- Suporte a autenticação baseada em tokens JWT: Flask-JWT-Extended
- Suporte a envio de emails: Flask-Mail
- Suporte a CORS: Flask-CORS
- Interface de administração em cima de um modelo de dados existente: Flask-Admin
E aqui você encontrará o repositório com o código utilizado nesse artigo.