https://a.storyblok.com/f/270183/50293/80080779d9/flask-vs-fastapi_1200x600.png

O confronto definitivo: Flask x FastAPI

Publicado em July 30, 2021

Tempo de leitura: 8 minutos

Escolher uma estrutura não é fácil, e é por isso que estou aqui para ajudar você a se livrar dessa dor de cabeça.

Por que deveríamos sequer comparar o Flask e FastAPI?

Elas são semelhantes. Ambas são microframeworks de Python simplificados, sem recursos supérfluos, o que significa maior agilidade no desenvolvimento e mais flexibilidade. Além disso, ambas são utilizadas para criar APIs e Applications web.

Elas também são diferentes. O Flask já foi mais testado na prática e, por isso, é um pouco mais confiável, além de ser amplamente utilizado. O FastAPI é um framework mais novo e moderno, conhecido por sua velocidade e que oferece diversos recursos integrados, como o Pydantic e o SwaggerUI.

Agora que você já entende melhor cada framework, vamos começar a comparação!

Instalação

Às vezes, a parte mais difícil de aprender algo novo é, na verdade, dar o primeiro passo. É por isso que vamos começar pela instalação.

É relativamente simples instalar tanto o Flask quanto o FastAPI usando o instalador preferido do Python, o pip. Também é recomendável instalar ambos dentro de um ambiente virtual, um ambiente isolado para cada um dos seus projetos em Python que elimina erros de conflito.

Frasco

$ pip install flask

FastAPI

$ pip install fastapi uvicorn

Conclusão: Observe que você instala o FastAPI com o Uvicorn. Pense no Uvicorn como um servidor extremamente rápido que permite que suas aplicações tenham um desempenho mais rápido.

Aplicativo “Hello World”

Se você escreveu apenas uma linha de código em toda a sua vida, aposto que foi algo assim:

print(“Hello World”)

É mais ou menos como se você estivesse aprendendo outro idioma, digamos, o mandarim. Existe um sistema chamado Pinyin, que transcreve os caracteres chineses para o inglês para que as pessoas possam pronunciá-los. Ele foi criado para que você comece a usar rapidamente, assim como uma Application “Hello World”.

Vamos ver como é um aplicativo “Hello World” tanto no Flask quanto no FastAPI.

Flask < 2.0

# inside of a Python .py file

from flask import Flask

app = Flask(__name__)

@app.route("/", methods=\[“GET”])
def home():
    return {"Hello": "World"}

if __name__ == "__main__":

    app.run()

Flask 2.0

from flask import Flask

app = Flask(__name__)

@app.get("/")
def home():
    return {"Hello": "World"}

if __name__ == "__main__":

    app.run()

FastAPI

# inside of a Python .py file

import uvicorn

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def home():
    return {"Hello": "World"}

if __name__ == "__main__":

    uvicorn.run("main:app")

Conclusão: Nas versões mais recentes do Flask, você pode usar o @app.get() e @app.post() como atalhos para o roteamento. A forma anterior de usar @app.route() exigia que você passasse seus verbos HTTP para uma lista de métodos, assim: methods=\[“GET”, “POST”].

Observação: o Flask faz uma GET por padrão, portanto, você não precisa especificá-lo na lista de métodos.
Esses métodos também estão disponíveis no FastAPI com suporte às seguintes rotas decoradas para cada método HTTP:

  • @app.get()

  • @app.post()

  • @app.put()

  • @app.delete()

Em execução no ambiente de desenvolvimento

Depois de criar seu aplicativo “Hello World”, é recomendável executá-lo primeiro no ambiente de desenvolvimento — ou localmente no seu computador — antes de colocá-lo em produção para que todo mundo veja. Se o seu aplicativo não funcionar como esperado, as pessoas com certeza vão ficar em pânico. É importante minimizar esse pânico.

Então, no seu terminal, execute estes comandos:

Frasco

$ export FLASK_APP=app.py

$ export FLASK_ENV=development

$ flask run

FastAPI

$ uvicorn main:app --reload

Conclusão: O FastAPI utiliza o Hot Reloading, que mantém o aplicativo em execução enquanto você faz alterações no código. Assim, você não precisa ficar reiniciando o servidor de desenvolvimento. Com o Flask, é necessário um comando adicional no terminal: export FLASK_ENV=development, que permite fazer alterações no código sem reiniciar o servidor de desenvolvimento.

Métodos HTTP

No exemplo “Hello World”, vimos como funciona uma chamada GET no Flask e no FastAPI; agora, vamos examinar mais detalhadamente o método POST.

Flask < 2.0

@app.route("/teams", methods=["POST"])
def create_team():
    team = {

        "team_name": "Phoenix Suns",
        "players": [

            {

                  "name": "Chris Paul",
                  "age": 36

            }

        ]

    }

    teams.append(team)
    return (jsonify(teams))

Flask 2.0

@app.post("/teams")
def create_team():
    team = {

        "team_name": "Phoenix Suns",
        "players": [

            {

                  "name": "Chris Paul",
                  "age": 36

            }

        ]

    }

    teams.append(team)
    return (jsonify(teams))

FastAPI

@app.post("/teams")
def create_team():
    team = {

        "team_name": "Phoenix Suns",
        "players": [

            {

                  "name": "Chris Paul",
                  "age": 36

            }

        ]

    }

    teams.append(team)
    return {'teams':teams}

Conclusão: O Flask 2.0 e o FastAPI parecem muito semelhantes ao se utilizar o método POST. O segredo está em observar como os novos dados são criados.

Com o Flask, você precisará usar uma ferramenta como o Postman atuando como cliente, para poder visualizar suas solicitações POST e os dados que criou no formato JSON.
O FastAPI já vem com o Pydantic e o SwaggerUI integrados, o que permite que você use a documentação automática para interagir com suas solicitações diretamente do navegador, incluindo as solicitações POST.

O Flask também pode utilizar documentação automática, mas você precisará instalá-la usando o flask-swagger. Além disso, há várias configurações necessárias para que ela funcione. Vamos ver como visualizar suas solicitações POST no FastAPI na próxima seção.

Documentação automática

Se você acredita em magia, com certeza vai adorar a Documentação Automática.

O FastAPI é baseado no Pydantic, um framework que facilita a modelagem e a validação de objetos. Ele já vem integrado, portanto, não é necessário instalá-lo. O Pydantic elimina o trabalho de escrever construtores e oferece todos os métodos mágicos. Ele também realiza a validação de dados, exibindo erros de forma mais amigável e utilizando dicas de tipo do Python, reduzindo assim o tempo de depuração. Para acessar sua documentação automática, certifique-se de que seu servidor de desenvolvimento esteja em execução e, em seguida, acesse seu localhost e a porta na qual seu aplicativo está rodando:

http://127.0.0.1:8000/docs

Você verá sua solicitação POST como no exemplo abaixo; caso esteja usando outros métodos HTTP, eles também estarão visíveis.

FastAPI Python automatic documentation POST request using PydanticFastAPI Python automatic documentation POST request using Pydantic

Vamos fazer algo bem mais legal para que possamos ver a beleza da documentação automática. Digamos que tenhamos este código no FastAPI:

FastAPI

from pydantic import BaseModel

app = FastAPI()

class Player(BaseModel):
    player_name: str
    player_team: str
    player_age: int

@app.post("/teams")
def create_team(request: Player):
    return {'teams':request}

Observe que, para usar o Pydantic, é preciso importar o BaseModel que a Player classe irá herdar. Também estamos declarando variáveis com dicas de tipo dentro da nossa classe e retornando um dicionário em nossa solicitação POST.

Ao acessar sua documentação automática, você verá um esquema. Esse esquema é uma estrutura básica para o seu modelo, com variáveis, onde é possível verificar quais campos são obrigatórios e quais são opcionais.

FastAPI Python automatic documentation with Pydantic POST request and schemaFastAPI Python automatic documentation with Pydantic POST request and schema

Você também pode “Experimentar” e testar seu endpoint de API inserindo valores para as variáveis. Aqui, por exemplo, estamos inserindo “Michael Jordan” para a variável player_name do tipo String.

FastAPI Python automatic documentation with Pydantic POST request and request bodyFastAPI Python automatic documentation with Pydantic POST request and request body

Então, quando você clicar em “Executar”, ele exibirá o corpo da resposta. Não há necessidade de usar uma ferramenta adicional como o Postman.

FastAPI Python automatic documentation with Pydantic POST request and response bodyFastAPI Python automatic documentation with Pydantic POST request and response body

Sua documentação interativa também irá gerar um comando curl para você, para que não precise escrevê-lo do zero:

FastAPI Python automatic documentation with Pydantic POST request and CurlFastAPI Python automatic documentation with Pydantic POST request and Curl

Conclusão: Como a documentação automática já vem integrada ao FastAPI, juntamente com o Pydantic e o Swagger UI, esses recursos certamente agilizarão seu tempo de desenvolvimento. Você não precisa instalar nenhuma ferramenta externa para testar suas solicitações.

Validação de dados

Como nosso querido amigo Pydantic já vem com o FastAPI na instalação, ele exibirá mensagens de erro bem intuitivas quando você se deparar com problemas no seu código.

FastAPI

from pydantic import BaseModel

from typing import Optional

class Login(BaseModel):
    username: str
    password: str
    agree_to_terms: Optional\[bool]

@app.post("/login")
def login(request: Login):
    if request.username == "janedoe" and   request.password == "password12345":
        return {"message": "Success"}
    return {"message": "Authentication Failed"}

Aqui, estamos criando uma classe chamada `Login` que herda da `BaseModel` do Pydantic e contém variáveis com indicação de tipo. Primeiro, verificamos se o username é janedoe e se a password é passworld12345, e então retornamos uma mensagem de sucesso ou de falha, conforme o caso.

Passamos para a documentação automática e testamos o corpo da nossa solicitação, passando None para o nome de usuário:

FastAPI Python automatic documentation with Pydantic POST request and change request bodyFastAPI Python automatic documentation with Pydantic POST request and change request body

O Pydantic fará sua mágica, e você receberá uma mensagem amigável informando exatamente qual é o erro. Nesse caso, ele retorna o erro Expecting Value, o que está totalmente correto, pois passamos None para o username.

FastAPI Python automatic documentation with Pydantic error messageFastAPI Python automatic documentation with Pydantic error message

Conclusão: O Flask não possui suporte interno para validação de dados. Você pode usar o poderoso pacote Pydantic para validação de dados, instalando-o com Flask-Pydantic.

Parâmetros de URL ou caminho

Um parâmetro de caminho ou de URL busca um único item. Digamos que queiramos obter um único jogador. O jogador cujo ID corresponder ao que passarmos na URL será retornado ao usuário.

Digamos que tenhamos uma lista de dicionários e queiramos obter um jogador deste arquivo JSON:

players = [

    {

        "player_id": 1,
        "name": "Giannis"

    },

    {

        "player_id": 2,
        "name": "Luka"

    }

]

Frasco

@app.get('/players/<int:player_id>')

def get_player_details(player_id):
    for player in players:
        if player["player_id"] == player_id:
            return jsonify(player)

Aqui, passamos em nossa rota para o localhost na porta 5000 com um ID igual a 2 e recebemos de volta o player com um ID igual a 2.

Flask Python url or path parameters running on localhost returning JSON as response bodyFlask Python url or path parameters running on localhost returning JSON as response body

FastAPI

@app.get("/player/{player_id}")

def get_player_details(player_id: int):
    for player in players:
        if player['player_id'] == player_id:
            return {'player':player['name']}

Aqui, passamos em nossa rota para o localhost na porta 8000 com um ID igual a 1 e recebemos de volta o player com um ID igual a 1.

FastAPI Python url or path parameters running on localhost returning JSON as response bodyFastAPI Python url or path parameters running on localhost returning JSON as response body

Conclusão: Com o FastAPI, como ele usa a indicação de tipos do Python, é possível portar seu código para outras estruturas, como o Django. Com o Flask, isso não é possível, pois usamos a indicação de tipos específica da estrutura, e não a do Python.

Pasta de modelos

A pasta “Templates” armazena seus arquivos HTML quando você está desenvolvendo um aplicativo web no Flask ou no FastAPI, e é necessário usar o Jinja para exibir suas variáveis em HTML. O Jinja é um mecanismo de modelagem que permite escrever código semelhante ao Python para exibir HTML.

Frasco

Por padrão, o Flask procura os modelos na pasta “templates”. Basta criar uma nessa pasta na sua estrutura de arquivos.

Flask Python templates folder in file structure to render HTML filesFlask Python templates folder in file structure to render HTML files

Flask Python templates folder in file structure to render HTML filesFlask Python templates folder in file structure to render HTML files

Então, você pode usar o Jinja para exibir suas variáveis, colocando-as entre chaves duplas:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Players</title>

</head>

<body>

    <h1>Display Players</h1>

    {{ player.name }}

    {{ player.jersey_number }}

</body>

</html>

Conclusão: O Jijnja já vem junto com o Flask na instalação, o que é uma grande vantagem. No FastAPI, é preciso instalar o Jinja e definir a pasta de modelos no seu código.

Servidor de produção

Em algum momento, você vai querer colocar seu aplicativo em operação e mostrá-lo ao mundo.

Frasco

O Flask utiliza um servidor web chamado WSGI, sigla para Web Server Gateway Interface, que vem sendo o padrão do Python há muitos anos. A desvantagem é que ele é síncrono. Isso significa que, se você tiver várias solicitações, elas terão que esperar na fila até que a processamento seja concluído.

FastAPI

O FastAPI usa um servidor web chamado ASGI (Asynchronous Server Gateway Interface), que é extremamente rápido porque é — bem, você adivinhou — assíncrono. Portanto, se você tiver várias solicitações chegando, elas não precisam esperar que as outras sejam concluídas para serem processadas.

Conclusão: O ASGI proporciona um desempenho mais rápido em suas aplicações web, pois processa as solicitações de forma assíncrona.

Rufem os tambores, por favor.

O vencedor é... bem, depende.

É assim que você pode escolher.

Uso o Flask se você quiser:

  • Uma estrutura comprovada na prática, já que existe há muito tempo

  • Para desenvolver um protótipo rápido

  • Para desenvolver aplicativos web

Uso FastAPI se você quiser:

  • Velocidade, no que se refere ao tempo de desenvolvimento e ao desempenho

  • Para reduzir o número de bugs e erros no seu código

  • Criar APIs do zero

Ok, então você já viu tanto o Flask quanto o FastAPI em ação. Agora você entende melhor os dois e já decidiu qual deles seria a melhor opção para o seu próximo projeto.

Então, qual framework você escolheu? Envie um tweet para a gente @VonageDev ou @tonyasims.

Compartilhar:

https://a.storyblok.com/f/270183/400x401/df70d85a84/tonya-sims-1.png
Tonya SimsEx-funcionários da Vonage

Tonya é ex-promotora de desenvolvedores Python na Vonage.