committed by
GitHub
46 changed files with 1263 additions and 499 deletions
@ -0,0 +1,45 @@ |
|||||
|
# Cabeçalhos 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* (assim como você pode fazer para cookies). |
||||
|
|
||||
|
Então você pode definir os cabeçalhos nesse objeto de resposta *temporário*. |
||||
|
|
||||
|
```Python hl_lines="1 7-8" |
||||
|
{!../../docs_src/response_headers/tutorial002.py!} |
||||
|
``` |
||||
|
|
||||
|
Em seguida você pode retornar qualquer objeto que precisar, da maneira que faria normalmente (um `dict`, um modelo de banco de dados, etc.). |
||||
|
|
||||
|
Se você declarou um `response_model`, ele ainda será utilizado para filtrar e converter o objeto que você retornou. |
||||
|
|
||||
|
**FastAPI** usará essa resposta *temporária* para extrair os cabeçalhos (cookies e código de status também) 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 cabeçalhos (e cookies) nelas. |
||||
|
|
||||
|
## Retornar uma `Response` diretamente |
||||
|
|
||||
|
Você também pode adicionar cabeçalhos quando retornar uma `Response` diretamente. |
||||
|
|
||||
|
Crie uma resposta conforme descrito em [Retornar uma resposta diretamente](response-directly.md){.internal-link target=_blank} e passe os cabeçalhos como um parâmetro adicional: |
||||
|
|
||||
|
```Python hl_lines="10-12" |
||||
|
{!../../docs_src/response_headers/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
/// note | "Detalhes técnicos" |
||||
|
|
||||
|
Você também pode usar `from starlette.responses import Response` ou `from starlette.responses import JSONResponse`. |
||||
|
|
||||
|
**FastAPI** fornece as mesmas `starlette.responses` como `fastapi.responses` apenas como uma conveniência para você, desenvolvedor. Mas a maioria das respostas disponíveis vem diretamente do Starlette. |
||||
|
|
||||
|
E como a `Response` pode ser usada frequentemente para definir cabeçalhos e cookies, **FastAPI** também a fornece em `fastapi.Response`. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Cabeçalhos personalizados |
||||
|
|
||||
|
Tenha em mente que cabeçalhos personalizados proprietários podem ser adicionados <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">usando o prefixo 'X-'</a>. |
||||
|
|
||||
|
Porém, se voce tiver cabeçalhos personalizados que deseja que um cliente no navegador possa ver, você precisa adicioná-los às suas configurações de CORS (saiba mais em [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), usando o parâmetro `expose_headers` descrito na <a href="https://www.starlette.io/middleware/#corsmiddleware" class="external-link" target="_blank">documentação de CORS do Starlette</a>. |
@ -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>): |
|
||||
|
|
||||
 |
|
||||
|
|
||||
### 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>): |
|
||||
|
|
||||
 |
|
||||
|
|
||||
## 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. |
|
@ -0,0 +1,205 @@ |
|||||
|
# Recursos Estáticos Personalizados para a UI de Documentação (Hospedagem Própria) |
||||
|
|
||||
|
A documentação da API usa **Swagger UI** e **ReDoc**, e cada um deles precisa de alguns arquivos JavaScript e CSS. |
||||
|
|
||||
|
Por padrão, esses arquivos são fornecidos por um <abbr title="Content Delivery Network: Um serviço, normalmente composto por vários servidores, que fornece arquivos estáticos, como JavaScript e CSS. É comumente usado para providenciar esses arquivos do servidor mais próximo do cliente, melhorando o desempenho.">CDN</abbr>. |
||||
|
|
||||
|
Mas é possível personalizá-los, você pode definir um CDN específico ou providenciar os arquivos você mesmo. |
||||
|
|
||||
|
## CDN Personalizado para JavaScript e CSS |
||||
|
|
||||
|
Vamos supor que você deseja usar um <abbr title="Content Delivery Network">CDN</abbr> diferente, por exemplo, você deseja usar `https://unpkg.com/`. |
||||
|
|
||||
|
Isso pode ser útil se, por exemplo, você mora em um país que restringe algumas URLs. |
||||
|
|
||||
|
### Desativar a documentação automática |
||||
|
|
||||
|
O primeiro passo é desativar a documentação automática, pois por padrão, ela usa o CDN padrão. |
||||
|
|
||||
|
Para desativá-los, defina suas URLs como `None` ao criar seu aplicativo `FastAPI`: |
||||
|
|
||||
|
```Python hl_lines="8" |
||||
|
{!../../docs_src/custom_docs_ui/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
### Incluir a documentação personalizada |
||||
|
|
||||
|
Agora você pode criar as *operações de rota* para a documentação personalizada. |
||||
|
|
||||
|
Você pode reutilizar as funções internas do FastAPI para criar as páginas HTML para a documentação e passar os argumentos necessários: |
||||
|
|
||||
|
* `openapi_url`: a URL onde a página HTML para a documentação pode obter o esquema OpenAPI para a sua API. Você pode usar aqui o atributo `app.openapi_url`. |
||||
|
* `title`: o título da sua API. |
||||
|
* `oauth2_redirect_url`: você pode usar `app.swagger_ui_oauth2_redirect_url` aqui para usar o padrão. |
||||
|
* `swagger_js_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **JavaScript**. Este é o URL do CDN personalizado. |
||||
|
* `swagger_css_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **CSS**. Este é o URL do CDN personalizado. |
||||
|
|
||||
|
E de forma semelhante para o ReDoc... |
||||
|
|
||||
|
```Python hl_lines="2-6 11-19 22-24 27-33" |
||||
|
{!../../docs_src/custom_docs_ui/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
/// tip | Dica |
||||
|
|
||||
|
A *operação de rota* para `swagger_ui_redirect` é um auxiliar para quando você usa OAuth2. |
||||
|
|
||||
|
Se você integrar sua API com um provedor OAuth2, você poderá autenticar e voltar para a documentação da API com as credenciais adquiridas. E interagir com ela usando a autenticação OAuth2 real. |
||||
|
|
||||
|
Swagger UI lidará com isso nos bastidores para você, mas ele precisa desse auxiliar de "redirecionamento". |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Criar uma *operação de rota* para testar |
||||
|
|
||||
|
Agora, para poder testar se tudo funciona, crie uma *operação de rota*: |
||||
|
|
||||
|
```Python hl_lines="36-38" |
||||
|
{!../../docs_src/custom_docs_ui/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
### Teste |
||||
|
|
||||
|
Agora, você deve ser capaz de ir para a documentação em <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, e recarregar a página, ela carregará esses recursos do novo CDN. |
||||
|
|
||||
|
## Hospedagem Própria de JavaScript e CSS para a documentação |
||||
|
|
||||
|
Hospedar o JavaScript e o CSS pode ser útil se, por exemplo, você precisa que seu aplicativo continue funcionando mesmo offline, sem acesso aberto à Internet, ou em uma rede local. |
||||
|
|
||||
|
Aqui você verá como providenciar esses arquivos você mesmo, no mesmo aplicativo FastAPI, e configurar a documentação para usá-los. |
||||
|
|
||||
|
### Estrutura de Arquivos do Projeto |
||||
|
|
||||
|
Vamos supor que a estrutura de arquivos do seu projeto se pareça com isso: |
||||
|
|
||||
|
``` |
||||
|
. |
||||
|
├── app |
||||
|
│ ├── __init__.py |
||||
|
│ ├── main.py |
||||
|
``` |
||||
|
|
||||
|
Agora crie um diretório para armazenar esses arquivos estáticos. |
||||
|
|
||||
|
Sua nova estrutura de arquivos poderia se parecer com isso: |
||||
|
|
||||
|
``` |
||||
|
. |
||||
|
├── app |
||||
|
│ ├── __init__.py |
||||
|
│ ├── main.py |
||||
|
└── static/ |
||||
|
``` |
||||
|
|
||||
|
### Baixe os arquivos |
||||
|
|
||||
|
Baixe os arquivos estáticos necessários para a documentação e coloque-os no diretório `static/`. |
||||
|
|
||||
|
Você provavelmente pode clicar com o botão direito em cada link e selecionar uma opção semelhante a `Salvar link como...`. |
||||
|
|
||||
|
**Swagger UI** usa os arquivos: |
||||
|
|
||||
|
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a> |
||||
|
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a> |
||||
|
|
||||
|
E o **ReDoc** usa os arquivos: |
||||
|
|
||||
|
* <a href="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js" class="external-link" target="_blank">`redoc.standalone.js`</a> |
||||
|
|
||||
|
Depois disso, sua estrutura de arquivos deve se parecer com: |
||||
|
|
||||
|
``` |
||||
|
. |
||||
|
├── app |
||||
|
│ ├── __init__.py |
||||
|
│ ├── main.py |
||||
|
└── static |
||||
|
├── redoc.standalone.js |
||||
|
├── swagger-ui-bundle.js |
||||
|
└── swagger-ui.css |
||||
|
``` |
||||
|
|
||||
|
### Prover os arquivos estáticos |
||||
|
|
||||
|
* Importe `StaticFiles`. |
||||
|
* "Monte" a instância `StaticFiles()` em um caminho específico. |
||||
|
|
||||
|
```Python hl_lines="7 11" |
||||
|
{!../../docs_src/custom_docs_ui/tutorial002.py!} |
||||
|
``` |
||||
|
|
||||
|
### Teste os arquivos estáticos |
||||
|
|
||||
|
Inicialize seu aplicativo e vá para <a href="http://127.0.0.1:8000/static/redoc.standalone.js" class="external-link" target="_blank">http://127.0.0.1:8000/static/redoc.standalone.js</a>. |
||||
|
|
||||
|
Você deverá ver um arquivo JavaScript muito longo para o **ReDoc**. |
||||
|
|
||||
|
Esse arquivo pode começar com algo como: |
||||
|
|
||||
|
```JavaScript |
||||
|
/*! |
||||
|
* ReDoc - OpenAPI/Swagger-generated API Reference Documentation |
||||
|
* ------------------------------------------------------------- |
||||
|
* Version: "2.0.0-rc.18" |
||||
|
* Repo: https://github.com/Redocly/redoc |
||||
|
*/ |
||||
|
!function(e,t){"object"==typeof exports&&"object"==typeof m |
||||
|
|
||||
|
... |
||||
|
``` |
||||
|
|
||||
|
Isso confirma que você está conseguindo fornecer arquivos estáticos do seu aplicativo e que você colocou os arquivos estáticos para a documentação no local correto. |
||||
|
|
||||
|
Agora, podemos configurar o aplicativo para usar esses arquivos estáticos para a documentação. |
||||
|
|
||||
|
### Desativar a documentação automática para arquivos estáticos |
||||
|
|
||||
|
Da mesma forma que ao usar um CDN personalizado, o primeiro passo é desativar a documentação automática, pois ela usa o CDN padrão. |
||||
|
|
||||
|
Para desativá-los, defina suas URLs como `None` ao criar seu aplicativo `FastAPI`: |
||||
|
|
||||
|
```Python hl_lines="9" |
||||
|
{!../../docs_src/custom_docs_ui/tutorial002.py!} |
||||
|
``` |
||||
|
|
||||
|
### Incluir a documentação personalizada para arquivos estáticos |
||||
|
|
||||
|
E da mesma forma que com um CDN personalizado, agora você pode criar as *operações de rota* para a documentação personalizada. |
||||
|
|
||||
|
Novamente, você pode reutilizar as funções internas do FastAPI para criar as páginas HTML para a documentação e passar os argumentos necessários: |
||||
|
|
||||
|
* `openapi_url`: a URL onde a página HTML para a documentação pode obter o esquema OpenAPI para a sua API. Você pode usar aqui o atributo `app.openapi_url`. |
||||
|
* `title`: o título da sua API. |
||||
|
* `oauth2_redirect_url`: Você pode usar `app.swagger_ui_oauth2_redirect_url` aqui para usar o padrão. |
||||
|
* `swagger_js_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **JavaScript**. Este é o URL do CDN personalizado. **Este é o URL que seu aplicativo está fornecendo**. |
||||
|
* `swagger_css_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **CSS**. **Esse é o que seu aplicativo está fornecendo**. |
||||
|
|
||||
|
E de forma semelhante para o ReDoc... |
||||
|
|
||||
|
```Python hl_lines="2-6 14-22 25-27 30-36" |
||||
|
{!../../docs_src/custom_docs_ui/tutorial002.py!} |
||||
|
``` |
||||
|
|
||||
|
/// tip | Dica |
||||
|
|
||||
|
A *operação de rota* para `swagger_ui_redirect` é um auxiliar para quando você usa OAuth2. |
||||
|
|
||||
|
Se você integrar sua API com um provedor OAuth2, você poderá autenticar e voltar para a documentação da API com as credenciais adquiridas. E, então, interagir com ela usando a autenticação OAuth2 real. |
||||
|
|
||||
|
Swagger UI lidará com isso nos bastidores para você, mas ele precisa desse auxiliar de "redirect". |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Criar uma *operação de rota* para testar arquivos estáticos |
||||
|
|
||||
|
Agora, para poder testar se tudo funciona, crie uma *operação de rota*: |
||||
|
|
||||
|
```Python hl_lines="39-41" |
||||
|
{!../../docs_src/custom_docs_ui/tutorial002.py!} |
||||
|
``` |
||||
|
|
||||
|
### Teste a UI de Arquivos Estáticos |
||||
|
|
||||
|
Agora, você deve ser capaz de desconectar o WiFi, ir para a documentação em <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, e recarregar a página. |
||||
|
|
||||
|
E mesmo sem Internet, você será capaz de ver a documentação da sua API e interagir com ela. |
@ -0,0 +1,7 @@ |
|||||
|
# Testando a Base de Dados |
||||
|
|
||||
|
Você pode estudar sobre bases de dados, SQL e SQLModel na <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">documentação de SQLModel</a>. 🤓 |
||||
|
|
||||
|
Aqui tem um mini <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">tutorial de como usar SQLModel com FastAPI</a>. ✨ |
||||
|
|
||||
|
Esse tutorial inclui uma sessão sobre <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/" class="external-link" target="_blank">testar bases de dados SQL</a>. 😎 |
@ -0,0 +1,197 @@ |
|||||
|
# Modelos de Parâmetros de Consulta |
||||
|
|
||||
|
Se você possui um grupo de **parâmetros de consultas** que são relacionados, você pode criar um **modelo Pydantic** para declará-los. |
||||
|
|
||||
|
Isso permitiria que você **reutilizasse o modelo** em **diversos lugares**, e também declarasse validações e metadados de todos os parâmetros de uma única vez. 😎 |
||||
|
|
||||
|
/// note | Nota |
||||
|
|
||||
|
Isso é suportado desde o FastAPI versão `0.115.0`. 🤓 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Parâmetros de Consulta com um Modelo Pydantic |
||||
|
|
||||
|
Declare os **parâmetros de consulta** que você precisa em um **modelo Pydantic**, e então declare o parâmetro como `Query`: |
||||
|
|
||||
|
//// tab | Python 3.10+ |
||||
|
|
||||
|
```Python hl_lines="9-13 17" |
||||
|
{!> ../../docs_src/query_param_models/tutorial001_an_py310.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Python 3.9+ |
||||
|
|
||||
|
```Python hl_lines="8-12 16" |
||||
|
{!> ../../docs_src/query_param_models/tutorial001_an_py39.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Python 3.8+ |
||||
|
|
||||
|
```Python hl_lines="10-14 18" |
||||
|
{!> ../../docs_src/query_param_models/tutorial001_an.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Python 3.10+ non-Annotated |
||||
|
|
||||
|
/// tip | Dica |
||||
|
|
||||
|
Prefira utilizar a versão `Annotated` se possível. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
```Python hl_lines="9-13 17" |
||||
|
{!> ../../docs_src/query_param_models/tutorial001_py310.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Python 3.9+ non-Annotated |
||||
|
|
||||
|
/// tip | Dica |
||||
|
|
||||
|
Prefira utilizar a versão `Annotated` se possível. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
```Python hl_lines="8-12 16" |
||||
|
{!> ../../docs_src/query_param_models/tutorial001_py39.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Python 3.8+ non-Annotated |
||||
|
|
||||
|
/// tip | Dica |
||||
|
|
||||
|
Prefira utilizar a versão `Annotated` se possível. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
```Python hl_lines="9-13 17" |
||||
|
{!> ../../docs_src/query_param_models/tutorial001_py310.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
O **FastAPI** **extrairá** os dados para **cada campo** dos **parâmetros de consulta** presentes na requisição, e fornecerá o modelo Pydantic que você definiu. |
||||
|
|
||||
|
|
||||
|
## Verifique os Documentos |
||||
|
|
||||
|
Você pode ver os parâmetros de consulta nos documentos de IU em `/docs`: |
||||
|
|
||||
|
<div class="screenshot"> |
||||
|
<img src="/img/tutorial/query-param-models/image01.png"> |
||||
|
</div> |
||||
|
|
||||
|
## Restrinja Parâmetros de Consulta Extras |
||||
|
|
||||
|
Em alguns casos especiais (provavelmente não muito comuns), você queira **restrinjir** os parâmetros de consulta que deseja receber. |
||||
|
|
||||
|
Você pode usar a configuração do modelo Pydantic para `forbid` (proibir) qualquer campo `extra`: |
||||
|
|
||||
|
//// tab | Python 3.10+ |
||||
|
|
||||
|
```Python hl_lines="10" |
||||
|
{!> ../../docs_src/query_param_models/tutorial002_an_py310.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Python 3.9+ |
||||
|
|
||||
|
```Python hl_lines="9" |
||||
|
{!> ../../docs_src/query_param_models/tutorial002_an_py39.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Python 3.8+ |
||||
|
|
||||
|
```Python hl_lines="11" |
||||
|
{!> ../../docs_src/query_param_models/tutorial002_an.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Python 3.10+ non-Annotated |
||||
|
|
||||
|
/// tip | Dica |
||||
|
|
||||
|
Prefira utilizar a versão `Annotated` se possível. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
```Python hl_lines="10" |
||||
|
{!> ../../docs_src/query_param_models/tutorial002_py310.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Python 3.9+ non-Annotated |
||||
|
|
||||
|
/// tip | Dica |
||||
|
|
||||
|
Prefira utilizar a versão `Annotated` se possível. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
```Python hl_lines="9" |
||||
|
{!> ../../docs_src/query_param_models/tutorial002_py39.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Python 3.8+ non-Annotated |
||||
|
|
||||
|
/// tip | Dica |
||||
|
|
||||
|
Prefira utilizar a versão `Annotated` se possível. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
```Python hl_lines="11" |
||||
|
{!> ../../docs_src/query_param_models/tutorial002.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Caso um cliente tente enviar alguns dados **extras** nos **parâmetros de consulta**, eles receberão um retorno de **erro**. |
||||
|
|
||||
|
Por exemplo, se o cliente tentar enviar um parâmetro de consulta `tool` com o valor `plumbus`, como: |
||||
|
|
||||
|
```http |
||||
|
https://example.com/items/?limit=10&tool=plumbus |
||||
|
``` |
||||
|
|
||||
|
Eles receberão um retorno de **erro** informando-os que o parâmentro de consulta `tool` não é permitido: |
||||
|
|
||||
|
```json |
||||
|
{ |
||||
|
"detail": [ |
||||
|
{ |
||||
|
"type": "extra_forbidden", |
||||
|
"loc": ["query", "tool"], |
||||
|
"msg": "Extra inputs are not permitted", |
||||
|
"input": "plumbus" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Resumo |
||||
|
|
||||
|
Você pode utilizar **modelos Pydantic** para declarar **parâmetros de consulta** no **FastAPI**. 😎 |
||||
|
|
||||
|
/// tip | Dica |
||||
|
|
||||
|
Alerta de spoiler: você também pode utilizar modelos Pydantic para declarar cookies e cabeçalhos, mas você irá ler sobre isso mais a frente no tutorial. 🤫 |
||||
|
|
||||
|
/// |
@ -0,0 +1,297 @@ |
|||||
|
# Переменные окружения |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Если вы уже знаете, что такое «переменные окружения» и как их использовать, можете пропустить это. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
Переменная окружения (также известная как «**env var**») - это переменная, которая живет **вне** кода Python, в **операционной системе**, и может быть прочитана вашим кодом Python (или другими программами). |
||||
|
|
||||
|
Переменные окружения могут быть полезны для работы с **настройками** приложений, как часть **установки** Python и т.д. |
||||
|
|
||||
|
## Создание и использование переменных окружения |
||||
|
|
||||
|
Можно **создавать** и использовать переменные окружения в **оболочке (терминале)**, не прибегая к помощи Python: |
||||
|
|
||||
|
//// tab | Linux, macOS, Windows Bash |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Вы можете создать переменную окружения MY_NAME с помощью |
||||
|
$ export MY_NAME="Wade Wilson" |
||||
|
|
||||
|
// Затем её можно использовать в других программах, например |
||||
|
$ echo "Hello $MY_NAME" |
||||
|
|
||||
|
Hello Wade Wilson |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Создайте переменную окружения MY_NAME |
||||
|
$ $Env:MY_NAME = "Wade Wilson" |
||||
|
|
||||
|
// Используйте её с другими программами, например |
||||
|
$ echo "Hello $Env:MY_NAME" |
||||
|
|
||||
|
Hello Wade Wilson |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## Чтение переменных окружения в python |
||||
|
|
||||
|
Так же существует возможность создания переменных окружения **вне** Python, в терминале (или любым другим способом), а затем **чтения их в Python**. |
||||
|
|
||||
|
Например, у вас есть файл `main.py`: |
||||
|
|
||||
|
```Python hl_lines="3" |
||||
|
import os |
||||
|
|
||||
|
name = os.getenv("MY_NAME", "World") |
||||
|
print(f"Hello {name} from Python") |
||||
|
``` |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Второй аргумент <a href=«https://docs.python.org/3.8/library/os.html#os.getenv» class=«external-link» target=«_blank»>`os.getenv()`</a> - это возвращаемое по умолчанию значение. |
||||
|
|
||||
|
Если значение не указано, то по умолчанию оно равно `None`. В данном случае мы указываем `«World»` в качестве значения по умолчанию. |
||||
|
/// |
||||
|
|
||||
|
Затем можно запустить эту программу на Python: |
||||
|
|
||||
|
//// tab | Linux, macOS, Windows Bash |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Здесь мы еще не устанавливаем переменную окружения |
||||
|
$ python main.py |
||||
|
|
||||
|
// Поскольку мы не задали переменную окружения, мы получим значение по умолчанию |
||||
|
|
||||
|
Hello World from Python |
||||
|
|
||||
|
// Но если мы сначала создадим переменную окружения |
||||
|
$ export MY_NAME="Wade Wilson" |
||||
|
|
||||
|
// А затем снова запустим программу |
||||
|
$ python main.py |
||||
|
|
||||
|
// Теперь она прочитает переменную окружения |
||||
|
|
||||
|
Hello Wade Wilson from Python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Здесь мы еще не устанавливаем переменную окружения |
||||
|
$ python main.py |
||||
|
|
||||
|
// Поскольку мы не задали переменную окружения, мы получим значение по умолчанию |
||||
|
|
||||
|
Hello World from Python |
||||
|
|
||||
|
// Но если мы сначала создадим переменную окружения |
||||
|
$ $Env:MY_NAME = "Wade Wilson" |
||||
|
|
||||
|
// А затем снова запустим программу |
||||
|
$ python main.py |
||||
|
|
||||
|
// Теперь она может прочитать переменную окружения |
||||
|
|
||||
|
Hello Wade Wilson from Python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Поскольку переменные окружения могут быть установлены вне кода, но могут быть прочитаны кодом, и их не нужно хранить (фиксировать в `git`) вместе с остальными файлами, их принято использовать для конфигураций или **настроек**. |
||||
|
|
||||
|
Вы также можете создать переменную окружения только для **конкретного вызова программы**, которая будет доступна только для этой программы и только на время ее выполнения. |
||||
|
|
||||
|
Для этого создайте её непосредственно перед самой программой, в той же строке: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Создайте переменную окружения MY_NAME в строке для этого вызова программы |
||||
|
$ MY_NAME="Wade Wilson" python main.py |
||||
|
|
||||
|
// Теперь она может прочитать переменную окружения |
||||
|
|
||||
|
Hello Wade Wilson from Python |
||||
|
|
||||
|
// После этого переменная окружения больше не существует |
||||
|
$ python main.py |
||||
|
|
||||
|
Hello World from Python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
Подробнее об этом можно прочитать на сайте <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a>. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Типизация и Валидация |
||||
|
|
||||
|
Эти переменные окружения могут работать только с **текстовыми строками**, поскольку они являются внешними по отношению к Python и должны быть совместимы с другими программами и остальной системой (и даже с различными операционными системами, такими как Linux, Windows, macOS). |
||||
|
|
||||
|
Это означает, что **любое значение**, считанное в Python из переменной окружения, **будет `str`**, и любое преобразование к другому типу или любая проверка должны быть выполнены в коде. |
||||
|
|
||||
|
Подробнее об использовании переменных окружения для работы с **настройками приложения** вы узнаете в [Расширенное руководство пользователя - Настройки и переменные среды](./advanced/settings.md){.internal-link target=_blank}. |
||||
|
|
||||
|
## Переменная окружения `PATH` |
||||
|
|
||||
|
Существует **специальная** переменная окружения **`PATH`**, которая используется операционными системами (Linux, macOS, Windows) для поиска программ для запуска. |
||||
|
|
||||
|
Значение переменной `PATH` - это длинная строка, состоящая из каталогов, разделенных двоеточием `:` в Linux и macOS, и точкой с запятой `;` в Windows. |
||||
|
|
||||
|
Например, переменная окружения `PATH` может выглядеть следующим образом: |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
```plaintext |
||||
|
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin |
||||
|
``` |
||||
|
|
||||
|
Это означает, что система должна искать программы в каталогах: |
||||
|
|
||||
|
* `/usr/local/bin` |
||||
|
* `/usr/bin` |
||||
|
* `/bin` |
||||
|
* `/usr/sbin` |
||||
|
* `/sbin` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
```plaintext |
||||
|
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32 |
||||
|
``` |
||||
|
|
||||
|
Это означает, что система должна искать программы в каталогах: |
||||
|
|
||||
|
* `C:\Program Files\Python312\Scripts` |
||||
|
* `C:\Program Files\Python312` |
||||
|
* `C:\Windows\System32` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Когда вы вводите **команду** в терминале, операционная система **ищет** программу в **каждой из тех директорий**, которые перечислены в переменной окружения `PATH`. |
||||
|
|
||||
|
Например, когда вы вводите `python` в терминале, операционная система ищет программу под названием `python` в **первой директории** в этом списке. |
||||
|
|
||||
|
Если она ее находит, то **использует ее**. В противном случае она продолжает искать в **других каталогах**. |
||||
|
|
||||
|
### Установка Python и обновление `PATH` |
||||
|
|
||||
|
При установке Python вас могут спросить, нужно ли обновить переменную окружения `PATH`. |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
Допустим, вы устанавливаете Python, и он оказывается в каталоге `/opt/custompython/bin`. |
||||
|
|
||||
|
Если вы скажете «да», чтобы обновить переменную окружения `PATH`, то программа установки добавит `/opt/custompython/bin` в переменную окружения `PATH`. |
||||
|
|
||||
|
Это может выглядеть следующим образом: |
||||
|
|
||||
|
```plaintext |
||||
|
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin |
||||
|
``` |
||||
|
|
||||
|
Таким образом, когда вы набираете `python` в терминале, система найдет программу Python в `/opt/custompython/bin` (последний каталог) и использует ее. |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
Допустим, вы устанавливаете Python, и он оказывается в каталоге `C:\opt\custompython\bin`. |
||||
|
|
||||
|
Если вы согласитесь обновить переменную окружения `PATH`, то программа установки добавит `C:\opt\custompython\bin` в переменную окружения `PATH`. |
||||
|
|
||||
|
```plaintext |
||||
|
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin |
||||
|
``` |
||||
|
|
||||
|
Таким образом, когда вы набираете `python` в терминале, система найдет программу Python в `C:\opt\custompython\bin` (последний каталог) и использует ее. |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Итак, если вы напечатаете: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
Система **найдет** программу `python` в `/opt/custompython/bin` и запустит ее. |
||||
|
|
||||
|
Это примерно эквивалентно набору текста: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ /opt/custompython/bin/python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
Система **найдет** программу `python` в каталоге `C:\opt\custompython\bin\python` и запустит ее. |
||||
|
|
||||
|
Это примерно эквивалентно набору текста: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ C:\opt\custompython\bin\python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
Эта информация будет полезна при изучении [Виртуальных окружений](virtual-environments.md){.internal-link target=_blank}. |
||||
|
|
||||
|
## Вывод |
||||
|
|
||||
|
Благодаря этому вы должны иметь базовое представление о том, что такое **переменные окружения** и как использовать их в Python. |
||||
|
|
||||
|
Подробнее о них вы также можете прочитать в <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">статье о переменных окружения на википедии</a>. |
||||
|
|
||||
|
Во многих случаях не всегда очевидно, как переменные окружения могут быть полезны и применимы. Но они постоянно появляются в различных сценариях разработки, поэтому знать о них полезно. |
||||
|
|
||||
|
Например, эта информация понадобится вам в следующем разделе, посвященном [Виртуальным окружениям](virtual-environments.md). |
@ -0,0 +1,3 @@ |
|||||
|
# 關於 FastAPI |
||||
|
|
||||
|
關於 FastAPI、其設計、靈感來源等更多資訊。 🤓 |
@ -0,0 +1,17 @@ |
|||||
|
# 在雲端部署 FastAPI |
||||
|
|
||||
|
你幾乎可以使用 **任何雲端供應商** 來部署你的 FastAPI 應用程式。 |
||||
|
|
||||
|
在大多數情況下,主要的雲端供應商都有部署 FastAPI 的指南。 |
||||
|
|
||||
|
## 雲端供應商 - 贊助商 |
||||
|
|
||||
|
一些雲端供應商 ✨ [**贊助 FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨,這確保了 FastAPI 及其 **生態系統** 持續健康地 **發展**。 |
||||
|
|
||||
|
這也展現了他們對 FastAPI 和其 **社群**(包括你)的真正承諾,他們不僅希望為你提供 **優質的服務**,還希望確保你擁有一個 **良好且健康的框架**:FastAPI。🙇 |
||||
|
|
||||
|
你可能會想嘗試他們的服務,以下有他們的指南: |
||||
|
|
||||
|
* <a href="https://docs.platform.sh/languages/python.html?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023" class="external-link" target="_blank" >Platform.sh</a> |
||||
|
* <a href="https://docs.porter.run/language-specific-guides/fastapi" class="external-link" target="_blank">Porter</a> |
||||
|
* <a href="https://docs.withcoherence.com/" class="external-link" target="_blank">Coherence</a> |
@ -0,0 +1,21 @@ |
|||||
|
# 部署 |
||||
|
|
||||
|
部署 **FastAPI** 應用程式相對容易。 |
||||
|
|
||||
|
## 部署是什麼意思 |
||||
|
|
||||
|
**部署** 應用程式指的是執行一系列必要的步驟,使其能夠 **讓使用者存取和使用**。 |
||||
|
|
||||
|
對於一個 **Web API**,部署通常涉及將其放置在 **遠端伺服器** 上,並使用性能優良且穩定的 **伺服器程式**,確保使用者能夠高效、無中斷地存取應用程式,且不會遇到問題。 |
||||
|
|
||||
|
這與 **開發** 階段形成鮮明對比,在 **開發** 階段,你會不斷更改程式碼、破壞程式碼、修復程式碼,然後停止和重新啟動伺服器等。 |
||||
|
|
||||
|
## 部署策略 |
||||
|
|
||||
|
根據你的使用場景和使用工具,有多種方法可以實現此目的。 |
||||
|
|
||||
|
你可以使用一些工具自行 **部署伺服器**,你也可以使用能為你完成部分工作的 **雲端服務**,或其他可能的選項。 |
||||
|
|
||||
|
我將向你展示在部署 **FastAPI** 應用程式時你可能應該記住的一些主要概念(儘管其中大部分適用於任何其他類型的 Web 應用程式)。 |
||||
|
|
||||
|
在接下來的部分中,你將看到更多需要記住的細節以及一些技巧。 ✨ |
@ -0,0 +1,83 @@ |
|||||
|
# FastAPI CLI |
||||
|
|
||||
|
**FastAPI CLI** 是一個命令列程式,能用來運行你的 FastAPI 應用程式、管理你的 FastAPI 專案等。 |
||||
|
|
||||
|
當你安裝 FastAPI(例如使用 `pip install "fastapi[standard]"`),它會包含一個叫做 `fastapi-cli` 的套件,這個套件提供了 `fastapi` 命令。 |
||||
|
|
||||
|
要運行你的 FastAPI 應用程式來進行開發,你可以使用 `fastapi dev` 命令: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:single">main.py</u> |
||||
|
<font color="#3465A4">INFO </font> Using path <font color="#3465A4">main.py</font> |
||||
|
<font color="#3465A4">INFO </font> Resolved absolute path <font color="#75507B">/home/user/code/awesomeapp/</font><font color="#AD7FA8">main.py</font> |
||||
|
<font color="#3465A4">INFO </font> Searching for package file structure from directories with <font color="#3465A4">__init__.py</font> files |
||||
|
<font color="#3465A4">INFO </font> Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font> |
||||
|
|
||||
|
╭─ <font color="#8AE234"><b>Python module file</b></font> ─╮ |
||||
|
│ │ |
||||
|
│ 🐍 main.py │ |
||||
|
│ │ |
||||
|
╰──────────────────────╯ |
||||
|
|
||||
|
<font color="#3465A4">INFO </font> Importing module <font color="#4E9A06">main</font> |
||||
|
<font color="#3465A4">INFO </font> Found importable FastAPI app |
||||
|
|
||||
|
╭─ <font color="#8AE234"><b>Importable FastAPI app</b></font> ─╮ |
||||
|
│ │ |
||||
|
│ <span style="background-color:#272822"><font color="#FF4689">from</font></span><span style="background-color:#272822"><font color="#F8F8F2"> main </font></span><span style="background-color:#272822"><font color="#FF4689">import</font></span><span style="background-color:#272822"><font color="#F8F8F2"> app</font></span><span style="background-color:#272822"> </span> │ |
||||
|
│ │ |
||||
|
╰──────────────────────────╯ |
||||
|
|
||||
|
<font color="#3465A4">INFO </font> Using import string <font color="#8AE234"><b>main:app</b></font> |
||||
|
|
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">╭────────── FastAPI CLI - Development mode ───────────╮</font></span> |
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span> |
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">│ Serving at: http://127.0.0.1:8000 │</font></span> |
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span> |
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">│ API docs: http://127.0.0.1:8000/docs │</font></span> |
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span> |
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">│ Running in development mode, for production use: │</font></span> |
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span> |
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">│ </font></span><span style="background-color:#C4A000"><font color="#555753"><b>fastapi run</b></font></span><span style="background-color:#C4A000"><font color="#2E3436"> │</font></span> |
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span> |
||||
|
<span style="background-color:#C4A000"><font color="#2E3436">╰─────────────────────────────────────────────────────╯</font></span> |
||||
|
|
||||
|
<font color="#4E9A06">INFO</font>: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] |
||||
|
<font color="#4E9A06">INFO</font>: Uvicorn running on <b>http://127.0.0.1:8000</b> (Press CTRL+C to quit) |
||||
|
<font color="#4E9A06">INFO</font>: Started reloader process [<font color="#34E2E2"><b>2265862</b></font>] using <font color="#34E2E2"><b>WatchFiles</b></font> |
||||
|
<font color="#4E9A06">INFO</font>: Started server process [<font color="#06989A">2265873</font>] |
||||
|
<font color="#4E9A06">INFO</font>: Waiting for application startup. |
||||
|
<font color="#4E9A06">INFO</font>: Application startup complete. |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
`fastapi` 命令列程式就是 **FastAPI CLI**。 |
||||
|
|
||||
|
FastAPI CLI 接收你的 Python 程式路徑(例如 `main.py`),並自動檢測 FastAPI 實例(通常命名為 `app`),確定正確的引入模組流程,然後運行該應用程式。 |
||||
|
|
||||
|
在生產環境,你應該使用 `fastapi run` 命令。 🚀 |
||||
|
|
||||
|
**FastAPI CLI** 內部使用了 <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a>,這是一個高效能、適合生產環境的 ASGI 伺服器。 😎 |
||||
|
|
||||
|
## `fastapi dev` |
||||
|
|
||||
|
執行 `fastapi dev` 會啟動開發模式。 |
||||
|
|
||||
|
預設情況下,**auto-reload** 功能是啟用的,當你對程式碼進行修改時,伺服器會自動重新載入。這會消耗較多資源,並且可能比禁用時更不穩定。因此,你應該只在開發環境中使用此功能。它也會在 IP 位址 `127.0.0.1` 上監聽,這是用於你的機器與自身通訊的 IP 位址(`localhost`)。 |
||||
|
|
||||
|
## `fastapi run` |
||||
|
|
||||
|
執行 `fastapi run` 會以生產模式啟動 FastAPI。 |
||||
|
|
||||
|
預設情況下,**auto-reload** 功能是禁用的。它也會在 IP 位址 `0.0.0.0` 上監聽,表示會監聽所有可用的 IP 地址,這樣任何能與該機器通訊的人都可以公開存取它。這通常是你在生產環境中運行應用程式的方式,例如在容器中運行時。 |
||||
|
|
||||
|
在大多數情況下,你會(也應該)有一個「終止代理」來處理 HTTPS,這取決於你如何部署你的應用程式,你的服務供應商可能會為你做這件事,或者你需要自己設置它。 |
||||
|
|
||||
|
/// tip |
||||
|
|
||||
|
你可以在[部署文件](deployment/index.md){.internal-link target=_blank}中了解更多相關資訊。 |
||||
|
|
||||
|
/// |
@ -0,0 +1,3 @@ |
|||||
|
# 資源 |
||||
|
|
||||
|
額外的資源、外部連結、文章等。 ✈️ |
Loading…
Reference in new issue