Série API em Flask - Parte 1 - Introdução, configuração e Hello World
Bem vindo! Vamos começar uma jornada para aprender a criar uma aplicação REST com Python e Flask Framework. No final deste projeto você será capaz de rodar localmente uma API com autenticação JWT.sss
Para entendimento, segue os capítulos que serão abordados.
Capítulo 1: Introdução, configuração e Hello World
Capítulo 2: Organizando as dependências e requerimentos
Capítulo 3: Configurando o pytest e nosso primeiro teste
Capítulo 4: Configurando o Makefile
Capítulo 5: Adicionando o MongoDB
Capítulo 6: Criando e testando o modelo de usuários
Capítulo 7: Criando usuários
Capítulo 8: Listando usuários
Capítulo 9: Buscando usuários
Capítulo 10: Editando um usuário
Capítulo 11: Deletando um usuário
Capítulo 12: Autênticação por JWT
Capítulo 13: Criando um container Docker
Capítulo 14: Arquivos de configuração para Deploy na Digital Ocean
Capítulo 15: Automatizando o processo de deploy com Fabric
Capítulo 16: CI e CD com Jenkins, Python, Flask e Fabric
Capítulo 17: Utilizando o RabbitMQ com Flask e Sendgrid para enviar e-mails de boas vindas e ativar a conta do usuário
O repositório com todo o código fonte esta aqui
Ambiente
O ambiente de desenvolvimento utilizado neste tutorial é baseado em Unix e a versão 3.6 do Python. É bem provável que sua distribuição linux ja tenha essa versão instalada.
Outro ponto a ser considerado antes de continuarmos é recomendado utilizar o virtualenvwrapper para encapsular o ambiente virtual e instalar os pacotes necessários. Clique no link, leia as instruções e faça a instalação.
Prosseguindo vamos criar nosso ambiente com o python 3
$ mkvirtualenv -p /usr/bin/python3 flask-api-users
Instalando o Flask
O próximo passo é instalar o Flask através do repositório público PyPi, apelido de Python Package Index. Para instalar qualquer pacote dentro do ambiente virtual é bem simples, graças, ao facilitador ou comando chamado pip ou pip3
que realiza todo o este árduo trabalho.
Execute o comando abaixo e aguarde:
$ pip3 install flask
Agora vamos criar um diretório e iniciar a configuração de todo o aplicativo:
$ mkdir flask-api-users
$ cd flask-api-users
Configurando a aplicação
Este passo é um pouco longo e requer uma estruturação de pastas para que o projeto fique organizado e de fácil entendimento.
Crie a seguinte estrutura e os arquivos conforme abaixo. Logo mais explicarei em detalhes suas responsabilidades:
$ tree .
.
├── application.py
├── apps
│ └── __init__.py
├── config.py
├── __init__.py
├── README.md
└── setup.py
Vamos começar codificando nosso setup.py
com as informações do projeto. Faça isso utilizando seu editor favorito.
# -*- coding: utf-8 -*-
# Third
from setuptools import find_packages, setup
__version__ = '0.1.0'
__description__ = 'Api Python Flask'
__long_description__ = 'This is an API to Flask Api Users'
__author__ = 'Lucas Simon'
__author_email__ = 'lucassrod@gmail.com'
setup(
name='api',
version=__version__,
author=__author__,
author_email=__author_email__,
packages=find_packages(),
license='MIT',
description=__description__,
long_description=__long_description__,
url='https://github.com/lucassimon/flask-api-users.git',
keywords='API, MongoDB',
include_package_data=True,
zip_safe=False,
classifiers=[
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
'Operating System :: OS Independent',
'Topic :: Software Development',
'Environment :: Web Environment',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'License :: OSI Approved :: MIT License',
],
)
Altere o arquivo config.py
. Ele ira receber os valores setados no ambiente linux através do arquivo .env
que será explicado logo a seguir.
# -*- coding: utf-8 -*-
# Python
from os import getenv
class Config:
SECRET_KEY = getenv('SECRET_KEY') or 'uma string randômica e gigante'
APP_PORT = int(getenv('APP_PORT'))
DEBUG = eval(getenv('DEBUG').title())
class DevelopmentConfig(Config):
FLASK_ENV = 'development'
DEBUG = True
config = {
'development': DevelopmentConfig,
'default': DevelopmentConfig
}
Próximo passo é criar nossa função factory inicializando o flask instalado que será utilizado para as configurações da API, banco de dados, cors e etc. Mas isso será visto no decorrer dessa série, por enquanto faremos o básico para termos nosso hello world. Então, altere o arquivo apps/__init__.py
e escreva o seguinte código.
# -*- coding: utf-8 -*-
from flask import Flask
from config import config
def create_app(config_name):
app = Flask('api-users')
app.config.from_object(config[config_name])
return app
Adicionando váriaveis de ambiente
Uma maneira interessante em colocar dados sensiveis para nossa aplicação como senhas, uri de conexão com banco de dados, serviços de messagerias, api é utilizando as váriaveis de ambiente através do arquivo .env
.
Logo crie esses arquivos na raiz da aplicação:
@ notebook in ~/workspace-python/flask-api-users
$ touch .env-example
$ touch .env
O conteúdo do arquivo .env
deve ser parecido com isto:
$ cat .env
DEBUG=True
APP_PORT=5000
FLASK_APP="application.py"
FLASK_ENV="development"
SECRET_KEY="hard-secret-key"
Também precisamos instalar o pacote python-dotenv para realizar a leitura dessas váriaveis automáticamente no application.py
. Para isso execute pip3 install python-dotenv
.
Nota: É muito importante colocar o arquivo .env
na lista de arquivos ignorados do git. Ninguém vai querer suas senhas expostas em um repositório público não é verdade? Por isso criamos um fake ou um arquivo de exemplo .env-example
que espelha as principais configurações.
$ cat .gitignore
build/
__pycache__/
*.pytest_cache/
local_settings.py
*.py[cod]
*.swp
*.log
.DS_Store
.env
.venv
env/
*.eggs
*.egg-info
.vscode
.idea
.cache/
A aplicação
O arquivo application.py
será nosso ponto de entrada para a aplicação e execução do servidor web.
Edite o arquivo e cole o código abaixo.
# -*- coding: utf-8 -*-
from os import getenv
from os.path import dirname, isfile, join
from dotenv import load_dotenv
# a partir do arquivo atual adicione ao path o arquivo .env
_ENV_FILE = join(dirname(__file__), '.env')
# existindo o arquivo faça a leitura do arquivo através da função load_dotenv
if isfile(_ENV_FILE):
load_dotenv(dotenv_path=_ENV_FILE)
from apps import create_app
# instancia nossa função factory criada anteriormente
app = create_app(getenv('FLASK_ENV') or 'default')
if __name__ == '__main__':
ip = '0.0.0.0'
port = app.config['APP_PORT']
debug = app.config['DEBUG']
# executa o servidor web do flask
app.run(
host=ip, debug=debug, port=port, use_reloader=debug
)
A partir desse momento podemos testar nossa aplicação executando o comando abaixo.
$ python application.py
* Serving Flask app "api-users" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 747-834-523
Ao aparecer essa mensagem como resultado do comando significa que estamos no caminho certo.
Instalando o Restful e nosso Hello World
O Flask-RESTful é uma extensão do Flask e adiciona algumas facilidades para construir uma API Rest.
Execute o comando $ pip3 install flask-restful
no shell.
Agora vamos criar nosso hello world. Crie um arquivo em apps/api.py
e coloque o conteúdo abaixo:
# -*- coding: utf-8 -*-
# Importamos as classes API e Resource
from flask_restful import Api, Resource
# Criamos uma classe que extende de Resource
class Index(Resource):
# Definimos a operação get do protocolo http
def get(self):
# retornamos um simples dicionário que será automáticamente
# retornado em json pelo flask
return {'hello': 'world by apps'}
# Instânciamos a API do FlaskRestful
api = Api()
def configure_api(app):
# adicionamos na rota '/' a sua classe correspondente Index
api.add_resource(Index, '/')
# inicializamos a api com as configurações do flask vinda por parâmetro
api.init_app(app)
Após criar nosso primeiro recurso precisamos que nossa função factory utilize execute a função configure_api
. Edite o arquivo apps/__init__.py
e realize a seguintes alterações:
# -*- coding: utf-8 -*-
from flask import Flask
from config import config
# Realize a importação da função que configura a api
from .api import configure_api
def create_app(config_name):
app = Flask('api-users')
app.config.from_object(config[config_name])
# executa a chamada da função de configuração
configure_api(app)
return app
Conclusão
Após uma longa configuração chegamos ao final deste tutorial e nada melhor do que ver resultados. Então execute a aplicação conforme a seguir:
$ python application.py
* Serving Flask app "api-users" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 747-834-523
Em outro terminal execute o comando para fazer uma requisição em nossa API ;)
$ http -v GET 0.0.0.0:5000
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: 0.0.0.0:5000
User-Agent: HTTPie/0.9.8
HTTP/1.0 200 OK
Content-Length: 33
Content-Type: application/json
Date: Tue, 12 Jun 2018 22:56:57 GMT
Server: Werkzeug/0.14.1 Python/3.6.3
{
"hello": "world by apps"
}
Bonus
Existem diversos clients no unix para fazer requisições http como o curl. Eu particulamente gosto do httpie e o Insomnia
Após essa leitura, um pouco extensa, podemox parar nosso servidor com um Ctrl-C
.
Agradeço, e fico feliz que vocês tenham iniciado essa jornada nesse mundo de API’s. Parabéns por chegar até aqui =)
Próximo artigo: Organizando as dependências e requerimentos