From 270aef71c47694ca349afeba95d13ade195185d2 Mon Sep 17 00:00:00 2001 From: Guillaume Fassot <97948781+prometek@users.noreply.github.com> Date: Sun, 8 Sep 2024 22:36:53 +0200 Subject: [PATCH 01/19] =?UTF-8?q?=F0=9F=93=9D=20Remove=20duplicate=20line?= =?UTF-8?q?=20in=20docs=20for=20`docs/en/docs/environment-variables.md`=20?= =?UTF-8?q?(#12169)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/environment-variables.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/en/docs/environment-variables.md b/docs/en/docs/environment-variables.md index 78e82d5af..43dd06add 100644 --- a/docs/en/docs/environment-variables.md +++ b/docs/en/docs/environment-variables.md @@ -243,8 +243,6 @@ This way, when you type `python` in the terminal, the system will find the Pytho //// -This way, when you type `python` in the terminal, the system will find the Python program in `/opt/custompython/bin` (the last directory) and use that one. - So, if you type:
From c49c4e7df8eef1ab4ed5baacdf02df3a10aaaae1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 8 Sep 2024 20:37:14 +0000 Subject: [PATCH 02/19] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index e09eb57b6..6e84911e9 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Docs + +* 📝 Remove duplicate line in docs for `docs/en/docs/environment-variables.md`. PR [#12169](https://github.com/fastapi/fastapi/pull/12169) by [@prometek](https://github.com/prometek). + ### Translations * 🌐 Add Korean translation for `docs/ko/docs/project-generation.md`. PR [#12157](https://github.com/fastapi/fastapi/pull/12157) by [@BORA040126](https://github.com/BORA040126). From a67167dce3f3b33ef1789c0eeb7a2dcdf2cc4314 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 20:35:50 +0200 Subject: [PATCH 03/19] =?UTF-8?q?=E2=AC=86=20[pre-commit.ci]=20pre-commit?= =?UTF-8?q?=20autoupdate=20(#12176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ⬆ [pre-commit.ci] pre-commit autoupdate updates: - [github.com/astral-sh/ruff-pre-commit: v0.6.3 → v0.6.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.3...v0.6.4) * bump ruff in tests requirements as well --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: svlandeg --- .pre-commit-config.yaml | 2 +- requirements-tests.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7e58afd4b..f74816f12 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.3 + rev: v0.6.4 hooks: - id: ruff args: diff --git a/requirements-tests.txt b/requirements-tests.txt index de5fdb8a2..809a19c0c 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -3,7 +3,7 @@ pytest >=7.1.3,<8.0.0 coverage[toml] >= 6.5.0,< 8.0 mypy ==1.8.0 -ruff ==0.6.3 +ruff ==0.6.4 dirty-equals ==0.6.0 # TODO: once removing databases from tutorial, upgrade SQLAlchemy # probably when including SQLModel From da4670cf775ff7c2ef98b7157a71a91fe980816e Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 9 Sep 2024 18:36:15 +0000 Subject: [PATCH 04/19] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 6e84911e9..3af1a5ade 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -17,6 +17,7 @@ hide: ### Internal +* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#12176](https://github.com/fastapi/fastapi/pull/12176) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci). * 👷 Update `issue-manager.yml`. PR [#12159](https://github.com/fastapi/fastapi/pull/12159) by [@tiangolo](https://github.com/tiangolo). * ✏️ Fix typo in `fastapi/params.py`. PR [#12143](https://github.com/fastapi/fastapi/pull/12143) by [@surreal30](https://github.com/surreal30). From fc601bcb4b2dd97e3c7918c8f59f97a62df06abc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 11:07:46 +0200 Subject: [PATCH 05/19] =?UTF-8?q?=E2=AC=86=20Bump=20tiangolo/issue-manager?= =?UTF-8?q?=20from=200.5.0=20to=200.5.1=20(#12173)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [tiangolo/issue-manager](https://github.com/tiangolo/issue-manager) from 0.5.0 to 0.5.1. - [Release notes](https://github.com/tiangolo/issue-manager/releases) - [Commits](https://github.com/tiangolo/issue-manager/compare/0.5.0...0.5.1) --- updated-dependencies: - dependency-name: tiangolo/issue-manager dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/issue-manager.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/issue-manager.yml b/.github/workflows/issue-manager.yml index fbb856792..439084434 100644 --- a/.github/workflows/issue-manager.yml +++ b/.github/workflows/issue-manager.yml @@ -27,7 +27,7 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: tiangolo/issue-manager@0.5.0 + - uses: tiangolo/issue-manager@0.5.1 with: token: ${{ secrets.GITHUB_TOKEN }} config: > From bc715d55bc1ee3aedf4d429ca4e08ae39e0bbb90 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 10 Sep 2024 09:08:09 +0000 Subject: [PATCH 06/19] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 3af1a5ade..b9eaed65d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -17,6 +17,7 @@ hide: ### Internal +* ⬆ Bump tiangolo/issue-manager from 0.5.0 to 0.5.1. PR [#12173](https://github.com/fastapi/fastapi/pull/12173) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#12176](https://github.com/fastapi/fastapi/pull/12176) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci). * 👷 Update `issue-manager.yml`. PR [#12159](https://github.com/fastapi/fastapi/pull/12159) by [@tiangolo](https://github.com/tiangolo). * ✏️ Fix typo in `fastapi/params.py`. PR [#12143](https://github.com/fastapi/fastapi/pull/12143) by [@surreal30](https://github.com/surreal30). From 80e2cd12747df2de38b4ab3ee1ee1cb889ee242b Mon Sep 17 00:00:00 2001 From: marcelomarkus Date: Tue, 10 Sep 2024 07:34:25 -0300 Subject: [PATCH 07/19] =?UTF-8?q?=F0=9F=8C=90=20Add=20Portuguese=20transla?= =?UTF-8?q?tion=20for=20`docs/pt/docs/tutorial/debugging.md`=20(#12165)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/pt/docs/tutorial/debugging.md | 115 +++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 docs/pt/docs/tutorial/debugging.md diff --git a/docs/pt/docs/tutorial/debugging.md b/docs/pt/docs/tutorial/debugging.md new file mode 100644 index 000000000..54582fcbc --- /dev/null +++ b/docs/pt/docs/tutorial/debugging.md @@ -0,0 +1,115 @@ +# Depuração + +Você pode conectar o depurador no seu editor, por exemplo, com o Visual Studio Code ou PyCharm. + +## Chamar `uvicorn` + +Em seu aplicativo FastAPI, importe e execute `uvicorn` diretamente: + +```Python hl_lines="1 15" +{!../../../docs_src/debugging/tutorial001.py!} +``` + +### Sobre `__name__ == "__main__"` + +O objetivo principal de `__name__ == "__main__"` é ter algum código que seja executado quando seu arquivo for chamado com: + +
+ +```console +$ python myapp.py +``` + +
+ +mas não é chamado quando outro arquivo o importa, como em: + +```Python +from myapp import app +``` + +#### Mais detalhes + +Digamos que seu arquivo se chama `myapp.py`. + +Se você executá-lo com: + +
+ +```console +$ python myapp.py +``` + +
+ +então a variável interna `__name__` no seu arquivo, criada automaticamente pelo Python, terá como valor a string `"__main__"`. + +Então, a seção: + +```Python + uvicorn.run(app, host="0.0.0.0", port=8000) +``` + +vai executar. + +--- + +Isso não acontecerá se você importar esse módulo (arquivo). + +Então, se você tiver outro arquivo `importer.py` com: + +```Python +from myapp import app + +# Mais um pouco de código +``` + +nesse caso, a variável criada automaticamente dentro de `myapp.py` não terá a variável `__name__` com o valor `"__main__"`. + +Então, a linha: + +```Python + uvicorn.run(app, host="0.0.0.0", port=8000) +``` + +não será executada. + +/// info | "Informação" + +Para mais informações, consulte a documentação oficial do Python. + +/// + +## Execute seu código com seu depurador + +Como você está executando o servidor Uvicorn diretamente do seu código, você pode chamar seu programa Python (seu aplicativo FastAPI) diretamente do depurador. + +--- + +Por exemplo, no Visual Studio Code, você pode: + +* Ir para o painel "Debug". +* "Add configuration...". +* Selecionar "Python" +* Executar o depurador com a opção "`Python: Current File (Integrated Terminal)`". + +Em seguida, ele iniciará o servidor com seu código **FastAPI**, parará em seus pontos de interrupção, etc. + +Veja como pode parecer: + + + +--- + +Se você usar o Pycharm, você pode: + +* Abrir o menu "Executar". +* Selecionar a opção "Depurar...". +* Então um menu de contexto aparece. +* Selecionar o arquivo para depurar (neste caso, `main.py`). + +Em seguida, ele iniciará o servidor com seu código **FastAPI**, parará em seus pontos de interrupção, etc. + +Veja como pode parecer: + + From 73d4f347df83c8e59ab55c9dfdbd974351e6efc5 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 10 Sep 2024 10:34:46 +0000 Subject: [PATCH 08/19] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index b9eaed65d..7492242a4 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/debugging.md`. PR [#12165](https://github.com/fastapi/fastapi/pull/12165) by [@marcelomarkus](https://github.com/marcelomarkus). * 🌐 Add Korean translation for `docs/ko/docs/project-generation.md`. PR [#12157](https://github.com/fastapi/fastapi/pull/12157) by [@BORA040126](https://github.com/BORA040126). ### Internal From a4a7925045e42030528c6f1fdeaa059e811455c0 Mon Sep 17 00:00:00 2001 From: marcelomarkus Date: Tue, 10 Sep 2024 07:35:14 -0300 Subject: [PATCH 09/19] =?UTF-8?q?=F0=9F=8C=90=20Add=20Portuguese=20transla?= =?UTF-8?q?tion=20for=20`docs/pt/docs/tutorial/testing.md`=20(#12164)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/pt/docs/tutorial/testing.md | 249 +++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 docs/pt/docs/tutorial/testing.md diff --git a/docs/pt/docs/tutorial/testing.md b/docs/pt/docs/tutorial/testing.md new file mode 100644 index 000000000..f734a7d9a --- /dev/null +++ b/docs/pt/docs/tutorial/testing.md @@ -0,0 +1,249 @@ +# Testando + +Graças ao Starlette, testar aplicativos **FastAPI** é fácil e agradável. + +Ele é baseado no HTTPX, que por sua vez é projetado com base em Requests, por isso é muito familiar e intuitivo. + +Com ele, você pode usar o pytest diretamente com **FastAPI**. + +## Usando `TestClient` + +/// info | "Informação" + +Para usar o `TestClient`, primeiro instale o `httpx`. + +Certifique-se de criar um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo e instalá-lo, por exemplo: + +```console +$ pip install httpx +``` + +/// + +Importe `TestClient`. + +Crie um `TestClient` passando seu aplicativo **FastAPI** para ele. + +Crie funções com um nome que comece com `test_` (essa é a convenção padrão do `pytest`). + +Use o objeto `TestClient` da mesma forma que você faz com `httpx`. + +Escreva instruções `assert` simples com as expressões Python padrão que você precisa verificar (novamente, `pytest` padrão). + +```Python hl_lines="2 12 15-18" +{!../../../docs_src/app_testing/tutorial001.py!} +``` + +/// tip | "Dica" + +Observe que as funções de teste são `def` normais, não `async def`. + +E as chamadas para o cliente também são chamadas normais, não usando `await`. + +Isso permite que você use `pytest` diretamente sem complicações. + +/// + +/// note | "Detalhes técnicos" + +Você também pode usar `from starlette.testclient import TestClient`. + +**FastAPI** fornece o mesmo `starlette.testclient` que `fastapi.testclient` apenas como uma conveniência para você, o desenvolvedor. Mas ele vem diretamente da Starlette. + +/// + +/// tip | "Dica" + +Se você quiser chamar funções `async` em seus testes além de enviar solicitações ao seu aplicativo FastAPI (por exemplo, funções de banco de dados assíncronas), dê uma olhada em [Testes assíncronos](../advanced/async-tests.md){.internal-link target=_blank} no tutorial avançado. + +/// + +## Separando testes + +Em uma aplicação real, você provavelmente teria seus testes em um arquivo diferente. + +E seu aplicativo **FastAPI** também pode ser composto de vários arquivos/módulos, etc. + +### Arquivo do aplicativo **FastAPI** + +Digamos que você tenha uma estrutura de arquivo conforme descrito em [Aplicativos maiores](bigger-applications.md){.internal-link target=_blank}: + +``` +. +├── app +│   ├── __init__.py +│   └── main.py +``` + +No arquivo `main.py` você tem seu aplicativo **FastAPI**: + + +```Python +{!../../../docs_src/app_testing/main.py!} +``` + +### Arquivo de teste + +Então você poderia ter um arquivo `test_main.py` com seus testes. Ele poderia estar no mesmo pacote Python (o mesmo diretório com um arquivo `__init__.py`): + +``` hl_lines="5" +. +├── app +│   ├── __init__.py +│   ├── main.py +│   └── test_main.py +``` + +Como esse arquivo está no mesmo pacote, você pode usar importações relativas para importar o objeto `app` do módulo `main` (`main.py`): + +```Python hl_lines="3" +{!../../../docs_src/app_testing/test_main.py!} +``` + +...e ter o código para os testes como antes. + +## Testando: exemplo estendido + +Agora vamos estender este exemplo e adicionar mais detalhes para ver como testar diferentes partes. + +### Arquivo de aplicativo **FastAPI** estendido + +Vamos continuar com a mesma estrutura de arquivo de antes: + +``` +. +├── app +│   ├── __init__.py +│   ├── main.py +│   └── test_main.py +``` + +Digamos que agora o arquivo `main.py` com seu aplicativo **FastAPI** tenha algumas outras **operações de rotas**. + +Ele tem uma operação `GET` que pode retornar um erro. + +Ele tem uma operação `POST` que pode retornar vários erros. + +Ambas as *operações de rotas* requerem um cabeçalho `X-Token`. + +//// tab | Python 3.10+ + +```Python +{!> ../../../docs_src/app_testing/app_b_an_py310/main.py!} +``` + +//// + +//// tab | Python 3.9+ + +```Python +{!> ../../../docs_src/app_testing/app_b_an_py39/main.py!} +``` + +//// + +//// tab | Python 3.8+ + +```Python +{!> ../../../docs_src/app_testing/app_b_an/main.py!} +``` + +//// + +//// tab | Python 3.10+ non-Annotated + +/// tip | "Dica" + +Prefira usar a versão `Annotated` se possível. + +/// + +```Python +{!> ../../../docs_src/app_testing/app_b_py310/main.py!} +``` + +//// + +//// tab | Python 3.8+ non-Annotated + +/// tip | "Dica" + +Prefira usar a versão `Annotated` se possível. + +/// + +```Python +{!> ../../../docs_src/app_testing/app_b/main.py!} +``` + +//// + +### Arquivo de teste estendido + +Você pode então atualizar `test_main.py` com os testes estendidos: + +```Python +{!> ../../../docs_src/app_testing/app_b/test_main.py!} +``` + +Sempre que você precisar que o cliente passe informações na requisição e não souber como, você pode pesquisar (no Google) como fazer isso no `httpx`, ou até mesmo como fazer isso com `requests`, já que o design do HTTPX é baseado no design do Requests. + +Depois é só fazer o mesmo nos seus testes. + +Por exemplo: + +* Para passar um parâmetro *path* ou *query*, adicione-o à própria URL. +* Para passar um corpo JSON, passe um objeto Python (por exemplo, um `dict`) para o parâmetro `json`. +* Se você precisar enviar *Dados de Formulário* em vez de JSON, use o parâmetro `data`. +* Para passar *headers*, use um `dict` no parâmetro `headers`. +* Para *cookies*, um `dict` no parâmetro `cookies`. + +Para mais informações sobre como passar dados para o backend (usando `httpx` ou `TestClient`), consulte a documentação do HTTPX. + +/// info | "Informação" + +Observe que o `TestClient` recebe dados que podem ser convertidos para JSON, não para modelos Pydantic. + +Se você tiver um modelo Pydantic em seu teste e quiser enviar seus dados para o aplicativo durante o teste, poderá usar o `jsonable_encoder` descrito em [Codificador compatível com JSON](encoder.md){.internal-link target=_blank}. + +/// + +## Execute-o + +Depois disso, você só precisa instalar o `pytest`. + +Certifique-se de criar um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo e instalá-lo, por exemplo: + +
+ +```console +$ pip install pytest + +---> 100% +``` + +
+ +Ele detectará os arquivos e os testes automaticamente, os executará e informará os resultados para você. + +Execute os testes com: + +
+ +```console +$ pytest + +================ test session starts ================ +platform linux -- Python 3.6.9, pytest-5.3.5, py-1.8.1, pluggy-0.13.1 +rootdir: /home/user/code/superawesome-cli/app +plugins: forked-1.1.3, xdist-1.31.0, cov-2.8.1 +collected 6 items + +---> 100% + +test_main.py ...... [100%] + +================= 1 passed in 0.03s ================= +``` + +
From e69ba263861b440fce06b55bedf83bd08646452b Mon Sep 17 00:00:00 2001 From: marcelomarkus Date: Tue, 10 Sep 2024 07:36:42 -0300 Subject: [PATCH 10/19] =?UTF-8?q?=F0=9F=8C=90=20Add=20Portuguese=20transla?= =?UTF-8?q?tion=20for=20`docs/pt/docs/environment-variables.md`=20(#12162)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/pt/docs/environment-variables.md | 298 ++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 docs/pt/docs/environment-variables.md diff --git a/docs/pt/docs/environment-variables.md b/docs/pt/docs/environment-variables.md new file mode 100644 index 000000000..360d1c496 --- /dev/null +++ b/docs/pt/docs/environment-variables.md @@ -0,0 +1,298 @@ +# Variáveis de Ambiente + +/// tip | "Dica" + +Se você já sabe o que são "variáveis de ambiente" e como usá-las, pode pular esta seção. + +/// + +Uma variável de ambiente (também conhecida como "**env var**") é uma variável que existe **fora** do código Python, no **sistema operacional**, e pode ser lida pelo seu código Python (ou por outros programas também). + +Variáveis de ambiente podem ser úteis para lidar com **configurações** do aplicativo, como parte da **instalação** do Python, etc. + +## Criar e Usar Variáveis de Ambiente + +Você pode **criar** e usar variáveis de ambiente no **shell (terminal)**, sem precisar do Python: + +//// tab | Linux, macOS, Windows Bash + +
+ +```console +// Você pode criar uma variável de ambiente MY_NAME com +$ export MY_NAME="Wade Wilson" + +// Então você pode usá-la com outros programas, como +$ echo "Hello $MY_NAME" + +Hello Wade Wilson +``` + +
+ +//// + +//// tab | Windows PowerShell + +
+ +```console +// Criar uma variável de ambiente MY_NAME +$ $Env:MY_NAME = "Wade Wilson" + +// Usá-la com outros programas, como +$ echo "Hello $Env:MY_NAME" + +Hello Wade Wilson +``` + +
+ +//// + +## Ler Variáveis de Ambiente no Python + +Você também pode criar variáveis de ambiente **fora** do Python, no terminal (ou com qualquer outro método) e depois **lê-las no Python**. + +Por exemplo, você poderia ter um arquivo `main.py` com: + +```Python hl_lines="3" +import os + +name = os.getenv("MY_NAME", "World") +print(f"Hello {name} from Python") +``` + +/// tip | "Dica" + +O segundo argumento para `os.getenv()` é o valor padrão a ser retornado. + +Se não for fornecido, é `None` por padrão, Aqui fornecemos `"World"` como o valor padrão a ser usado. + +/// + +Então você poderia chamar esse programa Python: + +//// tab | Linux, macOS, Windows Bash + +
+ +```console +// Aqui ainda não definimos a variável de ambiente +$ python main.py + +// Como não definimos a variável de ambiente, obtemos o valor padrão + +Hello World from Python + +// Mas se criarmos uma variável de ambiente primeiro +$ export MY_NAME="Wade Wilson" + +// E então chamar o programa novamente +$ python main.py + +// Agora ele pode ler a variável de ambiente + +Hello Wade Wilson from Python +``` + +
+ +//// + +//// tab | Windows PowerShell + +
+ +```console +// Aqui ainda não definimos a variável de ambiente +$ python main.py + +// Como não definimos a variável de ambiente, obtemos o valor padrão + +Hello World from Python + +// Mas se criarmos uma variável de ambiente primeiro +$ $Env:MY_NAME = "Wade Wilson" + +// E então chamar o programa novamente +$ python main.py + +// Agora ele pode ler a variável de ambiente + +Hello Wade Wilson from Python +``` + +
+ +//// + +Como as variáveis de ambiente podem ser definidas fora do código, mas podem ser lidas pelo código e não precisam ser armazenadas (com versão no `git`) com o restante dos arquivos, é comum usá-las para configurações ou **definições**. + +Você também pode criar uma variável de ambiente apenas para uma **invocação específica do programa**, que só está disponível para aquele programa e apenas pela duração dele. + +Para fazer isso, crie-a na mesma linha, antes do próprio programa: + +
+ +```console +// Criar uma variável de ambiente MY_NAME para esta chamada de programa +$ MY_NAME="Wade Wilson" python main.py + +// Agora ele pode ler a variável de ambiente + +Hello Wade Wilson from Python + +// A variável de ambiente não existe mais depois +$ python main.py + +Hello World from Python +``` + +
+ +/// tip | "Dica" + +Você pode ler mais sobre isso em The Twelve-Factor App: Config. + +/// + +## Tipos e Validação + +Essas variáveis de ambiente só podem lidar com **strings de texto**, pois são externas ao Python e precisam ser compatíveis com outros programas e com o resto do sistema (e até mesmo com diferentes sistemas operacionais, como Linux, Windows, macOS). + +Isso significa que **qualquer valor** lido em Python de uma variável de ambiente **será uma `str`**, e qualquer conversão para um tipo diferente ou qualquer validação precisa ser feita no código. + +Você aprenderá mais sobre como usar variáveis de ambiente para lidar com **configurações do aplicativo** no [Guia do Usuário Avançado - Configurações e Variáveis de Ambiente](./advanced/settings.md){.internal-link target=_blank}. + +## Variável de Ambiente `PATH` + +Existe uma variável de ambiente **especial** chamada **`PATH`** que é usada pelos sistemas operacionais (Linux, macOS, Windows) para encontrar programas para executar. + +O valor da variável `PATH` é uma longa string composta por diretórios separados por dois pontos `:` no Linux e macOS, e por ponto e vírgula `;` no Windows. + +Por exemplo, a variável de ambiente `PATH` poderia ter esta aparência: + +//// tab | Linux, macOS + +```plaintext +/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin +``` + +Isso significa que o sistema deve procurar programas nos diretórios: + +* `/usr/local/bin` +* `/usr/bin` +* `/bin` +* `/usr/sbin` +* `/sbin` + +//// + +//// tab | Windows + +```plaintext +C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32 +``` + +Isso significa que o sistema deve procurar programas nos diretórios: + +* `C:\Program Files\Python312\Scripts` +* `C:\Program Files\Python312` +* `C:\Windows\System32` + +//// + +Quando você digita um **comando** no terminal, o sistema operacional **procura** o programa em **cada um dos diretórios** listados na variável de ambiente `PATH`. + +Por exemplo, quando você digita `python` no terminal, o sistema operacional procura um programa chamado `python` no **primeiro diretório** dessa lista. + +Se ele o encontrar, então ele o **usará**. Caso contrário, ele continua procurando nos **outros diretórios**. + +### Instalando o Python e Atualizando o `PATH` + +Durante a instalação do Python, você pode ser questionado sobre a atualização da variável de ambiente `PATH`. + +//// tab | Linux, macOS + +Vamos supor que você instale o Python e ele fique em um diretório `/opt/custompython/bin`. + +Se você concordar em atualizar a variável de ambiente `PATH`, o instalador adicionará `/opt/custompython/bin` para a variável de ambiente `PATH`. + +Poderia parecer assim: + +```plaintext +/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin +``` + +Dessa forma, ao digitar `python` no terminal, o sistema encontrará o programa Python em `/opt/custompython/bin` (último diretório) e o utilizará. + +//// + +//// tab | Windows + +Digamos que você instala o Python e ele acaba em um diretório `C:\opt\custompython\bin`. + +Se você disser sim para atualizar a variável de ambiente `PATH`, o instalador adicionará `C:\opt\custompython\bin` à variável de ambiente `PATH`. + +```plaintext +C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin +``` + +Dessa forma, quando você digitar `python` no terminal, o sistema encontrará o programa Python em `C:\opt\custompython\bin` (o último diretório) e o utilizará. + +//// + +Então, se você digitar: + +
+ +```console +$ python +``` + +
+ +//// tab | Linux, macOS + +O sistema **encontrará** o programa `python` em `/opt/custompython/bin` e o executará. + +Seria aproximadamente equivalente a digitar: + +
+ +```console +$ /opt/custompython/bin/python +``` + +
+ +//// + +//// tab | Windows + +O sistema **encontrará** o programa `python` em `C:\opt\custompython\bin\python` e o executará. + +Seria aproximadamente equivalente a digitar: + +
+ +```console +$ C:\opt\custompython\bin\python +``` + +
+ +//// + +Essas informações serão úteis ao aprender sobre [Ambientes Virtuais](virtual-environments.md){.internal-link target=_blank}. + +## Conclusão + +Com isso, você deve ter uma compreensão básica do que são **variáveis ​​de ambiente** e como usá-las em Python. + +Você também pode ler mais sobre elas na Wikipedia para Variáveis ​​de Ambiente. + +Em muitos casos, não é muito óbvio como as variáveis ​​de ambiente seriam úteis e aplicáveis ​​imediatamente. Mas elas continuam aparecendo em muitos cenários diferentes quando você está desenvolvendo, então é bom saber sobre elas. + +Por exemplo, você precisará dessas informações na próxima seção, sobre [Ambientes Virtuais](virtual-environments.md). From 944b6e507e326f986061e99936c80aa565da669f Mon Sep 17 00:00:00 2001 From: marcelomarkus Date: Tue, 10 Sep 2024 07:37:13 -0300 Subject: [PATCH 11/19] =?UTF-8?q?=F0=9F=8C=90=20Add=20Portuguese=20transla?= =?UTF-8?q?tion=20for=20`docs/pt/docs/virtual-environments.md`=20(#12163)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/pt/docs/virtual-environments.md | 844 +++++++++++++++++++++++++++ 1 file changed, 844 insertions(+) create mode 100644 docs/pt/docs/virtual-environments.md diff --git a/docs/pt/docs/virtual-environments.md b/docs/pt/docs/virtual-environments.md new file mode 100644 index 000000000..863c8d65e --- /dev/null +++ b/docs/pt/docs/virtual-environments.md @@ -0,0 +1,844 @@ +# Ambientes Virtuais + +Ao trabalhar em projetos Python, você provavelmente deve usar um **ambiente virtual** (ou um mecanismo similar) para isolar os pacotes que você instala para cada projeto. + +/// info | "Informação" + +Se você já sabe sobre ambientes virtuais, como criá-los e usá-los, talvez seja melhor pular esta seção. 🤓 + +/// + +/// tip | "Dica" + +Um **ambiente virtual** é diferente de uma **variável de ambiente**. + +Uma **variável de ambiente** é uma variável no sistema que pode ser usada por programas. + +Um **ambiente virtual** é um diretório com alguns arquivos. + +/// + +/// info | "Informação" + +Esta página lhe ensinará como usar **ambientes virtuais** e como eles funcionam. + +Se você estiver pronto para adotar uma **ferramenta que gerencia tudo** para você (incluindo a instalação do Python), experimente uv. + +/// + +## Criar um Projeto + +Primeiro, crie um diretório para seu projeto. + +O que normalmente faço é criar um diretório chamado `code` dentro do meu diretório home/user. + +E dentro disso eu crio um diretório por projeto. + +
+ +```console +// Vá para o diretório inicial +$ cd +// Crie um diretório para todos os seus projetos de código +$ mkdir code +// Entre nesse diretório de código +$ cd code +// Crie um diretório para este projeto +$ mkdir awesome-project +// Entre no diretório do projeto +$ cd awesome-project +``` + +
+ +## Crie um ambiente virtual + +Ao começar a trabalhar em um projeto Python **pela primeira vez**, crie um ambiente virtual **dentro do seu projeto**. + +/// tip | "Dica" + +Você só precisa fazer isso **uma vez por projeto**, não toda vez que trabalhar. + +/// + +//// tab | `venv` + +Para criar um ambiente virtual, você pode usar o módulo `venv` que vem com o Python. + +
+ +```console +$ python -m venv .venv +``` + +
+ +/// details | O que esse comando significa + +* `python`: usa o programa chamado `python` +* `-m`: chama um módulo como um script, nós diremos a ele qual módulo vem em seguida +* `venv`: usa o módulo chamado `venv` que normalmente vem instalado com o Python +* `.venv`: cria o ambiente virtual no novo diretório `.venv` + +/// + +//// + +//// tab | `uv` + +Se você tiver o `uv` instalado, poderá usá-lo para criar um ambiente virtual. + +
+ +```console +$ uv venv +``` + +
+ +/// tip | "Dica" + +Por padrão, `uv` criará um ambiente virtual em um diretório chamado `.venv`. + +Mas você pode personalizá-lo passando um argumento adicional com o nome do diretório. + +/// + +//// + +Esse comando cria um novo ambiente virtual em um diretório chamado `.venv`. + +/// details | `.venv` ou outro nome + +Você pode criar o ambiente virtual em um diretório diferente, mas há uma convenção para chamá-lo de `.venv`. + +/// + +## Ative o ambiente virtual + +Ative o novo ambiente virtual para que qualquer comando Python que você executar ou pacote que você instalar o utilize. + +/// tip | "Dica" + +Faça isso **toda vez** que iniciar uma **nova sessão de terminal** para trabalhar no projeto. + +/// + +//// tab | Linux, macOS + +
+ +```console +$ source .venv/bin/activate +``` + +
+ +//// + +//// tab | Windows PowerShell + +
+ +```console +$ .venv\Scripts\Activate.ps1 +``` + +
+ +//// + +//// tab | Windows Bash + +Ou se você usa o Bash para Windows (por exemplo, Git Bash): + +
+ +```console +$ source .venv/Scripts/activate +``` + +
+ +//// + +/// tip | "Dica" + +Toda vez que você instalar um **novo pacote** naquele ambiente, **ative** o ambiente novamente. + +Isso garante que, se você usar um **programa de terminal (CLI)** instalado por esse pacote, você usará aquele do seu ambiente virtual e não qualquer outro que possa ser instalado globalmente, provavelmente com uma versão diferente do que você precisa. + +/// + +## Verifique se o ambiente virtual está ativo + +Verifique se o ambiente virtual está ativo (o comando anterior funcionou). + +/// tip | "Dica" + +Isso é **opcional**, mas é uma boa maneira de **verificar** se tudo está funcionando conforme o esperado e se você está usando o ambiente virtual pretendido. + +/// + +//// tab | Linux, macOS, Windows Bash + +
+ +```console +$ which python + +/home/user/code/awesome-project/.venv/bin/python +``` + +
+ +Se ele mostrar o binário `python` em `.venv/bin/python`, dentro do seu projeto (neste caso `awesome-project`), então funcionou. 🎉 + +//// + +//// tab | Windows PowerShell + +
+ +```console +$ Get-Command python + +C:\Users\user\code\awesome-project\.venv\Scripts\python +``` + +
+ +Se ele mostrar o binário `python` em `.venv\Scripts\python`, dentro do seu projeto (neste caso `awesome-project`), então funcionou. 🎉 + +//// + +## Atualizar `pip` + +/// tip | "Dica" + +Se você usar `uv`, você o usará para instalar coisas em vez do `pip`, então não precisará atualizar o `pip`. 😎 + +/// + +Se você estiver usando `pip` para instalar pacotes (ele vem por padrão com o Python), você deve **atualizá-lo** para a versão mais recente. + +Muitos erros exóticos durante a instalação de um pacote são resolvidos apenas atualizando o `pip` primeiro. + +/// tip | "Dica" + +Normalmente, você faria isso **uma vez**, logo após criar o ambiente virtual. + +/// + +Certifique-se de que o ambiente virtual esteja ativo (com o comando acima) e execute: + +
+ +```console +$ python -m pip install --upgrade pip + +---> 100% +``` + +
+ +## Adicionar `.gitignore` + +Se você estiver usando **Git** (você deveria), adicione um arquivo `.gitignore` para excluir tudo em seu `.venv` do Git. + +/// tip | "Dica" + +Se você usou `uv` para criar o ambiente virtual, ele já fez isso para você, você pode pular esta etapa. 😎 + +/// + +/// tip | "Dica" + +Faça isso **uma vez**, logo após criar o ambiente virtual. + +/// + +
+ +```console +$ echo "*" > .venv/.gitignore +``` + +
+ +/// details | O que esse comando significa + +* `echo "*"`: irá "imprimir" o texto `*` no terminal (a próxima parte muda isso um pouco) +* `>`: qualquer coisa impressa no terminal pelo comando à esquerda de `>` não deve ser impressa, mas sim escrita no arquivo que vai à direita de `>` +* `.gitignore`: o nome do arquivo onde o texto deve ser escrito + +E `*` para Git significa "tudo". Então, ele ignorará tudo no diretório `.venv`. + +Esse comando criará um arquivo `.gitignore` com o conteúdo: + +```gitignore +* +``` + +/// + +## Instalar Pacotes + +Após ativar o ambiente, você pode instalar pacotes nele. + +/// tip | "Dica" + +Faça isso **uma vez** ao instalar ou atualizar os pacotes que seu projeto precisa. + +Se precisar atualizar uma versão ou adicionar um novo pacote, você **fará isso novamente**. + +/// + +### Instalar pacotes diretamente + +Se estiver com pressa e não quiser usar um arquivo para declarar os requisitos de pacote do seu projeto, você pode instalá-los diretamente. + +/// tip | "Dica" + +É uma (muito) boa ideia colocar os pacotes e versões que seu programa precisa em um arquivo (por exemplo `requirements.txt` ou `pyproject.toml`). + +/// + +//// tab | `pip` + +
+ +```console +$ pip install "fastapi[standard]" + +---> 100% +``` + +
+ +//// + +//// tab | `uv` + +Se você tem o `uv`: + +
+ +```console +$ uv pip install "fastapi[standard]" +---> 100% +``` + +
+ +//// + +### Instalar a partir de `requirements.txt` + +Se você tiver um `requirements.txt`, agora poderá usá-lo para instalar seus pacotes. + +//// tab | `pip` + +
+ +```console +$ pip install -r requirements.txt +---> 100% +``` + +
+ +//// + +//// tab | `uv` + +Se você tem o `uv`: + +
+ +```console +$ uv pip install -r requirements.txt +---> 100% +``` + +
+ +//// + +/// details | `requirements.txt` + +Um `requirements.txt` com alguns pacotes poderia se parecer com: + +```requirements.txt +fastapi[standard]==0.113.0 +pydantic==2.8.0 +``` + +/// + +## Execute seu programa + +Depois de ativar o ambiente virtual, você pode executar seu programa, e ele usará o Python dentro do seu ambiente virtual com os pacotes que você instalou lá. + +
+ +```console +$ python main.py + +Hello World +``` + +
+ +## Configure seu editor + +Você provavelmente usaria um editor. Certifique-se de configurá-lo para usar o mesmo ambiente virtual que você criou (ele provavelmente o detectará automaticamente) para que você possa obter erros de preenchimento automático e em linha. + +Por exemplo: + +* VS Code +* PyCharm + +/// tip | "Dica" + +Normalmente, você só precisa fazer isso **uma vez**, ao criar o ambiente virtual. + +/// + +## Desativar o ambiente virtual + +Quando terminar de trabalhar no seu projeto, você pode **desativar** o ambiente virtual. + +
+ +```console +$ deactivate +``` + +
+ +Dessa forma, quando você executar `python`, ele não tentará executá-lo naquele ambiente virtual com os pacotes instalados nele. + +## Pronto para trabalhar + +Agora você está pronto para começar a trabalhar no seu projeto. + + + +/// tip | "Dica" + +Você quer entender o que é tudo isso acima? + +Continue lendo. 👇🤓 + +/// + +## Por que ambientes virtuais + +Para trabalhar com o FastAPI, você precisa instalar o Python. + +Depois disso, você precisará **instalar** o FastAPI e quaisquer outros **pacotes** que queira usar. + +Para instalar pacotes, você normalmente usaria o comando `pip` que vem com o Python (ou alternativas semelhantes). + +No entanto, se você usar `pip` diretamente, os pacotes serão instalados no seu **ambiente Python global** (a instalação global do Python). + +### O Problema + +Então, qual é o problema em instalar pacotes no ambiente global do Python? + +Em algum momento, você provavelmente acabará escrevendo muitos programas diferentes que dependem de **pacotes diferentes**. E alguns desses projetos em que você trabalha dependerão de **versões diferentes** do mesmo pacote. 😱 + +Por exemplo, você pode criar um projeto chamado `philosophers-stone`, este programa depende de outro pacote chamado **`harry`, usando a versão `1`**. Então, você precisa instalar `harry`. + +```mermaid +flowchart LR + stone(philosophers-stone) -->|requires| harry-1[harry v1] +``` + +Então, em algum momento depois, você cria outro projeto chamado `prisoner-of-azkaban`, e esse projeto também depende de `harry`, mas esse projeto precisa do **`harry` versão `3`**. + +```mermaid +flowchart LR + azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3] +``` + +Mas agora o problema é que, se você instalar os pacotes globalmente (no ambiente global) em vez de em um **ambiente virtual** local, você terá que escolher qual versão do `harry` instalar. + +Se você quiser executar `philosophers-stone`, precisará primeiro instalar `harry` versão `1`, por exemplo com: + +
+ +```console +$ pip install "harry==1" +``` + +
+ +E então você acabaria com `harry` versão `1` instalado em seu ambiente Python global. + +```mermaid +flowchart LR + subgraph global[global env] + harry-1[harry v1] + end + subgraph stone-project[philosophers-stone project] + stone(philosophers-stone) -->|requires| harry-1 + end +``` + +Mas se você quiser executar `prisoner-of-azkaban`, você precisará desinstalar `harry` versão `1` e instalar `harry` versão `3` (ou apenas instalar a versão `3` desinstalaria automaticamente a versão `1`). + +
+ +```console +$ pip install "harry==3" +``` + +
+ +E então você acabaria com `harry` versão `3` instalado em seu ambiente Python global. + +E se você tentar executar `philosophers-stone` novamente, há uma chance de que **não funcione** porque ele precisa de `harry` versão `1`. + +```mermaid +flowchart LR + subgraph global[global env] + harry-1[harry v1] + style harry-1 fill:#ccc,stroke-dasharray: 5 5 + harry-3[harry v3] + end + subgraph stone-project[philosophers-stone project] + stone(philosophers-stone) -.-x|⛔️| harry-1 + end + subgraph azkaban-project[prisoner-of-azkaban project] + azkaban(prisoner-of-azkaban) --> |requires| harry-3 + end +``` + +/// tip | "Dica" + +É muito comum em pacotes Python tentar ao máximo **evitar alterações drásticas** em **novas versões**, mas é melhor prevenir do que remediar e instalar versões mais recentes intencionalmente e, quando possível, executar os testes para verificar se tudo está funcionando corretamente. + +/// + +Agora, imagine isso com **muitos** outros **pacotes** dos quais todos os seus **projetos dependem**. Isso é muito difícil de gerenciar. E você provavelmente acabaria executando alguns projetos com algumas **versões incompatíveis** dos pacotes, e não saberia por que algo não está funcionando. + +Além disso, dependendo do seu sistema operacional (por exemplo, Linux, Windows, macOS), ele pode ter vindo com o Python já instalado. E, nesse caso, provavelmente tinha alguns pacotes pré-instalados com algumas versões específicas **necessárias para o seu sistema**. Se você instalar pacotes no ambiente global do Python, poderá acabar **quebrando** alguns dos programas que vieram com seu sistema operacional. + +## Onde os pacotes são instalados + +Quando você instala o Python, ele cria alguns diretórios com alguns arquivos no seu computador. + +Alguns desses diretórios são os responsáveis ​​por ter todos os pacotes que você instala. + +Quando você executa: + +
+ +```console +// Não execute isso agora, é apenas um exemplo 🤓 +$ pip install "fastapi[standard]" +---> 100% +``` + +
+ +Isso fará o download de um arquivo compactado com o código FastAPI, normalmente do PyPI. + +Ele também fará o **download** de arquivos para outros pacotes dos quais o FastAPI depende. + +Em seguida, ele **extrairá** todos esses arquivos e os colocará em um diretório no seu computador. + +Por padrão, ele colocará os arquivos baixados e extraídos no diretório que vem com a instalação do Python, que é o **ambiente global**. + +## O que são ambientes virtuais + +A solução para os problemas de ter todos os pacotes no ambiente global é usar um **ambiente virtual para cada projeto** em que você trabalha. + +Um ambiente virtual é um **diretório**, muito semelhante ao global, onde você pode instalar os pacotes para um projeto. + +Dessa forma, cada projeto terá seu próprio ambiente virtual (diretório `.venv`) com seus próprios pacotes. + +```mermaid +flowchart TB + subgraph stone-project[philosophers-stone project] + stone(philosophers-stone) --->|requires| harry-1 + subgraph venv1[.venv] + harry-1[harry v1] + end + end + subgraph azkaban-project[prisoner-of-azkaban project] + azkaban(prisoner-of-azkaban) --->|requires| harry-3 + subgraph venv2[.venv] + harry-3[harry v3] + end + end + stone-project ~~~ azkaban-project +``` + +## O que significa ativar um ambiente virtual + +Quando você ativa um ambiente virtual, por exemplo com: + +//// tab | Linux, macOS + +
+ +```console +$ source .venv/bin/activate +``` + +
+ +//// + +//// tab | Windows PowerShell + +
+ +```console +$ .venv\Scripts\Activate.ps1 +``` + +
+ +//// + +//// tab | Windows Bash + +Ou se você usa o Bash para Windows (por exemplo, Git Bash): + +
+ +```console +$ source .venv/Scripts/activate +``` + +
+ +//// + +Esse comando criará ou modificará algumas [variáveis ​​de ambiente](environment-variables.md){.internal-link target=_blank} que estarão disponíveis para os próximos comandos. + +Uma dessas variáveis ​​é a variável `PATH`. + +/// tip | "Dica" + +Você pode aprender mais sobre a variável de ambiente `PATH` na seção [Variáveis ​​de ambiente](environment-variables.md#path-environment-variable){.internal-link target=_blank}. + +/// + +A ativação de um ambiente virtual adiciona seu caminho `.venv/bin` (no Linux e macOS) ou `.venv\Scripts` (no Windows) à variável de ambiente `PATH`. + +Digamos que antes de ativar o ambiente, a variável `PATH` estava assim: + +//// tab | Linux, macOS + +```plaintext +/usr/bin:/bin:/usr/sbin:/sbin +``` + +Isso significa que o sistema procuraria programas em: + +* `/usr/bin` +* `/bin` +* `/usr/sbin` +* `/sbin` + +//// + +//// tab | Windows + +```plaintext +C:\Windows\System32 +``` + +Isso significa que o sistema procuraria programas em: + +* `C:\Windows\System32` + +//// + +Após ativar o ambiente virtual, a variável `PATH` ficaria mais ou menos assim: + +//// tab | Linux, macOS + +```plaintext +/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin +``` + +Isso significa que o sistema agora começará a procurar primeiro por programas em: + +```plaintext +/home/user/code/awesome-project/.venv/bin +``` + +antes de procurar nos outros diretórios. + +Então, quando você digita `python` no terminal, o sistema encontrará o programa Python em + +```plaintext +/home/user/code/awesome-project/.venv/bin/python +``` + +e usa esse. + +//// + +//// tab | Windows + +```plaintext +C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32 +``` + +Isso significa que o sistema agora começará a procurar primeiro por programas em: + +```plaintext +C:\Users\user\code\awesome-project\.venv\Scripts +``` + +antes de procurar nos outros diretórios. + +Então, quando você digita `python` no terminal, o sistema encontrará o programa Python em + +```plaintext +C:\Users\user\code\awesome-project\.venv\Scripts\python +``` + +e usa esse. + +//// + +Um detalhe importante é que ele colocará o caminho do ambiente virtual no **início** da variável `PATH`. O sistema o encontrará **antes** de encontrar qualquer outro Python disponível. Dessa forma, quando você executar `python`, ele usará o Python **do ambiente virtual** em vez de qualquer outro `python` (por exemplo, um `python` de um ambiente global). + +Ativar um ambiente virtual também muda algumas outras coisas, mas esta é uma das mais importantes. + +## Verificando um ambiente virtual + +Ao verificar se um ambiente virtual está ativo, por exemplo com: + +//// tab | Linux, macOS, Windows Bash + +
+ +```console +$ which python + +/home/user/code/awesome-project/.venv/bin/python +``` + +
+ +//// + +//// tab | Windows PowerShell + +
+ +```console +$ Get-Command python + +C:\Users\user\code\awesome-project\.venv\Scripts\python +``` + +
+ +//// + +Isso significa que o programa `python` que será usado é aquele **no ambiente virtual**. + +você usa `which` no Linux e macOS e `Get-Command` no Windows PowerShell. + +A maneira como esse comando funciona é que ele vai e verifica na variável de ambiente `PATH`, passando por **cada caminho em ordem**, procurando pelo programa chamado `python`. Uma vez que ele o encontre, ele **mostrará o caminho** para esse programa. + +A parte mais importante é que quando você chama ``python`, esse é exatamente o "`python`" que será executado. + +Assim, você pode confirmar se está no ambiente virtual correto. + +/// tip | "Dica" + +É fácil ativar um ambiente virtual, obter um Python e então **ir para outro projeto**. + +E o segundo projeto **não funcionaria** porque você está usando o **Python incorreto**, de um ambiente virtual para outro projeto. + +É útil poder verificar qual `python` está sendo usado. 🤓 + +/// + +## Por que desativar um ambiente virtual + +Por exemplo, você pode estar trabalhando em um projeto `philosophers-stone`, **ativar esse ambiente virtual**, instalar pacotes e trabalhar com esse ambiente. + +E então você quer trabalhar em **outro projeto** `prisoner-of-azkaban`. + +Você vai para aquele projeto: + +
+ +```console +$ cd ~/code/prisoner-of-azkaban +``` + +
+ +Se você não desativar o ambiente virtual para `philosophers-stone`, quando você executar `python` no terminal, ele tentará usar o Python de `philosophers-stone`. + +
+ +```console +$ cd ~/code/prisoner-of-azkaban + +$ python main.py + +// Erro ao importar o Sirius, ele não está instalado 😱 +Traceback (most recent call last): + File "main.py", line 1, in + import sirius +``` + +
+ +Mas se você desativar o ambiente virtual e ativar o novo para `prisoner-of-askaban`, quando você executar `python`, ele usará o Python do ambiente virtual em `prisoner-of-azkaban`. + +
+ +```console +$ cd ~/code/prisoner-of-azkaban + +// Você não precisa estar no diretório antigo para desativar, você pode fazer isso de onde estiver, mesmo depois de ir para o outro projeto 😎 +$ deactivate + +// Ative o ambiente virtual em prisoner-of-azkaban/.venv 🚀 +$ source .venv/bin/activate + +// Agora, quando você executar o python, ele encontrará o pacote sirius instalado neste ambiente virtual ✨ +$ python main.py + +Eu juro solenemente 🐺 +``` + +
+ +## Alternativas + +Este é um guia simples para você começar e lhe ensinar como tudo funciona **por baixo**. + +Existem muitas **alternativas** para gerenciar ambientes virtuais, dependências de pacotes (requisitos) e projetos. + +Quando estiver pronto e quiser usar uma ferramenta para **gerenciar todo o projeto**, dependências de pacotes, ambientes virtuais, etc., sugiro que você experimente o uv. + +`uv` pode fazer muitas coisas, ele pode: + +* **Instalar o Python** para você, incluindo versões diferentes +* Gerenciar o **ambiente virtual** para seus projetos +* Instalar **pacotes** +* Gerenciar **dependências e versões** de pacotes para seu projeto +* Certifique-se de ter um conjunto **exato** de pacotes e versões para instalar, incluindo suas dependências, para que você possa ter certeza de que pode executar seu projeto em produção exatamente da mesma forma que em seu computador durante o desenvolvimento, isso é chamado de **bloqueio** +* E muitas outras coisas + +## Conclusão + +Se você leu e entendeu tudo isso, agora **você sabe muito mais** sobre ambientes virtuais do que muitos desenvolvedores por aí. 🤓 + +Saber esses detalhes provavelmente será útil no futuro, quando você estiver depurando algo que parece complexo, mas você saberá **como tudo funciona**. 😎 From eb45bade63972dec674b83524e010e19ebdcd457 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 10 Sep 2024 10:37:36 +0000 Subject: [PATCH 12/19] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 7492242a4..114841f2d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/testing.md`. PR [#12164](https://github.com/fastapi/fastapi/pull/12164) by [@marcelomarkus](https://github.com/marcelomarkus). * 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/debugging.md`. PR [#12165](https://github.com/fastapi/fastapi/pull/12165) by [@marcelomarkus](https://github.com/marcelomarkus). * 🌐 Add Korean translation for `docs/ko/docs/project-generation.md`. PR [#12157](https://github.com/fastapi/fastapi/pull/12157) by [@BORA040126](https://github.com/BORA040126). From a4c5f7f62fbb2fbfc3daefd3ddcefa8b65e103d8 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 10 Sep 2024 10:38:58 +0000 Subject: [PATCH 13/19] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 114841f2d..11289cfe8 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Portuguese translation for `docs/pt/docs/environment-variables.md`. PR [#12162](https://github.com/fastapi/fastapi/pull/12162) by [@marcelomarkus](https://github.com/marcelomarkus). * 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/testing.md`. PR [#12164](https://github.com/fastapi/fastapi/pull/12164) by [@marcelomarkus](https://github.com/marcelomarkus). * 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/debugging.md`. PR [#12165](https://github.com/fastapi/fastapi/pull/12165) by [@marcelomarkus](https://github.com/marcelomarkus). * 🌐 Add Korean translation for `docs/ko/docs/project-generation.md`. PR [#12157](https://github.com/fastapi/fastapi/pull/12157) by [@BORA040126](https://github.com/BORA040126). From 74451189f6f243833674fc22a1fe57dfb21f9831 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 10 Sep 2024 10:40:52 +0000 Subject: [PATCH 14/19] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 11289cfe8..a72775416 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Translations +* 🌐 Add Portuguese translation for `docs/pt/docs/virtual-environments.md`. PR [#12163](https://github.com/fastapi/fastapi/pull/12163) by [@marcelomarkus](https://github.com/marcelomarkus). * 🌐 Add Portuguese translation for `docs/pt/docs/environment-variables.md`. PR [#12162](https://github.com/fastapi/fastapi/pull/12162) by [@marcelomarkus](https://github.com/marcelomarkus). * 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/testing.md`. PR [#12164](https://github.com/fastapi/fastapi/pull/12164) by [@marcelomarkus](https://github.com/marcelomarkus). * 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/debugging.md`. PR [#12165](https://github.com/fastapi/fastapi/pull/12165) by [@marcelomarkus](https://github.com/marcelomarkus). From b0eedbb5804a6ac32e4ee8d029d462d950ff8848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 11 Sep 2024 09:45:30 +0200 Subject: [PATCH 15/19] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Improve=20performanc?= =?UTF-8?q?e=20in=20request=20body=20parsing=20with=20a=20cache=20for=20in?= =?UTF-8?q?ternal=20model=20fields=20(#12184)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/_compat.py | 6 ++++++ fastapi/dependencies/utils.py | 4 ++-- tests/test_compat.py | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/fastapi/_compat.py b/fastapi/_compat.py index f940d6597..4b07b44fa 100644 --- a/fastapi/_compat.py +++ b/fastapi/_compat.py @@ -2,6 +2,7 @@ from collections import deque from copy import copy from dataclasses import dataclass, is_dataclass from enum import Enum +from functools import lru_cache from typing import ( Any, Callable, @@ -649,3 +650,8 @@ def is_uploadfile_sequence_annotation(annotation: Any) -> bool: is_uploadfile_or_nonable_uploadfile_annotation(sub_annotation) for sub_annotation in get_args(annotation) ) + + +@lru_cache +def get_cached_model_fields(model: Type[BaseModel]) -> List[ModelField]: + return get_model_fields(model) diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py index 6083b7319..f18eace9d 100644 --- a/fastapi/dependencies/utils.py +++ b/fastapi/dependencies/utils.py @@ -32,8 +32,8 @@ from fastapi._compat import ( evaluate_forwardref, field_annotation_is_scalar, get_annotation_from_field_info, + get_cached_model_fields, get_missing_field_error, - get_model_fields, is_bytes_field, is_bytes_sequence_field, is_scalar_field, @@ -810,7 +810,7 @@ async def request_body_to_args( fields_to_extract: List[ModelField] = body_fields if single_not_embedded_field and lenient_issubclass(first_field.type_, BaseModel): - fields_to_extract = get_model_fields(first_field.type_) + fields_to_extract = get_cached_model_fields(first_field.type_) if isinstance(received_body, FormData): body_to_process = await _extract_form_body(fields_to_extract, received_body) diff --git a/tests/test_compat.py b/tests/test_compat.py index 270475bf3..f4a3093c5 100644 --- a/tests/test_compat.py +++ b/tests/test_compat.py @@ -5,6 +5,7 @@ from fastapi._compat import ( ModelField, Undefined, _get_model_config, + get_cached_model_fields, get_model_fields, is_bytes_sequence_annotation, is_scalar_field, @@ -102,3 +103,18 @@ def test_is_pv1_scalar_field(): fields = get_model_fields(Model) assert not is_scalar_field(fields[0]) + + +def test_get_model_fields_cached(): + class Model(BaseModel): + foo: str + + non_cached_fields = get_model_fields(Model) + non_cached_fields2 = get_model_fields(Model) + cached_fields = get_cached_model_fields(Model) + cached_fields2 = get_cached_model_fields(Model) + for f1, f2 in zip(cached_fields, cached_fields2): + assert f1 is f2 + + assert non_cached_fields is not non_cached_fields2 + assert cached_fields is cached_fields2 From 8dc882f75121414eb44db590efae83fbddf43f72 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 Sep 2024 07:45:49 +0000 Subject: [PATCH 16/19] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index a72775416..647b51b19 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Refactors + +* ⚡️ Improve performance in request body parsing with a cache for internal model fields. PR [#12184](https://github.com/fastapi/fastapi/pull/12184) by [@tiangolo](https://github.com/tiangolo). + ### Docs * 📝 Remove duplicate line in docs for `docs/en/docs/environment-variables.md`. PR [#12169](https://github.com/fastapi/fastapi/pull/12169) by [@prometek](https://github.com/prometek). From 212fd5e247279073dceaba346fd4afc52f627232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 11 Sep 2024 09:46:34 +0200 Subject: [PATCH 17/19] =?UTF-8?q?=F0=9F=94=96=20Release=20version=200.114.?= =?UTF-8?q?1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 2 ++ fastapi/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 647b51b19..97f472815 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,8 @@ hide: ## Latest Changes +## 0.114.1 + ### Refactors * ⚡️ Improve performance in request body parsing with a cache for internal model fields. PR [#12184](https://github.com/fastapi/fastapi/pull/12184) by [@tiangolo](https://github.com/tiangolo). diff --git a/fastapi/__init__.py b/fastapi/__init__.py index dce17360f..c2ed4859a 100644 --- a/fastapi/__init__.py +++ b/fastapi/__init__.py @@ -1,6 +1,6 @@ """FastAPI framework, high performance, easy to learn, fast to code, ready for production""" -__version__ = "0.114.0" +__version__ = "0.114.1" from starlette import status as status From 24b8f2668beb773895a93040a2ae284898dc58b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 12 Sep 2024 00:49:55 +0200 Subject: [PATCH 18/19] =?UTF-8?q?=E2=9E=95=20Add=20inline-snapshot=20for?= =?UTF-8?q?=20tests=20(#12189)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 ++++ requirements-tests.txt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index bb87be470..1be2817a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -241,3 +241,7 @@ known-third-party = ["fastapi", "pydantic", "starlette"] [tool.ruff.lint.pyupgrade] # Preserve types, even if a file imports `from __future__ import annotations`. keep-runtime-typing = true + +[tool.inline-snapshot] +# default-flags=["fix"] +# default-flags=["create"] diff --git a/requirements-tests.txt b/requirements-tests.txt index 809a19c0c..2f2576dd5 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -14,7 +14,7 @@ anyio[trio] >=3.2.1,<4.0.0 PyJWT==2.8.0 pyyaml >=5.3.1,<7.0.0 passlib[bcrypt] >=1.7.2,<2.0.0 - +inline-snapshot==0.13.0 # types types-ujson ==5.7.0.1 types-orjson ==3.6.2 From ba0bb6212e553e779f75f973d07a4db112b43cf0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 Sep 2024 22:50:18 +0000 Subject: [PATCH 19/19] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 97f472815..01c9fb225 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Internal + +* ➕ Add inline-snapshot for tests. PR [#12189](https://github.com/fastapi/fastapi/pull/12189) by [@tiangolo](https://github.com/tiangolo). + ## 0.114.1 ### Refactors