Ir para o conte√ļdo

FastAPI

FastAPI

Framework FastAPI, alta performance, fácil de aprender, fácil de codar, pronto para produção

Test Coverage Package version


Documentação: https://fastapi.tiangolo.com

Código fonte: https://github.com/tiangolo/fastapi


FastAPI √© um moderno e r√°pido (alta performance) framework web para constru√ß√£o de APIs com Python 3.6 ou superior, baseado nos type hints padr√Ķes do Python.

Os recursos chave s√£o:

  • R√°pido: alta performance, equivalente a NodeJS e Go (gra√ßas ao Starlette e Pydantic). Um dos frameworks mais r√°pidos dispon√≠veis.
  • R√°pido para codar: Aumenta a velocidade para desenvolver recursos entre 200% a 300%. *
  • Poucos bugs: Reduz cerca de 40% de erros induzidos por humanos (desenvolvedores). *
  • Intuitivo: Grande suporte a IDEs. Auto-Complete em todos os lugares. Menos tempo debugando.
  • F√°cil: Projetado para ser f√°cil de aprender e usar. Menos tempo lendo documenta√ß√£o.
  • Enxuto: Minimize duplica√ß√£o de c√≥digo. M√ļltiplos recursos para cada declara√ß√£o de par√Ęmetro. Menos bugs.
  • Robusto: Tenha c√≥digo pronto para produ√ß√£o. E com documenta√ß√£o interativa autom√°tica.
  • Baseado em padr√Ķes: Baseado em (e totalmente compat√≠vel com) os padr√Ķes abertos para APIs: OpenAPI (anteriormente conhecido como Swagger) e JSON Schema.

* estimativas baseadas em testes realizados com equipe interna de desenvolvimento, construindo aplica√ß√Ķes em produ√ß√£o.

Gold Sponsors

Other sponsors

Opini√Ķes

"[...] Estou usando FastAPI muito esses dias. [...] Estou na verdade planejando utilizar ele em todos os times de serviços Machine Learning na Microsoft. Alguns deles estão sendo integrados no core do produto Windows e alguns produtos Office."

Kabir Khan - Microsoft (ref)

"Estou extremamente entusiasmado com o FastAPI. √Č t√£o divertido!"

Brian Okken - Python Bytes podcaster (ref)

"Honestamente, o que você construiu parece super sólido e rebuscado. De muitas formas, eu queria que o Hug fosse assim - é realmente inspirador ver alguém que construiu ele."

Timothy Crosley - criador doHug (ref)

"Se voc√™ est√° procurando aprender um framework moderno para construir aplica√ß√Ķes REST, d√™ uma olhada no FastAPI [...] √Č r√°pido, f√°cil de usar e f√°cil de aprender [...]"

"Nós trocamos nossas APIs por FastAPI [...] Acredito que vocês gostarão dele [...]"

Ines Montani - Matthew Honnibal - fundadores da Explosion AI - criadores da spaCy (ref) - (ref)

"N√≥s adotamos a biblioteca FastAPI para criar um servidor REST que possa ser chamado para obter predi√ß√Ķes. [para o Ludwig]"

Piero Molino, Yaroslav Dudin e Sai Sumanth Miryala - Uber (ref)

Typer, o FastAPI das interfaces de linhas de comando

Se você estiver construindo uma aplicação CLI para ser utilizada em um terminal ao invés de uma aplicação web, dê uma olhada no Typer.

Typer √© o irm√£o menor do FastAPI. E seu prop√≥sito √© ser o FastAPI das CLIs. ‚ƮԳŹ ūüöÄ

Requisitos

Python 3.6+

FastAPI est√° nos ombros de gigantes:

Instalação

$ pip install fastapi

---> 100%

Você também precisará de um servidor ASGI para produção, tal como Uvicorn ou Hypercorn.

$ pip install uvicorn[standard]

---> 100%

Exemplo

Crie

  • Crie um arquivo main.py com:
from typing import Optional

from fastapi import FastAPI

app = FastAPI()


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


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
    return {"item_id": item_id, "q": q}

Ou use async def...

Se seu código utiliza async / await, use async def:

from typing import Optional

from fastapi import FastAPI

app = FastAPI()


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


@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Optional[str] = None):
    return {"item_id": item_id, "q": q}

Nota:

Se você não sabe, verifique a seção "In a hurry?" sobre async e await nas docs.

Rode

Rode o servidor com:

$ uvicorn main:app --reload

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [28720]
INFO:     Started server process [28722]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

Sobre o comando uvicorn main:app --reload...

O comando uvicorn main:app se refere a:

  • main: o arquivo main.py (o "m√≥dulo" Python).
  • app: o objeto criado dentro de main.py com a linha app = FastAPI().
  • --reload: faz o servidor recarregar ap√≥s mudan√ßas de c√≥digo. Somente fa√ßa isso para desenvolvimento.

Verifique

Abra seu navegador em http://127.0.0.1:8000/items/5?q=somequery.

Você verá a resposta JSON como:

{"item_id": 5, "q": "somequery"}

Você acabou de criar uma API que:

  • Recebe requisi√ß√Ķes HTTP nas rotas / e /items/{item_id}.
  • Ambas rotas fazem opera√ß√Ķes GET (tamb√©m conhecido como m√©todos HTTP).
  • A rota /items/{item_id} tem um par√Ęmetro de rota item_id que deve ser um int.
  • A rota /items/{item_id} tem um par√Ęmetro query q str opcional.

Documentação Interativa da API

Agora v√° para http://127.0.0.1:8000/docs.

Você verá a documentação automática interativa da API (fornecida por Swagger UI):

Swagger UI

Documentação Alternativa da API

E agora, v√° para http://127.0.0.1:8000/redoc.

Você verá a documentação automática alternativa (fornecida por ReDoc):

ReDoc

Evoluindo o Exemplo

Agora modifique o arquivo main.py para receber um corpo para uma requisição PUT.

Declare o corpo utilizando tipos padrão Python, graças ao Pydantic.

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    price: float
    is_offer: Optional[bool] = None


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


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
    return {"item_id": item_id, "q": q}


@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
    return {"item_name": item.name, "item_id": item_id}

O servidor deverá recarregar automaticamente (porquê você adicionou --reload ao comando uvicorn acima).

Evoluindo a Documentação Interativa da API

Agora v√° para http://127.0.0.1:8000/docs.

  • A documenta√ß√£o interativa da API ser√° automaticamente atualizada, incluindo o novo corpo:

Swagger UI

  • Clique no bot√£o "Try it out", ele permiir√° que voc√™ preencha os par√Ęmetros e interaja diretamente com a API:

Swagger UI interaction

  • Ent√£o clique no bot√£o "Execute", a interface do usu√°rio ir√° se comunicar com a API, enviar os par√Ęmetros, pegar os resultados e mostr√°-los na tela:

Swagger UI interaction

Evoluindo a Documentação Alternativa da API

E agora, v√° para http://127.0.0.1:8000/redoc.

  • A documenta√ß√£o alternativa tamb√©m ir√° refletir o novo par√Ęmetro da query e o corpo:

ReDoc

Recapitulando

Resumindo, voc√™ declara uma vez os tipos dos par√Ęmetros, corpo etc. como par√Ęmetros de fun√ß√£o.

Você faz com tipos padrão do Python moderno.

Você não terá que aprender uma nova sintaxe, métodos ou classes de uma biblioteca específica etc.

Apenas Python 3.6+ padr√£o.

Por exemplo, para um int:

item_id: int

ou para um modelo mais complexo, Item:

item: Item

...e com essa √ļnica declara√ß√£o voc√™ tem:

  • Suporte ao Editor, incluindo:
    • Completa√ß√£o.
    • Verifica√ß√£o de tipos.
  • Valida√ß√£o de dados:
    • Erros autom√°ticos e claros quando o dado √© inv√°lido.
    • Valida√ß√£o at√© para objetos JSON profundamente aninhados.
  • Convers√£o de dados de entrada: vindo da rede para dados e tipos Python. Consegue ler:
    • JSON.
    • Par√Ęmetros de rota.
    • Par√Ęmetros de query .
    • Cookies.
    • Cabe√ßalhos.
    • Formul√°rios.
    • Arquivos.
  • Convers√£o de dados de sa√≠da de tipos e dados Python para dados de rede (como JSON):
    • Converte tipos Python (str, int, float, bool, list etc).
    • Objetos datetime.
    • Objetos UUID.
    • Modelos de Banco de Dados.
    • ...e muito mais.
  • Documenta√ß√£o interativa autom√°tica da API, incluindo 2 alternativas de interface de usu√°rio:
    • Swagger UI.
    • ReDoc.

Voltando ao código do exemplo anterior, FastAPI irá:

  • Validar que existe um item_id na rota para requisi√ß√Ķes GET e PUT.
  • Validar que item_id √© do tipo int para requisi√ß√Ķes GET e PUT.
    • Se n√£o √© validado, o cliente ver√° um √ļtil, claro erro.
  • Verificar se existe um par√Ęmetro de query opcional nomeado como q (como em http://127.0.0.1:8000/items/foo?q=somequery) para requisi√ß√Ķes GET.
    • Como o par√Ęmetro q √© declarado com = None, ele √© opcional.
    • Sem o None ele poderia ser obrigat√≥rio (como o corpo no caso de PUT).
  • Para requisi√ß√Ķes PUT para /items/{item_id}, ler√° o corpo como JSON e:
    • Verifica que tem um atributo obrigat√≥rio name que deve ser str.
    • Verifica que tem um atributo obrigat√≥rio price que deve ser float.
    • Verifica que tem an atributo opcional is_offer, que deve ser bool, se presente.
    • Tudo isso tamb√©m funciona para objetos JSON profundamente aninhados.
  • Converter de e para JSON automaticamente.
  • Documentar tudo com OpenAPI, que poder√° ser usado por:
    • Sistemas de documenta√ß√£o interativos.
    • Sistemas de clientes de gera√ß√£o de c√≥digo autom√°ticos, para muitas linguagens.
  • Fornecer diretamente 2 interfaces web de documenta√ß√£o interativa.

Nós arranhamos apenas a superfície, mas você já tem idéia de como tudo funciona.

Experimente mudar a seguinte linha:

    return {"item_name": item.name, "item_id": item_id}

...de:

        ... "item_name": item.name ...

...para:

        ... "item_price": item.price ...

...e veja como seu editor ir√° auto-completar os atributos e saber√° os tipos:

editor support

Para um exemplo mais completo incluindo mais recursos, veja Tutorial - Guia do Usu√°rio.

Alerta de Spoiler: o tutorial - guia do usu√°rio inclui:

  • Declara√ß√£o de par√Ęmetetros de diferentes lugares como: cabe√ßalhos, cookies, campos de formul√°rios e arquivos.
  • Como configurar Limita√ß√Ķes de Valida√ß√£o como maximum_length ou regex.
  • Um poderoso e f√°cil de usar sistema de Inje√ß√£o de Depend√™ncia.
  • Seguran√ßa e autentica√ß√£o, incluindo suporte para OAuth2 com autentica√ß√£o JWT tokens e HTTP Basic.
  • T√©cnicas mais avan√ßadas (mas igualmente f√°ceis) para declara√ß√£o de modelos JSON profundamente aninhados (gra√ßas ao Pydantic).
  • Muitos recursos extras (gra√ßas ao Starlette) como:
    • WebSockets
    • GraphQL
    • testes extrememamente f√°ceis baseados em requests e pytest
    • CORS
    • Cookie Sessions
    • ...e mais.

Performance

Testes de performance da Independent TechEmpower mostram aplica√ß√Ķes FastAPI rodando sob Uvicorn como um dos frameworks Python mais r√°pidos dispon√≠veis, somente atr√°s de Starlette e Uvicorn (utilizados internamente pelo FastAPI). (*)

Para entender mais sobre performance, veja a seção Benchmarks.

Dependências opcionais

Usados por Pydantic:

Usados por Starlette:

  • requests - Necess√°rio se voc√™ quiser utilizar o TestClient.
  • aiofiles - Necess√°rio se voc√™ quiser utilizar o FileResponse ou StaticFiles.
  • jinja2 - Necess√°rio se voc√™ quiser utilizar a configura√ß√£o padr√£o de templates.
  • python-multipart - Necess√°rio se voc√™ quiser suporte com "parsing" de formul√°rio, com request.form().
  • itsdangerous - Necess√°rio para suporte a SessionMiddleware.
  • pyyaml - Necess√°rio para suporte a SchemaGenerator da Starlette (voc√™ provavelmente n√£o precisar√° disso com o FastAPI).
  • graphene - Necess√°rio para suporte a GraphQLApp.
  • ujson - Necess√°rio se voc√™ quer utilizar UJSONResponse.

Usados por FastAPI / Starlette:

  • uvicorn - para o servidor que carrega e serve sua aplica√ß√£o.
  • orjson - Necess√°rio se voc√™ quer utilizar ORJSONResponse.

Você pode instalar todas essas dependências com pip install fastapi[all].

Licença

Esse projeto é licenciado sob os termos da licença MIT.