Quando executamos o fastapi
pelo comando:
fastapi dev fast_zero/app.py
Estamos iniciando um servidor web de desenvolvimento. Por isso a flag dev
.
Ao executar o comando fastapi dev
, ao fim da mensagem no terminal, vemos:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [893203] using WatchFiles
INFO: Started server process [893207]
INFO: Waiting for application startup.
INFO: Application startup complete.
Embora o FastAPI seja um ótimo framework web, ele não é um "servidor de aplicação". Por baixo dos panos, ele chama o Uvicorn
.
O uvicorn é um servidor de aplicação. Um servidor ASGI.
A responsabilidade dele é fazer a "cola" entre as chamadas de rede e repassar isso para o "código puro". Uma estrutura de alta performance para trabalhar com chamadas de rede.
Você também poderia usar diretamente o uvicorn:
uvicorn fast_zero.app:app
Até esse momento, estamos usando ainda o "loopback", o nosso pc é o cliente e o servidor ao mesmo tempo. O que não é muito prático ainda, pois queremos fazer uma aplicação para diversos clientes.
Saindo do loopback, podemos abrir o servidor do uvicorn
para rede local:
fastapi dev fast_zero/app.py --host 0.0.0.0
Assim, toda a sua rede domestica (ou empresarial) já podem acessar sua aplicação se souberem o ip.
Pode chamar alguém de casa, ou acessar por outro dispositivo
http://seu_ip:8000
>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.connect(("8.8.8.8", 80))
>>> s.getsockname()[0]
'192.168.0.100'
Você também pode usar comandos como
ipconfig
,ip addr
, ...
HTTP, ou Hypertext Transfer Protocol (Protocolo de Transferência de Hipertexto), é o protocolo fundamental na web para a transferência de dados e comunicação entre clientes e servidores. Ele baseia-se no modelo de requisição-resposta: onde o cliente faz uma requisição ao servidor, que responde a essa requisição. Essas requisições e respostas são formatadas conforme as regras do protocolo HTTP.
No contexto do HTTP, tanto requisições quanto respostas são referidas como mensagens. As mensagens HTTP na versão 1 têm uma estrutura textual semelhante ao seguinte exemplo:
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: 127.0.0.1:8000
User-Agent: HTTPie/3.2.2
HTTP/1.1 200 OK
content-length: 24
content-type: application/json
date: Fri, 19 Jan 2024 04:05:50 GMT
server: uvicorn
{
"message": "Olá mundo"
}
O cabeçalho contém metadados sobre a requisição ou resposta:
application/json
indica que o corpo da mensagem está em formato JSON. Ou text/html
, para mensagens que contém HTML.Quando um cliente faz uma requisição HTTP, ele indica sua intenção ao servidor com verbos:
Na nossa aplicação FastAPI, definimos que a função read_root que será executada quando uma requisição GET for feita por um cliente no caminho /:
@app.get('/')
def read_root():
return {'message': 'Olá Mundo!'}
Para mais informações a cerca do status code acesse a documentação do iana
Por padrão, o FastAPI já usa 200 OK
como código de resposta. Mas, podemos dizer isso explicitamente:
@app.get("/", status_code=HTTPStatus.OK)
def read_root():
return {'message': 'Olá Mundo!'}
O terceiro pilar fundamental da web é o HTML, sigla para Hypertext Markup Language.
Trata-se da linguagem de marcação padrão usada para criar e estruturar páginas na internet. Quando acessamos um site, o que vemos em nossos navegadores é o resultado da interpretação do HTML. Esta linguagem utiliza uma série de 'tags' – como <html>
, <head>
, <body>
, <h1>
, <p>
e outras – para definir a estrutura e o conteúdo de uma página web.
Todo o código apresentado neste tópico é apenas um exemplo básico do uso de HTML com FastAPI e não será utilizado no curso. No entanto, é extremamente importante mencionar este tópico.
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
app = FastAPI()
@app.get('/', response_class=HTMLResponse)
def read_root():
return """
<html>
<head>
<title> Nosso olá mundo!</title>
</head>
<body>
<h1> Olá Mundo </h1>
</body>
</html>"""
Embora o HTML seja crucial para a estruturação de páginas web, nosso curso foca em uma perspectiva diferente: a transferência de dados. Enquanto o HTML é usado para apresentar dados visualmente nos navegadores, existe outra camada focada na transferência de informações entre sistemas e servidores.
Aqui entra o conceito de APIs (Application Programming Interfaces), que frequentemente utilizam JSON (JavaScript Object Notation) para a troca de dados. JSON é um formato leve de troca de dados, fácil de ler e escrever para humanos, e simples de interpretar e gerar para máquinas.
As APIs originais, o termo orginal, se refere a HTML como a base das APIs referência
Quando discutimos APIs ""modernas"", nos referimos a APIs que priorizam o tráfego de dados, deixando de lado a camada de apresentação, como o HTML.
O objetivo é transmitir dados de forma agnóstica para diferentes tipos de clientes. Nesse contexto, o JSON (JavaScript Object Notation) se tornou a mídia padrão, graças à sua leveza e facilidade de leitura tanto por humanos quanto por máquinas.
{
"livros": [
{
"titulo": "O apanhador no campo de centeio",
"autor": "J.D. Salinger",
"ano": 1945,
"disponivel": false
},
{
"titulo": "O mestre e a margarida",
"autor": "Mikhail Bulgákov",
"ano": 1966,
"disponivel": true
}
]
}
Quando falamos sobre o compartilhamento de JSON entre cliente e servidor, é crucial estabelecer um entendimento mútuo sobre a estrutura dos dados que serão trocados.
A este entendimento, denominamos schema, que atua como um contrato definindo a forma e o conteúdo dos dados trafegados.
No universo de APIs e contratos de dados, especialmente ao trabalhar com Python, o Pydantic se destaca como uma ferramenta poderosa e versátil. Além de embutida no FastAPI.
A ideia dele é criar uma camada de documentação, via OpenAPI, e de fazer a validação dos modelos de entrada e saída da nossa API.
Vamos criar um novo arquivo em nosso projeto chamado fast_zero/schemas.py
:
from pydantic import BaseModel
class Message(BaseModel):
message: str
Aqui temos a ideia de um json representada em python. Um objeto de chave message
, com um valor do tipo `str.
Ao juntar o pydantic ao modelo de resposta, temos a garantia que a resposta seguirá esse formato e também documentará isso na API.
from http import HTTPStatus
from fastapi import FastAPI
from fast_zero.schemas import Message
app = FastAPI()
@app.get('/', status_code=HTTPStatus.OK, response_model=Message)
def read_root():
return {'message': 'Olá Mundo!'}
Se iniciarmos o nosso servidor task run
e entrarmos nas documentações, podemos ver o efeito:
Crie um novo endpoint em fast_zero/app.py
que retorne "olá mundo" usando HTML e escreva seu teste em tests/test_app.py
. Dica: para capturar a resposta do HTML do cliente de testes, você pode usar response.text
quiz: https://fastapidozero.dunossauro.com/4.0/quizes/aula_02/
git add .
git commit -m "Adicionando schema de mensagem"
git push
mermaid.js