Lucas Simon

Web Developer. lucassrod@gmail.com

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.

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