Como CRIAR a sua PRIMEIRA API em python
com o FastAPI
Tutorial para você construir a sua primeira API totalmente do zero
Matheus Vasconcellos · Follow
Published in Data Hackers
5 min read · Feb 13, 2022
Share
Fonte: https://github.com/tiangolo/fastapi
Introdução
Python é a linguagem que mais cresce no mundo. E, trabalhar com APIs é algo
fundamental para qualquer desenvolvedor de software. Ao pensarmos em APIs e
Python, temos sempre no topo do lista os frameworks Django e Flask.
Mas, o FastAPI promete entrar para essa lista também, devido à sua velocidade de
processamento e rapidez para codar, ou seja, de sair do “Hello World” até a
construção de uma API.
D ado o potencial desse framework, neste tutorial, vamos construir uma API
totalmente do zero, sendo um guia para iniciantes. Nessa linha,
desenvolveremos o CRUD com os métodos de GET, PUT, POST e DELETE,
aproveitando o máximo da biblioteca.
Para isso, este artigo está dividido da seguinte maneira:
1. Pré-requisitos
2. Hello World do FastAPI
3. Desenvolvimento do CRUD
4. Conclusão
1. Pré-requisitos
Os pré requisitos são: ter o python 3.6 ou superior instalado na sua máquina, assim
como as bibliotecas fastapi e uvicorn. Além disso, é recomendado um ambiente
virtual para o projeto.
Criação do ambiente virtual
Para inicializarmos o ambiente virtual, o primeiro passo é estar na pasta criada para
o projeto e rodar o seguinte código no terminal Linux:
python3 -m venv .venv
source .venv/bin/activate
Instalação das bibliotecas fastapi e uvicorn
Como estamos desenvolvendo uma API inicial e simples, vamos seguir com o
uvicorn como sendo o servidor ASGI, também utilizado na documentação oficial da
linguagem.
pip install fastapi uvicorn
2. Hello World da FastAPI
Para o “Hello World” e toda a nossa API, criamos o arquivo chamado api.py na pasta
root. Nesse novo arquivo, digitamos o seguinte trecho de código:
1 from fastapi import FastAPI
Open
2 in app Sign up Sign In
3 app = FastAPI()
4
Search Medium
5 @app.get("/")
6 def hello_world_root():
7 return {"Hello": "World"}
hello_world_fast_api.py hosted with ❤ by GitHub view raw
No terminal, digitamos o seguinte comando para iniciar o servidor e rodar no seu
browser a FastAPI:
uvicorn api:app --reload
Importante notar o argumento “ — reload”, que é responsável por atualizar o projeto toda
vez que o arquivo api.py é modificado. No caso de desenvolvimento, é extremamente útil,
no entanto, caso você esteja em um ambiente produtivo, essa flag não é recomendada.
Após rodar o comando acima, temos o seguinte retorno no terminal:
E, ao acessar no seu navegador o endereço: http://127.0.0.1:8000/ temos o nosso
hello world dentro de um dicionário.
Ao digitar http://127.0.0.1:8000/docs, a tela apresentada contém todas as rotas
mapeadas. Essa interface gráfica é incrível, e mais a frente, exploraremos ela um
pouco melhor com requisições executadas no “/doc”.
3. Desenvolvimento do CRUD
Ao chegarmos até aqui, já temos todas as dependências, o servidor rodando no
nosso navegador e com o hello world já desenvolvido. Agora, vamos à seção do
CRUD!
Aqui, desenvolvemos com base no cardápio de um café o CRUD. Nesse sentido,
temos os métodos de criação, leitura, atualização e exclusão do item. Os atributos
de cada item são: ID, nome do produto e preço.
Base de dados
Primeiramente, criamos uma base composta por dicionários dentro de uma lista,
com os atributos destacados acima.
1 menu = [
2 { 'id': 1,
3 'name': 'coffee',
4 'price': 2.5
5 },
6 {
7 'id': 2,
8 'name': 'cake',
9 'price': 10
10 },
11 {
12 'id': 3,
13 'name': 'tea',
14 'price': 3.2
15 },
16 {
17 'id': 4,
18 'name': 'croissant',
19 'price': 5.79
20 }
21 ]
menu.py hosted with ❤ by GitHub view raw
GET item
Com a base de dados, desenvolvemos as rotas para buscar a informação (GET),
conforme código a seguir:
1 @app.get('/get-item/{item_id}')
2 def get_item(
3 item_id: int = Path(
4 None,
5 description="Fill with ID of the item you want to view")):
6
7 search = list(filter(lambda x: x["id"] == item_id, menu))
8
9 if search == []:
10 return {'Error': 'Item does not exist'}
11
12 return {'Item': search[0]}
13
14
15 @app.get('/get-by-name')
16 def get_item(name: Optional[str] = None):
17
18 search = list(filter(lambda x: x["name"] == name, menu))
19
20 if search == []:
21 return {'item': 'Does not exist'}
22
23 return {'Item': search[0]}
get_by_id_and_name.py hosted with ❤ by GitHub view raw
Na primeira rota, o item é passado diretamente na url = /get-item/1
Na segunda rota, o item é passado na url como parâmetro = /get-by-name?
name=coffee
Além de realizar a requisição via URL diretamente, conseguimos também através da
interface gráfica demonstrada anteriormente, conforme print abaixo:
Assim, percebemos que, a consulta pode ser realizada tanto na url do seu
navegador quanto pela interface gráfica do “/docs” da URL raiz.
Feito! Fast, método GET “Fast”, como prometido pela lib.
POST, PUT e DELETE item
Os demais métodos POST, PUT e DELETE seguem a lógica de estrutura similar ao
GET. Por conta disso, escrevi todos eles abaixo.
1 @app.get("/")
2 def hello_world_root():
3 return {"Hello": "World"}
4
5
6 @app.get('/get-item/{item_id}')
7 def get_item(
8 item_id: int = Path(
9 None,
10 description="Fill with ID of the item you want to view")):
11
12 search = list(filter(lambda x: x["id"] == item_id, menu))
13
14 if search == []:
15 return {'Error': 'Item does not exist'}
16
17 return {'Item': search[0]}
18
19
20 @app.get('/get-by-name')
21 def get_item(name: Optional[str] = None):
22
23 search = list(filter(lambda x: x["name"] == name, menu))
24
25 if search == []:
26 return {'item': 'Does not exist'}
27
28 return {'Item': search[0]}
29
30
31 @app.get('/list-menu')
32 def list_menu():
33 return {'Menu': menu}
34
35
36 @app.post('/create-item/{item_id}')
37 def create_item(item_id: int, item: Item):
38
39 search = list(filter(lambda x: x["id"] == item_id, menu))
40
41 if search != []:
42 return {'Error': 'Item exists'}
43
44 item = item.dict()
45 item['id'] = item_id
46
47 menu.append(item)
48 return item
48 return item
49
50
51 @app.put('/update-item/{item_id}')
52 def update_item(item_id: int, item: UpdateItem):
53
54 search = list(filter(lambda x: x["id"] == item_id, menu))
55
56 if search == []:
57 return {'Item': 'Does not exist'}
58
59 if item.name is not None:
60 search[0]['name'] = item.name
61
62 if item.price is not None:
63 search[0]['price'] = item.price
64
65 return search
66
67
68 @app.delete('/delete-item/{item_id}')
69 def delete_item(item_id: int):
70 search = list(filter(lambda x: x["id"] == item_id, menu))
71
72 if search == []:
73 return {'Item': 'Does not exist'}
74
75 for i in range(len(menu)):
76 if menu[i]['id'] == item_id:
77 del menu[i]
78 break
79 return {'Message': 'Item deleted successfully'}
Ao salvar o arquivo api.py (com o flag reload), temos a seguinte página em
http://127.0.0.1:8000/docs
Tendo todos esses métodos e funções, construímos a nossa CRUD com o FastAPI
básica. Digo básica, pois além do que já fizemos aqui, ela poderia ainda ter
tratamento de erros e conexão com banco de dados SQL, por exemplo.
BaseModels
Nas funções de criação e atualização de item, temos os seguintes BaseModels, do
código:
1 class Item(BaseModel):
2 name: str
3 price: float
4
5
6 class UpdateItem(BaseModel):
7 name: Optional[str] = None
8 price: Optional[float] = None
base_models_pydantic.py hosted with ❤ by GitHub view raw
Importante explicar esse trecho que está na documentação oficial do FastAPI, trazendo a
recomendação de utilizar o BaseModel para definir o tipo de atributos.
Caso você tenha interesse em se aprofundar e entender mais sobre o pydantic e o
método BaseModels, clique aqui para acessar a documenta.
4. Conclusão
Com poucas linhas de código o framework cumpre o que promete com relação à
agilidade no desenvolvimento. Em referência à velocidade de processamento, não
realizamos nenhum teste, mas temos referências na internet de estudos, como esse,
que embasam isso.
Outro ponto a ser considerado é que ele é adotado por grandes empresas de
tecnologia como Uber, Netflix e Microsoft, tendo recomendações e elogios
encontrados na documentação. No entanto, por ser muito recente a comunidade
ainda é menor do que o Django e Flask.
Falando do projeto de CRUD do cardápio de um café, utilizamos os 4 métodos GET,
PUT, DELETE e POST. Além disso, também introduzimos e aplicamos o BaseModel
do pydantic.
Apesar de falarmos de tudo isso, este artigo é apenas uma introdução do
framework. Como melhoria do projeto, podemos conectar o CRUD com um banco
de dados SQL e adicionar tratamentos de erros, por exemplo.
Por fim, deixo o github do projeto com todo o código aqui. Aproveito a
oportunidade para deixar meus contatos:
LinkedIn: https://www.linkedin.com/in/matheus-lins-vasconcellos/
Github: https://github.com/matheusvclls
Referências:
Documentação FastAPI: https://fastapi.tiangolo.com/
Documentação Pydantic: https://pydantic-docs.helpmanual.io/usage/models/
Fastapi Python API Software Development Backend
Follow
Written by Matheus Vasconcellos
69 Followers · Writer for Data Hackers
I love how the data could be useful and solve problems.
More from Matheus Vasconcellos and Data Hackers
Matheus Vasconcellos in Nerd For Tech
My study guide for AWS Cloud Practitioner Exam