Browse Source

Merge branch 'master' into fix-duplicate-special-dependency-handling

pull/12406/head
Peter Volf 7 months ago
committed by GitHub
parent
commit
eddfed7ca8
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 3
      docs/en/data/members.yml
  2. 7
      docs/en/docs/release-notes.md
  3. 55
      docs/pt/docs/advanced/response-cookies.md
  4. 414
      docs/pt/docs/deployment.md
  5. 204
      docs/pt/docs/tutorial/body-updates.md

3
docs/en/data/members.yml

@ -11,6 +11,9 @@ members:
- login: svlandeg - login: svlandeg
avatar_url: https://avatars.githubusercontent.com/u/8796347 avatar_url: https://avatars.githubusercontent.com/u/8796347
url: https://github.com/svlandeg url: https://github.com/svlandeg
- login: YuriiMotov
avatar_url: https://avatars.githubusercontent.com/u/109919500
url: https://github.com/YuriiMotov
- login: estebanx64 - login: estebanx64
avatar_url: https://avatars.githubusercontent.com/u/10840422 avatar_url: https://avatars.githubusercontent.com/u/10840422
url: https://github.com/estebanx64 url: https://github.com/estebanx64

7
docs/en/docs/release-notes.md

@ -7,8 +7,15 @@ hide:
## Latest Changes ## Latest Changes
### Translations
* 🌐 Remove Portuguese translation for `docs/pt/docs/deployment.md`. PR [#12427](https://github.com/fastapi/fastapi/pull/12427) by [@ceb10n](https://github.com/ceb10n).
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/body-updates.md`. PR [#12381](https://github.com/fastapi/fastapi/pull/12381) by [@andersonrocha0](https://github.com/andersonrocha0).
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/response-cookies.md`. PR [#12417](https://github.com/fastapi/fastapi/pull/12417) by [@Paulofalcao2002](https://github.com/Paulofalcao2002).
### Internal ### Internal
* 🔧 Update team, include YuriiMotov 🚀. PR [#12453](https://github.com/fastapi/fastapi/pull/12453) by [@tiangolo](https://github.com/tiangolo).
* 👷 Refactor label-approved, make it an internal script instead of an external GitHub Action. PR [#12280](https://github.com/fastapi/fastapi/pull/12280) by [@tiangolo](https://github.com/tiangolo). * 👷 Refactor label-approved, make it an internal script instead of an external GitHub Action. PR [#12280](https://github.com/fastapi/fastapi/pull/12280) by [@tiangolo](https://github.com/tiangolo).
* 👷 Fix smokeshow, checkout files on CI. PR [#12434](https://github.com/fastapi/fastapi/pull/12434) by [@tiangolo](https://github.com/tiangolo). * 👷 Fix smokeshow, checkout files on CI. PR [#12434](https://github.com/fastapi/fastapi/pull/12434) by [@tiangolo](https://github.com/tiangolo).
* 👷 Use uv in CI. PR [#12281](https://github.com/fastapi/fastapi/pull/12281) by [@tiangolo](https://github.com/tiangolo). * 👷 Use uv in CI. PR [#12281](https://github.com/fastapi/fastapi/pull/12281) by [@tiangolo](https://github.com/tiangolo).

55
docs/pt/docs/advanced/response-cookies.md

@ -0,0 +1,55 @@
# Cookies de Resposta
## Usando um parâmetro `Response`
Você pode declarar um parâmetro do tipo `Response` na sua *função de operação de rota*.
E então você pode definir cookies nesse objeto de resposta *temporário*.
```Python hl_lines="1 8-9"
{!../../docs_src/response_cookies/tutorial002.py!}
```
Em seguida, você pode retornar qualquer objeto que precise, como normalmente faria (um `dict`, um modelo de banco de dados, etc).
E se você declarou um `response_model`, ele ainda será usado para filtrar e converter o objeto que você retornou.
**FastAPI** usará essa resposta *temporária* para extrair os cookies (também os cabeçalhos e código de status) e os colocará na resposta final que contém o valor que você retornou, filtrado por qualquer `response_model`.
Você também pode declarar o parâmetro `Response` em dependências e definir cookies (e cabeçalhos) nelas.
## Retornando uma `Response` diretamente
Você também pode criar cookies ao retornar uma `Response` diretamente no seu código.
Para fazer isso, você pode criar uma resposta como descrito em [Retornando uma Resposta Diretamente](response-directly.md){.internal-link target=_blank}.
Então, defina os cookies nela e a retorne:
```Python hl_lines="10-12"
{!../../docs_src/response_cookies/tutorial001.py!}
```
/// tip | Dica
Lembre-se de que se você retornar uma resposta diretamente em vez de usar o parâmetro `Response`, FastAPI a retornará diretamente.
Portanto, você terá que garantir que seus dados sejam do tipo correto. E.g. será compatível com JSON se você estiver retornando um `JSONResponse`.
E também que você não esteja enviando nenhum dado que deveria ter sido filtrado por um `response_model`.
///
### Mais informações
/// note | "Detalhes Técnicos"
Você também poderia usar `from starlette.responses import Response` ou `from starlette.responses import JSONResponse`.
**FastAPI** fornece as mesmas `starlette.responses` em `fastapi.responses` apenas como uma conveniência para você, o desenvolvedor. Mas a maioria das respostas disponíveis vem diretamente do Starlette.
E como o `Response` pode ser usado frequentemente para definir cabeçalhos e cookies, o **FastAPI** também o fornece em `fastapi.Response`.
///
Para ver todos os parâmetros e opções disponíveis, verifique a <a href="https://www.starlette.io/responses/#set-cookie" class="external-link" target="_blank">documentação no Starlette</a>.

414
docs/pt/docs/deployment.md

@ -1,414 +0,0 @@
# Implantação
Implantar uma aplicação **FastAPI** é relativamente fácil.
Existem vários modos de realizar o _deploy_ dependendo de seu caso de uso específico e as ferramentas que você utiliza.
Você verá mais sobre alguns modos de fazer o _deploy_ nas próximas seções.
## Versões do FastAPI
**FastAPI** já está sendo utilizado em produção em muitas aplicações e sistemas. E a cobertura de teste é mantida a 100%. Mas seu desenvolvimento continua andando rapidamente.
Novos recursos são adicionados frequentemente, _bugs_ são corrigidos regularmente, e o código está continuamente melhorando.
É por isso que as versões atuais estão ainda no `0.x.x`, isso reflete que cada versão poderia ter potencialmente alterações que podem quebrar. Isso segue as convenções de <a href="https://semver.org/" class="external-link" target="_blank">Versionamento Semântico</a>.
Você pode criar aplicações para produção com **FastAPI** bem agora (e você provavelmente já faça isso por um tempo), você tem que ter certeza de utilizar uma versão que funcione corretamente com o resto do seu código.
### Anote sua versão `fastapi`
A primeira coisa que você deve fazer é "fixar" a versão do **FastAPI** que está utilizando para a última versão específica que você sabe que funciona corretamente para a sua aplicação.
Por exemplo, vamos dizer que você esteja utilizando a versão `0.45.0` no seu _app_.
Se você usa um arquivo `requirements.txt`, dá para especificar a versão assim:
```txt
fastapi==0.45.0
```
isso significa que você pode usar exatamente a versão `0.45.0`.
Ou você poderia fixar assim:
```txt
fastapi>=0.45.0,<0.46.0
```
o que significa que você pode usar as versões `0.45.0` ou acima, mas menor que `0.46.0`. Por exemplo, a versão `0.45.2` poderia ser aceita.
Se você usa qualquer outra ferramenta para gerenciar suas instalações, como Poetry, Pipenv ou outro, todos terão um modo que você possa usar para definir versões específicas para seus pacotes.
### Versões disponíveis
Você pode ver as versões disponíveis (por exemplo, para verificar qual é a versão atual) nas [Notas de Lançamento](release-notes.md){.internal-link target=_blank}.
### Sobre as versões
Seguindo as convenções do Versionamento Semântico, qualquer versão abaixo de `1.0.0` pode potencialmente adicionar mudanças que quebrem.
FastAPI também segue a convenção que qualquer versão de _"PATCH"_ seja para ajustes de _bugs_ e mudanças que não quebrem a aplicação.
/// tip
O _"PATCH"_ é o último número, por exemplo, em `0.2.3`, a versão do _PATCH_ é `3`.
///
Então, você poderia ser capaz de fixar para uma versão como:
```txt
fastapi>=0.45.0,<0.46.0
```
Mudanças que quebram e novos recursos são adicionados em versões _"MINOR"_.
/// tip
O _"MINOR"_ é o número do meio, por exemplo, em `0.2.3`, a versão _MINOR_ é `2`.
///
### Atualizando as versões FastAPI
Você pode adicionar testes em sua aplicação.
Com o **FastAPI** é muito fácil (graças ao Starlette), verifique a documentação: [Testando](tutorial/testing.md){.internal-link target=_blank}
Após você ter os testes, então você pode fazer o _upgrade_ da versão **FastAPI** para uma mais recente, e ter certeza que todo seu código esteja funcionando corretamente rodando seus testes.
Se tudo estiver funcionando, ou após você fazer as alterações necessárias, e todos seus testes estiverem passando, então você poderá fixar o `fastapi` para a versão mais recente.
### Sobre Starlette
Você não deve fixar a versão do `starlette`.
Versões diferentes do **FastAPI** irão utilizar uma versão mais nova específica do Starlette.
Então, você pode deixar que o **FastAPI** use a versão correta do Starlette.
### Sobre Pydantic
Pydantic inclui os testes para **FastAPI** em seus próprios testes, então novas versões do Pydantic (acima de `1.0.0`) são sempre compatíveis com FastAPI.
Você pode fixar o Pydantic para qualquer versão acima de `1.0.0` e abaixo de `2.0.0` que funcionará.
Por exemplo:
```txt
pydantic>=1.2.0,<2.0.0
```
## Docker
Nessa seção você verá instruções e _links_ para guias de saber como:
* Fazer uma imagem/container da sua aplicação **FastAPI** com máxima performance. Em aproximadamente **5 min**.
* (Opcionalmente) entender o que você, como desenvolvedor, precisa saber sobre HTTPS.
* Inicializar um _cluster_ Docker Swarm Mode com HTTPS automático, mesmo em um simples servidor de $5 dólares/mês. Em aproximadamente **20 min**.
* Gere e implante uma aplicação **FastAPI** completa, usando seu _cluster_ Docker Swarm, com HTTPS etc. Em aproxiamadamente **10 min**.
Você pode usar <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a> para implantação. Ele tem várias vantagens como segurança, replicabilidade, desenvolvimento simplificado etc.
Se você está usando Docker, você pode utilizar a imagem Docker oficial:
### <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>
Essa imagem tem um mecanismo incluído de "auto-ajuste", para que você possa apenas adicionar seu código e ter uma alta performance automaticamente. E sem fazer sacrifícios.
Mas você pode ainda mudar e atualizar todas as configurações com variáveis de ambiente ou arquivos de configuração.
/// tip
Para ver todas as configurações e opções, vá para a página da imagem do Docker: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
///
### Crie um `Dockerfile`
* Vá para o diretório de seu projeto.
* Crie um `Dockerfile` com:
```Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app
```
#### Grandes aplicações
Se você seguiu a seção sobre criação de [Grandes Aplicações com Múltiplos Arquivos](tutorial/bigger-applications.md){.internal-link target=_blank}, seu `Dockerfile` poderia parecer como:
```Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app/app
```
#### Raspberry Pi e outras arquiteturas
Se você estiver rodando Docker em um Raspberry Pi (que possui um processador ARM) ou qualquer outra arquitetura, você pode criar um `Dockerfile` do zero, baseado em uma imagem base Python (que é multi-arquitetural) e utilizar Uvicorn sozinho.
Nesse caso, seu `Dockerfile` poderia parecer assim:
```Dockerfile
FROM python:3.7
RUN pip install fastapi uvicorn
EXPOSE 80
COPY ./app /app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
```
### Crie o código **FastAPI**
* Crie um diretório `app` e entre nele.
* Crie um arquivo `main.py` com:
```Python
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: str = None):
return {"item_id": item_id, "q": q}
```
* Você deve ter uma estrutura de diretórios assim:
```
.
├── app
│ └── main.py
└── Dockerfile
```
### Construa a imagem Docker
* Vá para o diretório do projeto (onde seu `Dockerfile` está, contendo seu diretório `app`.
* Construa sua imagem FastAPI:
<div class="termy">
```console
$ docker build -t myimage .
---> 100%
```
</div>
### Inicie o container Docker
* Rode um container baseado em sua imagem:
<div class="termy">
```console
$ docker run -d --name mycontainer -p 80:80 myimage
```
</div>
Agora você tem um servidor FastAPI otimizado em um container Docker. Auto-ajustado para seu servidor atual (e número de núcleos de CPU).
### Verifique
Você deve ser capaz de verificar na URL de seu container Docker, por exemplo: <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> ou <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (ou equivalente, usando seu _host_ Docker).
Você verá algo como:
```JSON
{"item_id": 5, "q": "somequery"}
```
### API interativa de documetação
Agora você pode ir para <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> ou <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (ou equivalente, usando seu _host_ Docker).
Você verá a API interativa de documentação (fornecida por <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### APIs alternativas de documentação
E você pode também ir para <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> ou <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (ou equivalente, usando seu _host_ Docker).
Você verá a documentação automática alternativa (fornecida por <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## HTTPS
### Sobre HTTPS
É fácil assumir que HTTPS seja algo que esteja apenas "habilitado" ou não.
Mas ele é um pouquinho mais complexo do que isso.
/// tip
Se você está com pressa ou não se importa, continue na próxima seção com instruções passo a passo para configurar tudo.
///
Para aprender o básico de HTTPS, pela perspectiva de um consumidor, verifique <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
Agora, pela perspectiva de um desenvolvedor, aqui estão algumas coisas para se ter em mente enquanto se pensa sobre HTTPS:
* Para HTTPS, o servidor precisa ter "certificados" gerados por terceiros.
* Esses certificados são na verdade adquiridos por terceiros, não "gerados".
* Certificados tem um prazo de uso.
* Eles expiram.
* E então eles precisam ser renovados, adquiridos novamente por terceiros.
* A encriptação da conexão acontece no nível TCP.
* TCP é uma camada abaixo do HTTP.
* Então, o controle de certificado e encriptação é feito antes do HTTP.
* TCP não conhece nada sobre "domínios". Somente sobre endereços IP.
* A informação sobre o domínio requisitado vai nos dados HTTP.
* Os certificados HTTPS "certificam" um certo domínio, mas o protocolo e a encriptação acontecem no nível TCP, antes de saber qual domínio está sendo lidado.
* Por padrão, isso significa que você pode ter somente um certificado HTTPS por endereço IP.
* Não importa quão grande é seu servidor ou quão pequena cada aplicação que você tenha possar ser.
* No entanto, existe uma solução para isso.
* Existe uma extensão para o protocolo TLS (o que controla a encriptação no nível TCP, antes do HTTP) chamada <a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">SNI</abbr></a>.
* Essa extensão SNI permite um único servidor (com um único endereço IP) a ter vários certificados HTTPS e servir múltiplas aplicações/domínios HTTPS.
* Para que isso funcione, um único componente (programa) rodando no servidor, ouvindo no endereço IP público, deve ter todos os certificados HTTPS no servidor.
* Após obter uma conexão segura, o protocolo de comunicação ainda é HTTP.
* O conteúdo está encriptado, mesmo embora ele esteja sendo enviado com o protocolo HTTP.
É uma prática comum ter um servidor HTTP/programa rodando no servidor (a máquina, _host_ etc.) e gerenciar todas as partes HTTP: enviar as requisições HTTP decriptadas para a aplicação HTTP rodando no mesmo servidor (a aplicação **FastAPI**, nesse caso), pega a resposta HTTP da aplicação, encripta utilizando o certificado apropriado e enviando de volta para o cliente usando HTTPS. Esse servidor é frequentemente chamado <a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS _Termination Proxy_</a>.
### Vamos encriptar
Antes de encriptar, esses certificados HTTPS foram vendidos por terceiros de confiança.
O processo para adquirir um desses certificados costumava ser chato, exigia muita papelada e eram bem caros.
Mas então <a href="https://letsencrypt.org/" class="external-link" target="_blank">_Let's Encrypt_</a> foi criado.
É um projeto da Fundação Linux.Ele fornece certificados HTTPS de graça. De um jeito automatizado. Esses certificados utilizam todos os padrões de segurança criptográfica, e tem vida curta (cerca de 3 meses), para que a segurança seja melhor devido ao seu curto período de vida.
Os domínios são seguramente verificados e os certificados são gerados automaticamente. Isso também permite automatizar a renovação desses certificados.
A idéia é automatizar a aquisição e renovação desses certificados, para que você possa ter um HTTPS seguro, grátis, para sempre.
### Traefik
<a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a> é um _proxy_ reverso / _load balancer_ de alta performance. Ele pode fazer o trabalho do _"TLS Termination Proxy"_ (à parte de outros recursos).
Ele tem integração com _Let's Encrypt_. Assim, ele pode controlar todas as partes HTTPS, incluindo a aquisição e renovação de certificados.
Ele também tem integrações com Docker. Assim, você pode declarar seus domínios em cada configuração de aplicação e leitura dessas configurações, gerando os certificados HTTPS e servindo o HTTPS para sua aplicação automaticamente, sem exigir qualquer mudança em sua configuração.
---
Com essas ferramentas e informações, continue com a próxima seção para combinar tudo.
## _Cluster_ de Docker Swarm Mode com Traefik e HTTPS
Você pode ter um _cluster_ de Docker Swarm Mode configurado em minutos (cerca de 20) com o Traefik controlando HTTPS (incluindo aquisição e renovação de certificados).
Utilizando o Docker Swarm Mode, você pode iniciar com um _"cluster"_ de apenas uma máquina (que pode até ser um servidor por 5 dólares / mês) e então você pode aumentar conforme a necessidade adicionando mais servidores.
Para configurar um _cluster_ Docker Swarm Mode com Traefik controlando HTTPS, siga essa orientação:
### <a href="https://medium.com/@tiangolo/docker-swarm-mode-and-traefik-for-a-https-cluster-20328dba6232" class="external-link" target="_blank">Docker Swarm Mode and Traefik for an HTTPS cluster</a>
### Faça o _deploy_ de uma aplicação FastAPI
O jeito mais fácil de configurar tudo pode ser utilizando o [Gerador de Projetos **FastAPI**](project-generation.md){.internal-link target=_blank}.
Ele é designado para ser integrado com esse _cluster_ Docker Swarm com Traefik e HTTPS descrito acima.
Você pode gerar um projeto em cerca de 2 minutos.
O projeto gerado tem instruções para fazer o _deploy_, fazendo isso leva outros 2 minutos.
## Alternativamente, faça o _deploy_ **FastAPI** sem Docker
Você pode fazer o _deploy_ do **FastAPI** diretamente sem o Docker também.
Você apenas precisa instalar um servidor ASGI compatível como:
//// tab | Uvicorn
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>, um servidor ASGI peso leve, construído sobre uvloop e httptools.
<div class="termy">
```console
$ pip install "uvicorn[standard]"
---> 100%
```
</div>
////
//// tab | Hypercorn
* <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, um servidor ASGI também compatível com HTTP/2.
<div class="termy">
```console
$ pip install hypercorn
---> 100%
```
</div>
...ou qualquer outro servidor ASGI.
////
E rode sua applicação do mesmo modo que você tem feito nos tutoriais, mas sem a opção `--reload`, por exemplo:
//// tab | Uvicorn
<div class="termy">
```console
$ uvicorn main:app --host 0.0.0.0 --port 80
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
```
</div>
////
//// tab | Hypercorn
<div class="termy">
```console
$ hypercorn main:app --bind 0.0.0.0:80
Running on 0.0.0.0:8080 over http (CTRL + C to quit)
```
</div>
////
Você deve querer configurar mais algumas ferramentas para ter certeza que ele seja reinicializado automaticamante se ele parar.
Você também deve querer instalar <a href="https://gunicorn.org/" class="external-link" target="_blank">Gunicorn</a> e <a href="https://www.uvicorn.org/#running-with-gunicorn" class="external-link" target="_blank">utilizar ele como um gerenciador para o Uvicorn</a>, ou usar Hypercorn com múltiplos _workers_.
Tenha certeza de ajustar o número de _workers_ etc.
Mas se você estiver fazendo tudo isso, você pode apenas usar uma imagem Docker que fará isso automaticamente.

204
docs/pt/docs/tutorial/body-updates.md

@ -0,0 +1,204 @@
# Corpo - Atualizações
## Atualização de dados existentes com `PUT`
Para atualizar um item, você pode usar a operação <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTP `PUT`</a>.
Você pode usar `jsonable_encoder` para converter os dados de entrada em dados que podem ser armazenados como JSON (por exemplo, com um banco de dados NoSQL). Por exemplo, convertendo `datetime` em `str`.
//// tab | Python 3.10+
```Python hl_lines="28-33"
{!> ../../../docs_src/body_updates/tutorial001_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="30-35"
{!> ../../../docs_src/body_updates/tutorial001_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="30-35"
{!> ../../../docs_src/body_updates/tutorial001.py!}
```
////
`PUT` é usado para receber dados que devem substituir os dados existentes.
### Aviso sobre a substituição
Isso significa que, se você quiser atualizar o item `bar` usando `PUT` com um corpo contendo:
```Python
{
"name": "Barz",
"price": 3,
"description": None,
}
```
Como ele não inclui o atributo já armazenado `"tax": 20.2`, o modelo de entrada assumiria o valor padrão de `"tax": 10.5`.
E os dados seriam salvos com esse "novo" `tax` de `10.5`.
## Atualizações parciais com `PATCH`
Você também pode usar a operação <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTP `PATCH`</a> para *atualizar* parcialmente os dados.
Isso significa que você pode enviar apenas os dados que deseja atualizar, deixando o restante intacto.
/// note | Nota
`PATCH` é menos comumente usado e conhecido do que `PUT`.
E muitas equipes usam apenas `PUT`, mesmo para atualizações parciais.
Você é **livre** para usá-los como preferir, **FastAPI** não impõe restrições.
Mas este guia te dá uma ideia de como eles são destinados a serem usados.
///
### Usando o parâmetro `exclude_unset` do Pydantic
Se você quiser receber atualizações parciais, é muito útil usar o parâmetro `exclude_unset` no método `.model_dump()` do modelo do Pydantic.
Como `item.model_dump(exclude_unset=True)`.
/// info | Informação
No Pydantic v1, o método que era chamado `.dict()` e foi depreciado (mas ainda suportado) no Pydantic v2. Agora, deve-se usar o método `.model_dump()`.
Os exemplos aqui usam `.dict()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_dump()` a partir do Pydantic v2.
///
Isso gera um `dict` com apenas os dados definidos ao criar o modelo `item`, excluindo os valores padrão.
Então, você pode usar isso para gerar um `dict` com apenas os dados definidos (enviados na solicitação), omitindo valores padrão:
//// tab | Python 3.10+
```Python hl_lines="32"
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="34"
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="34"
{!> ../../../docs_src/body_updates/tutorial002.py!}
```
////
### Usando o parâmetro `update` do Pydantic
Agora, você pode criar uma cópia do modelo existente usando `.model_copy()`, e passar o parâmetro `update` com um `dict` contendo os dados para atualizar.
/// info | Informação
No Pydantic v1, o método era chamado `.copy()`, ele foi depreciado (mas ainda suportado) no Pydantic v2, e renomeado para `.model_copy()`.
Os exemplos aqui usam `.copy()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_copy()` com o Pydantic v2.
///
Como `stored_item_model.model_copy(update=update_data)`:
//// tab | Python 3.10+
```Python hl_lines="33"
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="35"
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="35"
{!> ../../../docs_src/body_updates/tutorial002.py!}
```
////
### Recapitulando as atualizações parciais
Resumindo, para aplicar atualizações parciais você pode:
* (Opcionalmente) usar `PATCH` em vez de `PUT`.
* Recuperar os dados armazenados.
* Colocar esses dados em um modelo do Pydantic.
* Gerar um `dict` sem valores padrão a partir do modelo de entrada (usando `exclude_unset`).
* Dessa forma, você pode atualizar apenas os valores definidos pelo usuário, em vez de substituir os valores já armazenados com valores padrão em seu modelo.
* Criar uma cópia do modelo armazenado, atualizando seus atributos com as atualizações parciais recebidas (usando o parâmetro `update`).
* Converter o modelo copiado em algo que possa ser armazenado no seu banco de dados (por exemplo, usando o `jsonable_encoder`).
* Isso é comparável ao uso do método `.model_dump()`, mas garante (e converte) os valores para tipos de dados que possam ser convertidos em JSON, por exemplo, `datetime` para `str`.
* Salvar os dados no seu banco de dados.
* Retornar o modelo atualizado.
//// tab | Python 3.10+
```Python hl_lines="28-35"
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="30-37"
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="30-37"
{!> ../../../docs_src/body_updates/tutorial002.py!}
```
////
/// tip | Dica
Você pode realmente usar essa mesma técnica com uma operação HTTP `PUT`.
Mas o exemplo aqui usa `PATCH` porque foi criado para esses casos de uso.
///
/// note | Nota
Observe que o modelo de entrada ainda é validado.
Portanto, se você quiser receber atualizações parciais que possam omitir todos os atributos, precisará ter um modelo com todos os atributos marcados como opcionais (com valores padrão ou `None`).
Para distinguir os modelos com todos os valores opcionais para **atualizações** e modelos com valores obrigatórios para **criação**, você pode usar as ideias descritas em [Modelos Adicionais](extra-models.md){.internal-link target=_blank}.
///
Loading…
Cancel
Save