diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 4cc8bf018..f4572ffe8 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -18,6 +18,10 @@ hide: ### Translations +* 🌐 Update translations for ru (update-outdated). PR [#14693](https://github.com/fastapi/fastapi/pull/14693) by [@tiangolo](https://github.com/tiangolo). +* 🌐 Update translations for pt (update-outdated). PR [#14724](https://github.com/fastapi/fastapi/pull/14724) by [@tiangolo](https://github.com/tiangolo). +* 🌐 Update Korean LLM prompt. PR [#14740](https://github.com/fastapi/fastapi/pull/14740) by [@hard-coders](https://github.com/hard-coders). +* 🌐 Improve LLM prompt for Turkish translations. PR [#14728](https://github.com/fastapi/fastapi/pull/14728) by [@Kadermiyanyedi](https://github.com/Kadermiyanyedi). * 🌐 Update portuguese llm-prompt.md. PR [#14702](https://github.com/fastapi/fastapi/pull/14702) by [@ceb10n](https://github.com/ceb10n). * 🌐 Update LLM prompt instructions file for French. PR [#14618](https://github.com/fastapi/fastapi/pull/14618) by [@tiangolo](https://github.com/tiangolo). * 🌐 Update translations for ko (add-missing). PR [#14699](https://github.com/fastapi/fastapi/pull/14699) by [@tiangolo](https://github.com/tiangolo). diff --git a/docs/ko/llm-prompt.md b/docs/ko/llm-prompt.md index df807c949..533160eab 100644 --- a/docs/ko/llm-prompt.md +++ b/docs/ko/llm-prompt.md @@ -8,6 +8,7 @@ Language code: ko. - Use polite, instructional Korean (e.g. 합니다/하세요 style). - Keep the tone consistent with the existing Korean FastAPI docs. +- Do not translate “You” literally as “당신”. Use “여러분” where appropriate, or omit the subject if it sounds more natural in Korean. ### Headings diff --git a/docs/pt/docs/_llm-test.md b/docs/pt/docs/_llm-test.md index fda58334c..3a2801fdd 100644 --- a/docs/pt/docs/_llm-test.md +++ b/docs/pt/docs/_llm-test.md @@ -1,8 +1,8 @@ # Arquivo de teste de LLM { #llm-test-file } -Este documento testa se o LLM, que traduz a documentação, entende o `general_prompt` em `scripts/translate.py` e o prompt específico do idioma em `docs/{language code}/llm-prompt.md`. O prompt específico do idioma é anexado ao `general_prompt`. +Este documento testa se o LLM, que traduz a documentação, entende o `general_prompt` em `scripts/translate.py` e o prompt específico do idioma em `docs/{language code}/llm-prompt.md`. O prompt específico do idioma é anexado ao `general_prompt`. -Os testes adicionados aqui serão vistos por todos os autores dos prompts específicos de idioma. +Os testes adicionados aqui serão vistos por todos os designers dos prompts específicos de idioma. Use da seguinte forma: @@ -23,7 +23,7 @@ Este é um trecho de código: `foo`. E este é outro trecho de código: `bar`. E //// -//// tab | Informações +//// tab | Informação O conteúdo dos trechos de código deve ser deixado como está. @@ -45,9 +45,9 @@ O LLM provavelmente vai traduzir isso errado. O interessante é apenas se ele ma //// -//// tab | Informações +//// tab | Informação -O autor do prompt pode escolher se deseja converter aspas neutras em aspas tipográficas. Também é aceitável deixá-las como estão. +O designer do prompt pode escolher se quer converter aspas neutras em aspas tipográficas. Também é aceitável deixá-las como estão. Veja, por exemplo, a seção `### Quotes` em `docs/de/llm-prompt.md`. @@ -67,7 +67,7 @@ Pesado: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you ha //// -//// tab | Informações +//// tab | Informação ... No entanto, as aspas dentro de trechos de código devem permanecer como estão. @@ -95,24 +95,24 @@ $ fastapi run MDN -* I/O. +* MDN +* I/O. //// -//// tab | Informações +//// tab | Informação Os atributos "title" dos elementos "abbr" são traduzidos seguindo algumas instruções específicas. @@ -228,7 +228,7 @@ Veja a seção `### HTML abbr elements` no prompt geral em `scripts/translate.py //// tab | Teste -### Desenvolver uma aplicação web - um tutorial { #develop-a-webapp-a-tutorial } +### Desenvolver uma webapp - um tutorial { #develop-a-webapp-a-tutorial } Olá. @@ -242,7 +242,7 @@ Olá novamente. //// -//// tab | Informações +//// tab | Informação A única regra rígida para títulos é que o LLM deixe a parte do hash dentro de chaves inalterada, o que garante que os links não quebrem. @@ -494,9 +494,9 @@ Para algumas instruções específicas do idioma, veja, por exemplo, a seção ` //// -//// tab | Informações +//// tab | Informação -Esta é uma lista não completa e não normativa de termos (principalmente) técnicos vistos na documentação. Pode ser útil para o autor do prompt descobrir para quais termos o LLM precisa de uma ajudinha. Por exemplo, quando ele continua revertendo uma boa tradução para uma tradução subótima. Ou quando tem problemas para conjugar/declinar um termo no seu idioma. +Esta é uma lista não completa e não normativa de termos (principalmente) técnicos vistos na documentação. Pode ser útil para o designer do prompt descobrir para quais termos o LLM precisa de uma ajudinha. Por exemplo, quando ele continua revertendo uma boa tradução para uma tradução subótima. Ou quando tem problemas para conjugar/declinar um termo no seu idioma. Veja, por exemplo, a seção `### List of English terms and their preferred German translations` em `docs/de/llm-prompt.md`. diff --git a/docs/pt/docs/advanced/path-operation-advanced-configuration.md b/docs/pt/docs/advanced/path-operation-advanced-configuration.md index e1c3e5ab8..b3af116a2 100644 --- a/docs/pt/docs/advanced/path-operation-advanced-configuration.md +++ b/docs/pt/docs/advanced/path-operation-advanced-configuration.md @@ -10,7 +10,7 @@ Se você não é um "especialista" no OpenAPI, você provavelmente não precisa Você pode definir o `operationId` do OpenAPI que será utilizado na sua *operação de rota* com o parâmetro `operation_id`. -Você precisa ter certeza que ele é único para cada operação. +Você deveria ter certeza que ele é único para cada operação. {* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *} @@ -18,13 +18,13 @@ Você precisa ter certeza que ele é único para cada operação. Se você quiser utilizar o nome das funções da sua API como `operationId`s, você pode iterar sobre todos esses nomes e sobrescrever o `operation_id` em cada *operação de rota* utilizando o `APIRoute.name` dela. -Você deve fazer isso depois de adicionar todas as suas *operações de rota*. +Você deveria fazer isso depois de adicionar todas as suas *operações de rota*. {* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *} /// tip | Dica -Se você chamar `app.openapi()` manualmente, os `operationId`s devem ser atualizados antes dessa chamada. +Se você chamar `app.openapi()` manualmente, você deveria atualizar os `operationId`s antes dessa chamada. /// @@ -44,11 +44,11 @@ Para excluir uma *operação de rota* do esquema OpenAPI gerado (e por consequê ## Descrição avançada a partir de docstring { #advanced-description-from-docstring } -Você pode limitar as linhas utilizadas a partir de uma docstring de uma *função de operação de rota* para o OpenAPI. +Você pode limitar as linhas utilizadas a partir da docstring de uma *função de operação de rota* para o OpenAPI. -Adicionar um `\f` (um caractere de escape para alimentação de formulário) faz com que o **FastAPI** restrinja a saída utilizada pelo OpenAPI até esse ponto. +Adicionar um `\f` (um caractere de escape para "form feed") faz com que o **FastAPI** trunque a saída usada para o OpenAPI até esse ponto. -Ele não será mostrado na documentação, mas outras ferramentas (como o Sphinx) serão capazes de utilizar o resto do texto. +Ele não será mostrado na documentação, mas outras ferramentas (como o Sphinx) serão capazes de utilizar o resto. {* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *} @@ -131,70 +131,38 @@ E se você olhar o esquema OpenAPI resultante (na rota `/openapi.json` da sua AP ### Esquema de *operação de rota* do OpenAPI personalizado { #custom-openapi-path-operation-schema } -O dicionário em `openapi_extra` vai ter todos os seus níveis mesclados dentro do esquema OpenAPI gerado automaticamente para a *operação de rota*. +O dicionário em `openapi_extra` vai ser mesclado profundamente com o esquema OpenAPI gerado automaticamente para a *operação de rota*. -Então, você pode adicionar dados extras para o esquema gerado automaticamente. +Então, você pode adicionar dados extras ao esquema gerado automaticamente. -Por exemplo, você poderia optar por ler e validar a requisição com seu próprio código, sem utilizar funcionalidades automatizadas do FastAPI com o Pydantic, mas você ainda pode quere definir a requisição no esquema OpenAPI. +Por exemplo, você poderia decidir ler e validar a requisição com seu próprio código, sem usar as funcionalidades automáticas do FastAPI com o Pydantic, mas ainda assim querer definir a requisição no esquema OpenAPI. Você pode fazer isso com `openapi_extra`: {* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *} -Nesse exemplo, nós não declaramos nenhum modelo do Pydantic. Na verdade, o corpo da requisição não está nem mesmo analisado como JSON, ele é lido diretamente como `bytes` e a função `magic_data_reader()` seria a responsável por analisar ele de alguma forma. +Nesse exemplo, nós não declaramos nenhum modelo do Pydantic. Na verdade, o corpo da requisição não está nem mesmo analisado como JSON, ele é lido diretamente como `bytes`, e a função `magic_data_reader()` seria a responsável por analisar ele de alguma forma. De toda forma, nós podemos declarar o esquema esperado para o corpo da requisição. ### Tipo de conteúdo do OpenAPI personalizado { #custom-openapi-content-type } -Utilizando esse mesmo truque, você pode utilizar um modelo Pydantic para definir o JSON Schema que é então incluído na seção do esquema personalizado do OpenAPI na *operação de rota*. +Utilizando esse mesmo truque, você pode usar um modelo Pydantic para definir o JSON Schema que é então incluído na seção do esquema personalizado do OpenAPI na *operação de rota*. -E você pode fazer isso até mesmo quando os dados da requisição não seguem o formato JSON. +E você pode fazer isso até mesmo quando o tipo de dados na requisição não é JSON. -Por exemplo, nesta aplicação nós não usamos a funcionalidade integrada ao FastAPI de extrair o JSON Schema dos modelos Pydantic nem a validação automática do JSON. Na verdade, estamos declarando o tipo do conteúdo da requisição como YAML, em vez de JSON: - -//// tab | Pydantic v2 +Por exemplo, nesta aplicação nós não usamos a funcionalidade integrada ao FastAPI de extrair o JSON Schema dos modelos Pydantic nem a validação automática para JSON. Na verdade, estamos declarando o tipo de conteúdo da requisição como YAML, em vez de JSON: {* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *} -//// +Entretanto, mesmo que não utilizemos a funcionalidade integrada por padrão, ainda estamos usando um modelo Pydantic para gerar um JSON Schema manualmente para os dados que queremos receber em YAML. -//// tab | Pydantic v1 +Então utilizamos a requisição diretamente e extraímos o corpo como `bytes`. Isso significa que o FastAPI não vai sequer tentar analisar o payload da requisição como JSON. -{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *} - -//// - -/// info | Informação - -Na versão 1 do Pydantic, o método para obter o JSON Schema de um modelo é `Item.schema()`, na versão 2 do Pydantic, o método é `Item.model_json_schema()`. - -/// - -Entretanto, mesmo que não utilizemos a funcionalidade integrada por padrão, ainda estamos usando um modelo Pydantic para gerar um JSON Schema manualmente para os dados que queremos receber no formato YAML. - -Então utilizamos a requisição diretamente, e extraímos o corpo como `bytes`. Isso significa que o FastAPI não vai sequer tentar analisar o corpo da requisição como JSON. - -E então no nosso código, nós analisamos o conteúdo YAML diretamente, e estamos utilizando o mesmo modelo Pydantic para validar o conteúdo YAML: - -//// tab | Pydantic v2 +E então no nosso código, nós analisamos o conteúdo YAML diretamente e, em seguida, estamos usando novamente o mesmo modelo Pydantic para validar o conteúdo YAML: {* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *} -//// - -//// tab | Pydantic v1 - -{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *} - -//// - -/// info | Informação - -Na versão 1 do Pydantic, o método para analisar e validar um objeto era `Item.parse_obj()`, na versão 2 do Pydantic, o método é chamado de `Item.model_validate()`. - -/// - /// tip | Dica Aqui reutilizamos o mesmo modelo do Pydantic. diff --git a/docs/pt/docs/advanced/settings.md b/docs/pt/docs/advanced/settings.md index 6f5b7feae..28411269b 100644 --- a/docs/pt/docs/advanced/settings.md +++ b/docs/pt/docs/advanced/settings.md @@ -46,12 +46,6 @@ $ pip install "fastapi[all]" -/// info | Informação - -No Pydantic v1 ele vinha incluído no pacote principal. Agora é distribuído como um pacote independente para que você possa optar por instalá-lo ou não, caso não precise dessa funcionalidade. - -/// - ### Criar o objeto `Settings` { #create-the-settings-object } Importe `BaseSettings` do Pydantic e crie uma subclasse, muito parecido com um modelo do Pydantic. @@ -60,24 +54,8 @@ Da mesma forma que com modelos do Pydantic, você declara atributos de classe co Você pode usar as mesmas funcionalidades e ferramentas de validação que usa em modelos do Pydantic, como diferentes tipos de dados e validações adicionais com `Field()`. -//// tab | Pydantic v2 - {* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *} -//// - -//// tab | Pydantic v1 - -/// info | Informação - -No Pydantic v1 você importaria `BaseSettings` diretamente de `pydantic` em vez de `pydantic_settings`. - -/// - -{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *} - -//// - /// tip | Dica Se você quer algo rápido para copiar e colar, não use este exemplo, use o último abaixo. @@ -215,8 +193,6 @@ APP_NAME="ChimichangApp" E então atualizar seu `config.py` com: -//// tab | Pydantic v2 - {* ../../docs_src/settings/app03_an_py39/config.py hl[9] *} /// tip | Dica @@ -225,26 +201,6 @@ O atributo `model_config` é usado apenas para configuração do Pydantic. Você /// -//// - -//// tab | Pydantic v1 - -{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *} - -/// tip | Dica - -A classe `Config` é usada apenas para configuração do Pydantic. Você pode ler mais em Pydantic Model Config. - -/// - -//// - -/// info | Informação - -Na versão 1 do Pydantic a configuração era feita em uma classe interna `Config`, na versão 2 do Pydantic é feita em um atributo `model_config`. Esse atributo recebe um `dict`, e para ter autocompletar e erros inline você pode importar e usar `SettingsConfigDict` para definir esse `dict`. - -/// - Aqui definimos a configuração `env_file` dentro da sua classe `Settings` do Pydantic e definimos o valor como o nome do arquivo dotenv que queremos usar. ### Criando o `Settings` apenas uma vez com `lru_cache` { #creating-the-settings-only-once-with-lru-cache } diff --git a/docs/pt/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md b/docs/pt/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md index 2a2659a03..0995e1028 100644 --- a/docs/pt/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md +++ b/docs/pt/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md @@ -2,21 +2,23 @@ Se você tem uma aplicação FastAPI antiga, pode estar usando o Pydantic versão 1. -O FastAPI tem suporte ao Pydantic v1 ou v2 desde a versão 0.100.0. +O FastAPI versão 0.100.0 tinha suporte ao Pydantic v1 ou v2. Ele usaria aquele que você tivesse instalado. -Se você tiver o Pydantic v2 instalado, ele será utilizado. Se, em vez disso, tiver o Pydantic v1, será ele que será utilizado. +O FastAPI versão 0.119.0 introduziu suporte parcial ao Pydantic v1 a partir de dentro do Pydantic v2 (como `pydantic.v1`), para facilitar a migração para o v2. -O Pydantic v1 está agora descontinuado e o suporte a ele será removido nas próximas versões do FastAPI, você deveria migrar para o Pydantic v2. Assim, você terá as funcionalidades, melhorias e correções mais recentes. +O FastAPI 0.126.0 removeu o suporte ao Pydantic v1, enquanto ainda oferece suporte a `pydantic.v1` por mais algum tempo. /// warning | Atenção -Além disso, a equipe do Pydantic interrompeu o suporte ao Pydantic v1 para as versões mais recentes do Python, a partir do **Python 3.14**. +A equipe do Pydantic interrompeu o suporte ao Pydantic v1 para as versões mais recentes do Python, a partir do **Python 3.14**. + +Isso inclui `pydantic.v1`, que não é mais suportado no Python 3.14 e superiores. Se quiser usar as funcionalidades mais recentes do Python, você precisará garantir que usa o Pydantic v2. /// -Se você tem uma aplicação FastAPI antiga com Pydantic v1, aqui vou mostrar como migrá-la para o Pydantic v2 e as **novas funcionalidades no FastAPI 0.119.0** para ajudar em uma migração gradual. +Se você tem uma aplicação FastAPI antiga com Pydantic v1, aqui vou mostrar como migrá-la para o Pydantic v2, e as **funcionalidades no FastAPI 0.119.0** para ajudar em uma migração gradual. ## Guia oficial { #official-guide } @@ -44,7 +46,7 @@ Depois disso, você pode rodar os testes e verificar se tudo funciona. Se funcio ## Pydantic v1 no v2 { #pydantic-v1-in-v2 } -O Pydantic v2 inclui tudo do Pydantic v1 como um submódulo `pydantic.v1`. +O Pydantic v2 inclui tudo do Pydantic v1 como um submódulo `pydantic.v1`. Mas isso não é mais suportado em versões acima do Python 3.13. Isso significa que você pode instalar a versão mais recente do Pydantic v2 e importar e usar os componentes antigos do Pydantic v1 a partir desse submódulo, como se tivesse o Pydantic v1 antigo instalado. @@ -66,7 +68,7 @@ Tenha em mente que, como a equipe do Pydantic não oferece mais suporte ao Pydan ### Pydantic v1 e v2 na mesma aplicação { #pydantic-v1-and-v2-on-the-same-app } -Não é suportado pelo Pydantic ter um modelo do Pydantic v2 com campos próprios definidos como modelos do Pydantic v1, ou vice-versa. +Não é **suportado** pelo Pydantic ter um modelo do Pydantic v2 com campos próprios definidos como modelos do Pydantic v1, ou vice-versa. ```mermaid graph TB @@ -86,7 +88,7 @@ graph TB style V2Field fill:#f9fff3 ``` -...but, you can have separated models using Pydantic v1 and v2 in the same app. +...mas, você pode ter modelos separados usando Pydantic v1 e v2 na mesma aplicação. ```mermaid graph TB @@ -106,7 +108,7 @@ graph TB style V2Field fill:#f9fff3 ``` -Em alguns casos, é até possível ter modelos Pydantic v1 e v2 na mesma operação de rota na sua aplicação FastAPI: +Em alguns casos, é até possível ter modelos Pydantic v1 e v2 na mesma **operação de rota** na sua aplicação FastAPI: {* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *} @@ -122,7 +124,7 @@ Se você precisar usar algumas das ferramentas específicas do FastAPI para par /// tip | Dica -Primeiro tente com o `bump-pydantic`; se seus testes passarem e isso funcionar, então você concluiu tudo com um único comando. ✨ +Primeiro tente com o `bump-pydantic`, se seus testes passarem e isso funcionar, então você concluiu tudo com um único comando. ✨ /// diff --git a/docs/pt/docs/how-to/separate-openapi-schemas.md b/docs/pt/docs/how-to/separate-openapi-schemas.md index 8855934fd..f757025a0 100644 --- a/docs/pt/docs/how-to/separate-openapi-schemas.md +++ b/docs/pt/docs/how-to/separate-openapi-schemas.md @@ -1,8 +1,8 @@ # Esquemas OpenAPI Separados para Entrada e Saída ou Não { #separate-openapi-schemas-for-input-and-output-or-not } -Ao usar **Pydantic v2**, o OpenAPI gerado é um pouco mais exato e **correto** do que antes. 😎 +Desde que o **Pydantic v2** foi lançado, o OpenAPI gerado é um pouco mais exato e **correto** do que antes. 😎 -Inclusive, em alguns casos, ele terá até **dois JSON Schemas** no OpenAPI para o mesmo modelo Pydantic, para entrada e saída, dependendo se eles possuem **valores padrão**. +De fato, em alguns casos, ele terá até **dois JSON Schemas** no OpenAPI para o mesmo modelo Pydantic, para entrada e saída, dependendo se eles possuem **valores padrão**. Vamos ver como isso funciona e como alterar se for necessário. @@ -95,10 +95,8 @@ O suporte para `separate_input_output_schemas` foi adicionado no FastAPI `0.102. ### Mesmo Esquema para Modelos de Entrada e Saída na Documentação { #same-schema-for-input-and-output-models-in-docs } -E agora haverá um único esquema para entrada e saída para o modelo, apenas `Item`, e `description` **não será obrigatório**: +E agora haverá um único esquema para entrada e saída para o modelo, apenas `Item`, e ele terá `description` como **não obrigatório**:
- -Esse é o mesmo comportamento do Pydantic v1. 🤓 diff --git a/docs/pt/docs/index.md b/docs/pt/docs/index.md index 0428c3a79..4e3be586d 100644 --- a/docs/pt/docs/index.md +++ b/docs/pt/docs/index.md @@ -40,8 +40,8 @@ Os recursos chave são: * **Rápido**: alta performance, equivalente a **NodeJS** e **Go** (graças ao Starlette e Pydantic). [Um dos frameworks mais rápidos disponíveis](#performance). * **Rápido para codar**: Aumenta a velocidade para desenvolver recursos entre 200% a 300%. * * **Poucos bugs**: Reduz cerca de 40% de erros induzidos por humanos (desenvolvedores). * -* **Intuitivo**: Grande suporte a _IDEs_. Preenchimento automático em todos os lugares. Menos tempo debugando. -* **Fácil**: Projetado para ser fácil de aprender e usar. Menos tempo lendo documentação. +* **Intuitivo**: Grande suporte a editores. Completação em todos os lugares. Menos tempo debugando. +* **Fácil**: Projetado para ser fácil de aprender e usar. Menos tempo lendo docs. * **Enxuto**: Minimize duplicação de código. Múltiplas funcionalidades para cada declaração de parâmetro. Menos bugs. * **Robusto**: Tenha código pronto para produção. E com documentação interativa automática. * **Baseado em padrões**: Baseado em (e totalmente compatível com) os padrões abertos para APIs: OpenAPI (anteriormente conhecido como Swagger) e JSON Schema. @@ -73,7 +73,7 @@ Os recursos chave são: ## Opiniões { #opinions } -"*[...] Estou usando **FastAPI** muito esses dias. [...] Estou na verdade planejando utilizar ele em todos os times de **serviços _Machine Learning_ na Microsoft**. Alguns deles estão sendo integrados no _core_ do produto **Windows** e alguns produtos **Office**.*" +"_[...] Estou usando **FastAPI** muito esses dias. [...] Estou na verdade planejando utilizar ele em todos os times de **serviços ML na Microsoft**. Alguns deles estão sendo integrados no _core_ do produto **Windows** e alguns produtos **Office**._"
Kabir Khan - Microsoft (ref)
@@ -91,39 +91,45 @@ Os recursos chave são: --- -"*Estou extremamente entusiasmado com o **FastAPI**. É tão divertido!*" +"_Estou muito entusiasmado com o **FastAPI**. É tão divertido!_" -
Brian Okken - Python Bytes podcaster (ref)
+
Brian Okken - Python Bytes apresentador do podcast (ref)
--- -"*Honestamente, o que você construiu parece super sólido e rebuscado. De muitas formas, eu queria que o **Hug** fosse assim - é realmente inspirador ver alguém que construiu ele.*" +"_Honestamente, o que você construiu parece super sólido e refinado. De muitas formas, é o que eu queria que o **Hug** fosse - é realmente inspirador ver alguém construir isso._"
Timothy Crosley - criador doHug (ref)
--- -"*Se você está procurando aprender um **_framework_ moderno** para construir aplicações _REST_, dê uma olhada no **FastAPI** [...] É rápido, fácil de usar e fácil de aprender [...]*" +"_Se você está procurando aprender um **framework moderno** para construir APIs REST, dê uma olhada no **FastAPI** [...] É rápido, fácil de usar e fácil de aprender [...]_" -"*Nós trocamos nossas **APIs** por **FastAPI** [...] Acredito que vocês gostarão dele [...]*" +"_Nós trocamos nossas **APIs** por **FastAPI** [...] Acredito que você gostará dele [...]_"
Ines Montani - Matthew Honnibal - fundadores da Explosion AI - criadores da spaCy (ref) - (ref)
--- -"_Se alguém estiver procurando construir uma API Python para produção, eu recomendaria fortemente o **FastAPI**. Ele é **lindamente projetado**, **simples de usar** e **altamente escalável**. Ele se tornou um **componente chave** para a nossa estratégia API first de desenvolvimento e está impulsionando diversas automações e serviços, como o nosso Virtual TAC Engineer._" +"_Se alguém estiver procurando construir uma API Python para produção, eu recomendaria fortemente o **FastAPI**. Ele é **lindamente projetado**, **simples de usar** e **altamente escalável**, e se tornou um **componente chave** para a nossa estratégia de desenvolvimento API first, impulsionando diversas automações e serviços, como o nosso Virtual TAC Engineer._"
Deon Pillsbury - Cisco (ref)
--- +## Mini documentário do FastAPI { #fastapi-mini-documentary } + +Há um mini documentário do FastAPI lançado no fim de 2025, você pode assisti-lo online: + +FastAPI Mini Documentary + ## **Typer**, o FastAPI das interfaces de linhas de comando { #typer-the-fastapi-of-clis } -Se você estiver construindo uma aplicação CLI para ser utilizada em um terminal ao invés de uma aplicação web, dê uma olhada no **Typer**. +Se você estiver construindo uma aplicação CLI para ser utilizada no terminal ao invés de uma API web, dê uma olhada no **Typer**. -**Typer** é o irmão menor do FastAPI. E seu propósito é ser o **FastAPI das _CLIs_**. ⌨️ 🚀 +**Typer** é o irmão menor do FastAPI. E seu propósito é ser o **FastAPI das CLIs**. ⌨️ 🚀 ## Requisitos { #requirements } @@ -255,10 +261,10 @@ Você verá a resposta JSON como: Você acabou de criar uma API que: -* Recebe requisições HTTP nas _rotas_ `/` e `/items/{item_id}`. -* Ambas _rotas_ fazem operações `GET` (também conhecido como _métodos_ HTTP). -* A _rota_ `/items/{item_id}` tem um _parâmetro de rota_ `item_id` que deve ser um `int`. -* A _rota_ `/items/{item_id}` tem um _parâmetro query_ `q` `str` opcional. +* Recebe requisições HTTP nos _paths_ `/` e `/items/{item_id}`. +* Ambos _paths_ fazem operações `GET` (também conhecido como _métodos_ HTTP). +* O _path_ `/items/{item_id}` tem um _parâmetro de path_ `item_id` que deve ser um `int`. +* O _path_ `/items/{item_id}` tem um _parâmetro query_ `q` `str` opcional. ### Documentação Interativa da API { #interactive-api-docs } @@ -278,7 +284,7 @@ Você verá a documentação automática alternativa (fornecida por http://127.0.0.1:8000/redoc. -* A documentação alternativa também irá refletir o novo parâmetro da _query_ e o corpo: +* A documentação alternativa também irá refletir o novo parâmetro query e o corpo: ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) @@ -368,15 +374,15 @@ item: Item * Validação de dados: * Erros automáticos e claros quando o dado é inválido. * Validação até para objetos JSON profundamente aninhados. -* Conversão de dados de entrada: vindo da rede para dados e tipos Python. Consegue ler: +* Conversão de dados de entrada: vindo da rede para dados e tipos Python. Consegue ler: * JSON. - * Parâmetros de rota. - * Parâmetros de _query_ . - * _Cookies_. + * Parâmetros de path. + * Parâmetros query. + * Cookies. * Cabeçalhos. * Formulários. * Arquivos. -* Conversão de dados de saída de tipos e dados Python para dados de rede (como JSON): +* Conversão de dados de saída: convertendo de tipos e dados Python para dados de rede (como JSON): * Converte tipos Python (`str`, `int`, `float`, `bool`, `list` etc). * Objetos `datetime`. * Objetos `UUID`. @@ -390,17 +396,17 @@ item: Item Voltando ao código do exemplo anterior, **FastAPI** irá: -* Validar que existe um `item_id` na rota para requisições `GET` e `PUT`. +* Validar que existe um `item_id` no path para requisições `GET` e `PUT`. * Validar que `item_id` é do tipo `int` para requisições `GET` e `PUT`. - * Se não é validado, o cliente verá um útil, claro erro. -* Verificar se existe um parâmetro de _query_ opcional nomeado como `q` (como em `http://127.0.0.1:8000/items/foo?q=somequery`) para requisições `GET`. + * Se não for, o cliente verá um erro útil e claro. +* Verificar se existe um parâmetro query opcional nomeado como `q` (como em `http://127.0.0.1:8000/items/foo?q=somequery`) para requisições `GET`. * Como o parâmetro `q` é declarado com `= None`, ele é opcional. - * Sem o `None` ele poderia ser obrigatório (como o corpo no caso de `PUT`). + * Sem o `None` ele seria obrigatório (como o corpo no caso de `PUT`). * Para requisições `PUT` para `/items/{item_id}`, lerá o corpo como JSON: * Verifica que tem um atributo obrigatório `name` que deve ser `str`. - * Verifica que tem um atributo obrigatório `price` que deve ser `float`. - * Verifica que tem an atributo opcional `is_offer`, que deve ser `bool`, se presente. - * Tudo isso também funciona para objetos JSON profundamente aninhados. + * Verifica que tem um atributo obrigatório `price` que tem que ser um `float`. + * Verifica que tem um atributo opcional `is_offer`, que deve ser um `bool`, se presente. + * Tudo isso também funcionaria para objetos JSON profundamente aninhados. * Converter de e para JSON automaticamente. * Documentar tudo com OpenAPI, que poderá ser usado por: * Sistemas de documentação interativos. @@ -409,7 +415,7 @@ Voltando ao código do exemplo anterior, **FastAPI** irá: --- -Nós apenas arranhamos a superfície, mas você já tem idéia de como tudo funciona. +Nós apenas arranhamos a superfície, mas você já tem ideia de como tudo funciona. Experimente mudar a seguinte linha: @@ -437,22 +443,22 @@ Para um exemplo mais completo incluindo mais recursos, veja Injeção de Dependência**. -* Segurança e autenticação, incluindo suporte para **OAuth2** com autenticação **JWT tokens** e **HTTP Basic**. +* Declaração de **parâmetros** de diferentes lugares como: **cabeçalhos**, **cookies**, **campos de formulários** e **arquivos**. +* Como configurar **limitações de validação** como `maximum_length` ou `regex`. +* Um poderoso e fácil de usar sistema de **Injeção de Dependência**. +* Segurança e autenticação, incluindo suporte para **OAuth2** com autenticação com **JWT tokens** e **HTTP Basic**. * Técnicas mais avançadas (mas igualmente fáceis) para declaração de **modelos JSON profundamente aninhados** (graças ao Pydantic). * Integrações **GraphQL** com o Strawberry e outras bibliotecas. * Muitos recursos extras (graças ao Starlette) como: * **WebSockets** - * testes extrememamente fáceis baseados em HTTPX e `pytest` + * testes extremamente fáceis baseados em HTTPX e `pytest` * **CORS** * **Cookie Sessions** * ...e mais. ### Implemente sua aplicação (opcional) { #deploy-your-app-optional } -Você pode opcionalmente implantar sua aplicação FastAPI na FastAPI Cloud, inscreva-se na lista de espera se ainda não o fez. 🚀 +Você pode opcionalmente implantar sua aplicação FastAPI na FastAPI Cloud, vá e entre na lista de espera se ainda não o fez. 🚀 Se você já tem uma conta na **FastAPI Cloud** (nós convidamos você da lista de espera 😉), pode implantar sua aplicação com um único comando. @@ -506,7 +512,7 @@ Siga os tutoriais do seu provedor de nuvem para implantar aplicações FastAPI c Testes de performance da _Independent TechEmpower_ mostram aplicações **FastAPI** rodando sob Uvicorn como um dos _frameworks_ Python mais rápidos disponíveis, somente atrás de Starlette e Uvicorn (utilizados internamente pelo FastAPI). (*) -Para entender mais sobre performance, veja a seção Comparações. +Para entender mais sobre isso, veja a seção Comparações. ## Dependências { #dependencies } @@ -514,7 +520,7 @@ O FastAPI depende do Pydantic e do Starlette. ### Dependências `standard` { #standard-dependencies } -Quando você instala o FastAPI com `pip install "fastapi[standard]"`, ele vêm com o grupo `standard` (padrão) de dependências opcionais: +Quando você instala o FastAPI com `pip install "fastapi[standard]"`, ele vem com o grupo `standard` de dependências opcionais: Utilizado pelo Pydantic: @@ -524,7 +530,7 @@ Utilizado pelo Starlette: * httpx - Obrigatório caso você queira utilizar o `TestClient`. * jinja2 - Obrigatório se você quer utilizar a configuração padrão de templates. -* python-multipart - Obrigatório se você deseja suporte a "parsing" de formulário, com `request.form()`. +* python-multipart - Obrigatório se você deseja suporte a "parsing" de formulário, com `request.form()`. Utilizado pelo FastAPI: @@ -547,7 +553,7 @@ Existem algumas dependências adicionais que você pode querer instalar. Dependências opcionais adicionais do Pydantic: * pydantic-settings - para gerenciamento de configurações. -* pydantic-extra-types - tipos extras para serem utilizados com o Pydantic. +* pydantic-extra-types - para tipos extras a serem utilizados com o Pydantic. Dependências opcionais adicionais do FastAPI: diff --git a/docs/pt/docs/tutorial/bigger-applications.md b/docs/pt/docs/tutorial/bigger-applications.md index 9dec7b196..87bd13375 100644 --- a/docs/pt/docs/tutorial/bigger-applications.md +++ b/docs/pt/docs/tutorial/bigger-applications.md @@ -31,7 +31,7 @@ Digamos que você tenha uma estrutura de arquivos como esta: /// tip | Dica -Existem vários arquivos `__init__.py` presentes em cada diretório ou subdiretório. +Existem vários arquivos `__init__.py`: um em cada diretório ou subdiretório. Isso permite a importação de código de um arquivo para outro. @@ -43,32 +43,32 @@ from app.routers import items /// -* O diretório `app` contém todo o código da aplicação. Ele possui um arquivo `app/__init__.py` vazio, o que o torna um "pacote Python" (uma coleção de "módulos Python"): `app`. -* Dentro dele, o arquivo `app/main.py` está localizado em um pacote Python (diretório com `__init__.py`). Portanto, ele é um "módulo" desse pacote: `app.main`. -* Existem também um arquivo `app/dependencies.py`, assim como o `app/main.py`, ele é um "módulo": `app.dependencies`. +* O diretório `app` contém tudo. E possui um arquivo vazio `app/__init__.py`, então ele é um "pacote Python" (uma coleção de "módulos Python"): `app`. +* Ele contém um arquivo `app/main.py`. Como está dentro de um pacote Python (um diretório com um arquivo `__init__.py`), ele é um "módulo" desse pacote: `app.main`. +* Existe também um arquivo `app/dependencies.py`, assim como `app/main.py`, ele é um "módulo": `app.dependencies`. * Há um subdiretório `app/routers/` com outro arquivo `__init__.py`, então ele é um "subpacote Python": `app.routers`. -* O arquivo `app/routers/items.py` está dentro de um pacote, `app/routers/`, portanto, é um "submódulo": `app.routers.items`. -* O mesmo com `app/routers/users.py`, ele é outro submódulo: `app.routers.users`. -* Há também um subdiretório `app/internal/` com outro arquivo `__init__.py`, então ele é outro "subpacote Python":`app.internal`. +* O arquivo `app/routers/items.py` está dentro de um pacote, `app/routers/`, portanto é um submódulo: `app.routers.items`. +* O mesmo com `app/routers/users.py`, ele é outro submódulo: `app.routers.users`. +* Há também um subdiretório `app/internal/` com outro arquivo `__init__.py`, então ele é outro "subpacote Python": `app.internal`. * E o arquivo `app/internal/admin.py` é outro submódulo: `app.internal.admin`. A mesma estrutura de arquivos com comentários: -``` +```bash . -├── app # "app" é um pacote Python -│   ├── __init__.py # este arquivo torna "app" um "pacote Python" -│   ├── main.py # "main" módulo, e.g. import app.main -│   ├── dependencies.py # "dependencies" módulo, e.g. import app.dependencies -│   └── routers # "routers" é um "subpacote Python" -│   │ ├── __init__.py # torna "routers" um "subpacote Python" -│   │ ├── items.py # "items" submódulo, e.g. import app.routers.items -│   │ └── users.py # "users" submódulo, e.g. import app.routers.users -│   └── internal # "internal" é um "subpacote Python" -│   ├── __init__.py # torna "internal" um "subpacote Python" -│   └── admin.py # "admin" submódulo, e.g. import app.internal.admin +├── app # "app" is a Python package +│   ├── __init__.py # this file makes "app" a "Python package" +│   ├── main.py # "main" module, e.g. import app.main +│   ├── dependencies.py # "dependencies" module, e.g. import app.dependencies +│   └── routers # "routers" is a "Python subpackage" +│   │ ├── __init__.py # makes "routers" a "Python subpackage" +│   │ ├── items.py # "items" submodule, e.g. import app.routers.items +│   │ └── users.py # "users" submodule, e.g. import app.routers.users +│   └── internal # "internal" is a "Python subpackage" +│   ├── __init__.py # makes "internal" a "Python subpackage" +│   └── admin.py # "admin" submodule, e.g. import app.internal.admin ``` ## `APIRouter` { #apirouter } @@ -79,11 +79,11 @@ Você quer manter as *operações de rota* relacionadas aos seus usuários separ Mas ele ainda faz parte da mesma aplicação/web API **FastAPI** (faz parte do mesmo "pacote Python"). -Você pode criar as *operações de rotas* para esse módulo usando o `APIRouter`. +Você pode criar as *operações de rota* para esse módulo usando o `APIRouter`. ### Importe `APIRouter` { #import-apirouter } -você o importa e cria uma "instância" da mesma maneira que faria com a classe `FastAPI`: +Você o importa e cria uma "instância" da mesma maneira que faria com a classe `FastAPI`: {* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *} @@ -91,7 +91,7 @@ você o importa e cria uma "instância" da mesma maneira que faria com a classe E então você o utiliza para declarar suas *operações de rota*. -Utilize-o da mesma maneira que utilizaria a classe `FastAPI`: +Utilize-o da mesma maneira que utilizaria a classe `FastAPI`: {* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *} @@ -151,7 +151,7 @@ Então, em vez de adicionar tudo isso a cada *operação de rota*, podemos adici {* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *} -Como o caminho de cada *operação de rota* deve começar com `/`, como em: +Como o path de cada *operação de rota* tem que começar com `/`, como em: ```Python hl_lines="1" @router.get("/{item_id}") @@ -163,9 +163,9 @@ async def read_item(item_id: str): Então, o prefixo neste caso é `/items`. -Também podemos adicionar uma lista de `tags` e `responses` extras que serão aplicadas a todas as *operações de rota* incluídas neste roteador. +Também podemos adicionar uma list de `tags` e `responses` extras que serão aplicadas a todas as *operações de rota* incluídas neste router. -E podemos adicionar uma lista de `dependencies` que serão adicionadas a todas as *operações de rota* no roteador e serão executadas/resolvidas para cada request feita a elas. +E podemos adicionar uma list de `dependencies` que serão adicionadas a todas as *operações de rota* no router e serão executadas/resolvidas para cada request feita a elas. /// tip | Dica @@ -173,7 +173,7 @@ Observe que, assim como [dependências em *decoradores de operação de rota*](d /// -O resultado final é que os caminhos dos itens agora são: +O resultado final é que os paths dos itens agora são: * `/items/` * `/items/{item_id}` @@ -183,9 +183,9 @@ O resultado final é que os caminhos dos itens agora são: * Elas serão marcadas com uma lista de tags que contêm uma única string `"items"`. * Essas "tags" são especialmente úteis para os sistemas de documentação interativa automática (usando OpenAPI). * Todas elas incluirão as `responses` predefinidas. -* Todas essas *operações de rota* terão a lista de `dependencies` avaliada/executada antes delas. +* Todas essas *operações de rota* terão a list de `dependencies` avaliada/executada antes delas. * Se você também declarar dependências em uma *operação de rota* específica, **elas também serão executadas**. - * As dependências do roteador são executadas primeiro, depois as [`dependencies` no decorador](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank} e, em seguida, as dependências de parâmetros normais. + * As dependências do router são executadas primeiro, depois as [`dependencies` no decorador](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank} e, em seguida, as dependências de parâmetros normais. * Você também pode adicionar [dependências de `Segurança` com `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}. /// tip | Dica @@ -246,7 +246,7 @@ from ..dependencies import get_token_header significa: -* Começando no mesmo pacote em que este módulo (o arquivo `app/routers/items.py`) reside (o diretório `app/routers/`)... +* Começando no mesmo pacote em que este módulo (o arquivo `app/routers/items.py`) vive (o diretório `app/routers/`)... * vá para o pacote pai (o diretório `app/`)... * e lá, encontre o módulo `dependencies` (o arquivo em `app/dependencies.py`)... * e dele, importe a função `get_token_header`. @@ -283,9 +283,9 @@ Mas ainda podemos adicionar _mais_ `tags` que serão aplicadas a uma *operação /// tip | Dica -Esta última operação de caminho terá a combinação de tags: `["items", "custom"]`. +Esta última operação de rota terá a combinação de tags: `["items", "custom"]`. -E também terá ambas as respostas na documentação, uma para `404` e uma para `403`. +E também terá ambas as responses na documentação, uma para `404` e uma para `403`. /// @@ -325,7 +325,7 @@ from .routers import items, users significa: -* Começando no mesmo pacote em que este módulo (o arquivo `app/main.py`) reside (o diretório `app/`)... +* Começando no mesmo pacote em que este módulo (o arquivo `app/main.py`) vive (o diretório `app/`)... * procure o subpacote `routers` (o diretório em `app/routers/`)... * e dele, importe o submódulo `items` (o arquivo em `app/routers/items.py`) e `users` (o arquivo em `app/routers/users.py`)... @@ -376,7 +376,7 @@ Então, para poder usar ambos no mesmo arquivo, importamos os submódulos direta {* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *} -### Inclua os `APIRouter`s para `usuários` e `itens` { #include-the-apirouters-for-users-and-items } +### Inclua os `APIRouter`s para `users` e `items` { #include-the-apirouters-for-users-and-items } Agora, vamos incluir os `router`s dos submódulos `users` e `items`: @@ -392,7 +392,7 @@ E `items.router` contém o `APIRouter` dentro do arquivo `app/routers/items.py`. Com `app.include_router()` podemos adicionar cada `APIRouter` ao aplicativo principal `FastAPI`. -Ele incluirá todas as rotas daquele roteador como parte dele. +Ele incluirá todas as rotas daquele router como parte dele. /// note | Detalhes Técnicos @@ -404,7 +404,7 @@ Então, nos bastidores, ele realmente funcionará como se tudo fosse o mesmo apl /// check | Verifique -Você não precisa se preocupar com desempenho ao incluir roteadores. +Você não precisa se preocupar com desempenho ao incluir routers. Isso levará microssegundos e só acontecerá na inicialização. @@ -453,7 +453,7 @@ e funcionará corretamente, junto com todas as outras *operações de rota* adic /// note | Detalhes Técnicos Avançados -**Observação**: este é um detalhe muito técnico que você provavelmente pode **simplesmente pular**. +**Nota**: este é um detalhe muito técnico que você provavelmente pode **simplesmente pular**. --- @@ -479,15 +479,15 @@ $ fastapi dev app/main.py -E abra os documentos em http://127.0.0.1:8000/docs. +E abra a documentação em http://127.0.0.1:8000/docs. -Você verá a documentação automática da API, incluindo os caminhos de todos os submódulos, usando os caminhos (e prefixos) corretos e as tags corretas: +Você verá a documentação automática da API, incluindo os paths de todos os submódulos, usando os paths (e prefixos) corretos e as tags corretas: -## Inclua o mesmo roteador várias vezes com `prefix` diferentes { #include-the-same-router-multiple-times-with-different-prefix } +## Inclua o mesmo router várias vezes com `prefix` diferentes { #include-the-same-router-multiple-times-with-different-prefix } -Você também pode usar `.include_router()` várias vezes com o *mesmo* roteador usando prefixos diferentes. +Você também pode usar `.include_router()` várias vezes com o *mesmo* router usando prefixos diferentes. Isso pode ser útil, por exemplo, para expor a mesma API sob prefixos diferentes, por exemplo, `/api/v1` e `/api/latest`. @@ -495,10 +495,10 @@ Esse é um uso avançado que você pode não precisar, mas está lá caso precis ## Inclua um `APIRouter` em outro { #include-an-apirouter-in-another } -Da mesma forma que você pode incluir um `APIRouter` em um aplicativo `FastAPI`, você pode incluir um `APIRouter` em outro `APIRouter` usando: +Da mesma forma que você pode incluir um `APIRouter` em uma aplicação `FastAPI`, você pode incluir um `APIRouter` em outro `APIRouter` usando: ```Python router.include_router(other_router) ``` -Certifique-se de fazer isso antes de incluir `router` no aplicativo `FastAPI`, para que as *operações de rota* de `other_router` também sejam incluídas. +Certifique-se de fazer isso antes de incluir `router` na aplicação `FastAPI`, para que as *operações de rota* de `other_router` também sejam incluídas. diff --git a/docs/pt/docs/tutorial/body-updates.md b/docs/pt/docs/tutorial/body-updates.md index 67bf68492..95f89c8d2 100644 --- a/docs/pt/docs/tutorial/body-updates.md +++ b/docs/pt/docs/tutorial/body-updates.md @@ -1,6 +1,6 @@ # Corpo - Atualizações { #body-updates } -## Atualização de dados existentes com `PUT` { #update-replacing-with-put } +## Atualização substituindo com `PUT` { #update-replacing-with-put } Para atualizar um item, você pode usar a operação HTTP `PUT`. @@ -22,13 +22,13 @@ Isso significa que, se você quiser atualizar o item `bar` usando `PUT` com um c } ``` -Como ele não inclui o atributo já armazenado `"tax": 20.2`, o modelo de entrada assumiria o valor padrão de `"tax": 10.5`. +como ele não inclui o atributo já armazenado `"tax": 20.2`, o modelo de entrada assumiria o valor padrão de `"tax": 10.5`. E os dados seriam salvos com esse "novo" `tax` de `10.5`. ## Atualizações parciais com `PATCH` { #partial-updates-with-patch } -Você também pode usar a operação HTTP `PATCH` para atualizar parcialmente os dados. +Você também pode usar a operação HTTP `PATCH` para atualizar dados *parcialmente*. Isso significa que você pode enviar apenas os dados que deseja atualizar, deixando o restante intacto. @@ -40,25 +40,17 @@ E muitas equipes usam apenas `PUT`, mesmo para atualizações parciais. Você é **livre** para usá-los como preferir, **FastAPI** não impõe restrições. -Mas este guia te dá uma ideia de como eles são destinados a serem usados. +Mas este guia mostra, mais ou menos, como eles são destinados a serem usados. /// ### Usando o parâmetro `exclude_unset` do Pydantic { #using-pydantics-exclude-unset-parameter } -Se você quiser receber atualizações parciais, é muito útil usar o parâmetro `exclude_unset` no método `.model_dump()` do modelo do Pydantic. +Se você quiser receber atualizações parciais, é muito útil usar o parâmetro `exclude_unset` no `.model_dump()` do modelo do Pydantic. Como `item.model_dump(exclude_unset=True)`. -/// info | Informação - -No Pydantic v1, o método que era chamado `.dict()` e foi descontinuado (mas ainda suportado) no Pydantic v2. Agora, deve-se usar o método `.model_dump()`. - -Os exemplos aqui usam `.dict()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_dump()` a partir do Pydantic v2. - -/// - -Isso gera um `dict` com apenas os dados definidos ao criar o modelo `item`, excluindo os valores padrão. +Isso geraria um `dict` com apenas os dados que foram definidos ao criar o modelo `item`, excluindo os valores padrão. Então, você pode usar isso para gerar um `dict` com apenas os dados definidos (enviados na solicitação), omitindo valores padrão: @@ -68,31 +60,23 @@ Então, você pode usar isso para gerar um `dict` com apenas os dados definidos Agora, você pode criar uma cópia do modelo existente usando `.model_copy()`, e passar o parâmetro `update` com um `dict` contendo os dados para atualizar. -/// info | Informação - -No Pydantic v1, o método era chamado `.copy()`, ele foi descontinuado (mas ainda suportado) no Pydantic v2, e renomeado para `.model_copy()`. - -Os exemplos aqui usam `.copy()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_copy()` com o Pydantic v2. - -/// - Como `stored_item_model.model_copy(update=update_data)`: {* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *} ### Recapitulando as atualizações parciais { #partial-updates-recap } -Resumindo, para aplicar atualizações parciais você pode: +Resumindo, para aplicar atualizações parciais você deveria: * (Opcionalmente) usar `PATCH` em vez de `PUT`. * Recuperar os dados armazenados. * Colocar esses dados em um modelo do Pydantic. * Gerar um `dict` sem valores padrão a partir do modelo de entrada (usando `exclude_unset`). - * Dessa forma, você pode atualizar apenas os valores definidos pelo usuário, em vez de substituir os valores já armazenados com valores padrão em seu modelo. + * Dessa forma, você pode atualizar apenas os valores realmente definidos pelo usuário, em vez de substituir valores já armazenados por valores padrão do modelo. * Criar uma cópia do modelo armazenado, atualizando seus atributos com as atualizações parciais recebidas (usando o parâmetro `update`). -* Converter o modelo copiado em algo que possa ser armazenado no seu banco de dados (por exemplo, usando o `jsonable_encoder`). - * Isso é comparável ao uso do método `.model_dump()`, mas garante (e converte) os valores para tipos de dados que possam ser convertidos em JSON, por exemplo, `datetime` para `str`. -* Salvar os dados no seu banco de dados. +* Converter o modelo copiado em algo que possa ser armazenado no seu BD (por exemplo, usando o `jsonable_encoder`). + * Isso é comparável a usar o método `.model_dump()` do modelo novamente, mas garante (e converte) os valores para tipos de dados que possam ser convertidos em JSON, por exemplo, `datetime` para `str`. +* Salvar os dados no seu BD. * Retornar o modelo atualizado. {* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *} @@ -109,8 +93,8 @@ Mas o exemplo aqui usa `PATCH` porque foi criado para esses casos de uso. Observe que o modelo de entrada ainda é validado. -Portanto, se você quiser receber atualizações parciais que possam omitir todos os atributos, precisará ter um modelo com todos os atributos marcados como opcionais (com valores padrão ou `None`). +Portanto, se você quiser receber atualizações parciais que possam omitir todos os atributos, você precisa ter um modelo com todos os atributos marcados como opcionais (com valores padrão ou `None`). -Para distinguir os modelos com todos os valores opcionais para **atualizações** e modelos com valores obrigatórios para **criação**, você pode usar as ideias descritas em [Modelos Adicionais](extra-models.md){.internal-link target=_blank}. +Para distinguir entre os modelos com todos os valores opcionais para **atualizações** e modelos com valores obrigatórios para **criação**, você pode usar as ideias descritas em [Modelos Adicionais](extra-models.md){.internal-link target=_blank}. /// diff --git a/docs/pt/docs/tutorial/body.md b/docs/pt/docs/tutorial/body.md index 1330f4458..669334439 100644 --- a/docs/pt/docs/tutorial/body.md +++ b/docs/pt/docs/tutorial/body.md @@ -10,11 +10,11 @@ Para declarar um corpo da **requisição**, você utiliza os modelos do 0.95.0) exigiam que você usasse `Query` como valor padrão do seu parâmetro, em vez de colocá-lo em `Annotated`. É muito provável que você veja código assim por aí, então vou te explicar. +Versões anteriores do FastAPI (antes de 0.95.0) exigiam que você usasse `Query` como valor padrão do seu parâmetro, em vez de colocá-lo em `Annotated`, há uma grande chance de você ver código usando isso por aí, então vou explicar. /// tip | Dica @@ -192,7 +192,7 @@ Você também pode adicionar um parâmetro `min_length`: ## Adicione expressões regulares { #add-regular-expressions } -Você pode definir um `pattern` de expressão regular que o parâmetro deve corresponder: +Você pode definir um `pattern` de expressão regular que o parâmetro deve corresponder: {* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *} @@ -206,20 +206,6 @@ Se você se sentir perdido com essas ideias de **"expressão regular"**, não se Agora você sabe que, sempre que precisar delas, pode usá-las no **FastAPI**. -### Pydantic v1 `regex` em vez de `pattern` { #pydantic-v1-regex-instead-of-pattern } - -Antes da versão 2 do Pydantic e antes do FastAPI 0.100.0, o parâmetro se chamava `regex` em vez de `pattern`, mas agora está descontinuado. - -Você ainda pode ver algum código usando isso: - -//// tab | Pydantic v1 - -{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *} - -//// - -Mas saiba que isso está descontinuado e deve ser atualizado para usar o novo parâmetro `pattern`. 🤓 - ## Valores padrão { #default-values } Você pode, claro, usar valores padrão diferentes de `None`. @@ -280,7 +266,7 @@ Então, com uma URL como: http://localhost:8000/items/?q=foo&q=bar ``` -você receberá os múltiplos valores do *parâmetro de consulta* `q` (`foo` e `bar`) em uma `list` Python dentro da sua *função de operação de rota*, no *parâmetro da função* `q`. +você receberia os múltiplos valores dos *parâmetros de consulta* `q` (`foo` e `bar`) em uma `list` Python dentro da sua *função de operação de rota*, no *parâmetro da função* `q`. Assim, a resposta para essa URL seria: @@ -350,7 +336,7 @@ Essas informações serão incluídas no OpenAPI gerado e usadas pelas interface Tenha em mente que ferramentas diferentes podem ter níveis diferentes de suporte ao OpenAPI. -Algumas delas podem ainda não mostrar todas as informações extras declaradas, embora na maioria dos casos o recurso ausente já esteja planejado para desenvolvimento. +Algumas delas podem ainda não mostrar todas as informações extras declaradas, embora na maioria dos casos a funcionalidade ausente já esteja planejada para desenvolvimento. /// @@ -386,7 +372,7 @@ Então você pode declarar um `alias`, e esse alias será usado para encontrar o Agora digamos que você não gosta mais desse parâmetro. -Você tem que deixá-lo por um tempo, pois há clientes usando-o, mas quer que a documentação mostre claramente que ele está descontinuado. +Você tem que deixá-lo por um tempo, pois há clientes usando-o, mas quer que a documentação mostre claramente que ele está deprecated. Então passe o parâmetro `deprecated=True` para `Query`: @@ -416,7 +402,7 @@ O Pydantic também tem ISBN ou com `imdb-` para um ID de URL de filme IMDB: +Por exemplo, este validador personalizado verifica se o ID do item começa com `isbn-` para um número de livro ISBN ou com `imdb-` para um ID de URL de filme IMDB: {* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *} @@ -428,7 +414,7 @@ Isso está disponível com a versão 2 do Pydantic ou superior. 😎 /// tip | Dica -Se você precisar fazer qualquer tipo de validação que exija comunicação com algum **componente externo**, como um banco de dados ou outra API, você deve usar **Dependências do FastAPI** em vez disso; você aprenderá sobre elas mais adiante. +Se você precisar fazer qualquer tipo de validação que exija comunicação com algum **componente externo**, como um banco de dados ou outra API, você deveria usar **Dependências do FastAPI** em vez disso; você aprenderá sobre elas mais adiante. Esses validadores personalizados são para coisas que podem ser verificadas **apenas** com os **mesmos dados** fornecidos na requisição. @@ -440,7 +426,7 @@ O ponto importante é apenas usar **`AfterValidator` com uma função dentro de --- -Mas se você está curioso sobre este exemplo específico e ainda entretido, aqui vão alguns detalhes extras. +Mas se você estiver curioso sobre este exemplo de código específico e ainda entretido, aqui vão alguns detalhes extras. #### String com `value.startswith()` { #string-with-value-startswith } @@ -450,7 +436,7 @@ Percebeu? Uma string usando `value.startswith()` pode receber uma tupla, e verif #### Um item aleatório { #a-random-item } -Com `data.items()` obtemos um objeto iterável com tuplas contendo a chave e o valor de cada item do dicionário. +Com `data.items()` obtemos um objeto iterável com tuplas contendo a chave e o valor de cada item do dicionário. Convertimos esse objeto iterável em uma `list` adequada com `list(data.items())`. diff --git a/docs/pt/docs/tutorial/response-model.md b/docs/pt/docs/tutorial/response-model.md index dc66bb46c..8a7a71248 100644 --- a/docs/pt/docs/tutorial/response-model.md +++ b/docs/pt/docs/tutorial/response-model.md @@ -252,20 +252,6 @@ Então, se você enviar uma solicitação para essa *operação de rota* para o /// info | Informação -No Pydantic v1, o método era chamado `.dict()`, ele foi descontinuado (mas ainda suportado) no Pydantic v2 e renomeado para `.model_dump()`. - -Os exemplos aqui usam `.dict()` para compatibilidade com Pydantic v1, mas você deve usar `.model_dump()` em vez disso se puder usar Pydantic v2. - -/// - -/// info | Informação - -O FastAPI usa `.dict()` do modelo Pydantic com seu parâmetro `exclude_unset` para chegar a isso. - -/// - -/// info | Informação - Você também pode usar: * `response_model_exclude_defaults=True` diff --git a/docs/pt/docs/tutorial/schema-extra-example.md b/docs/pt/docs/tutorial/schema-extra-example.md index bddd320cd..2d62ffd85 100644 --- a/docs/pt/docs/tutorial/schema-extra-example.md +++ b/docs/pt/docs/tutorial/schema-extra-example.md @@ -8,39 +8,17 @@ Aqui estão várias maneiras de fazer isso. Você pode declarar `examples` para um modelo Pydantic que serão adicionados ao JSON Schema gerado. -//// tab | Pydantic v2 - {* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *} -//// - -//// tab | Pydantic v1 - -{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *} - -//// - Essas informações extras serão adicionadas como estão ao **JSON Schema** de saída para esse modelo e serão usadas na documentação da API. -//// tab | Pydantic v2 - -Na versão 2 do Pydantic, você usaria o atributo `model_config`, que recebe um `dict`, conforme descrito na documentação do Pydantic: Configuration. +Você pode usar o atributo `model_config`, que recebe um `dict`, conforme descrito na documentação do Pydantic: Configuration. Você pode definir `"json_schema_extra"` com um `dict` contendo quaisquer dados adicionais que você queira que apareçam no JSON Schema gerado, incluindo `examples`. -//// - -//// tab | Pydantic v1 - -Na versão 1 do Pydantic, você usaria uma classe interna `Config` e `schema_extra`, conforme descrito na documentação do Pydantic: Schema customization. - -Você pode definir `schema_extra` com um `dict` contendo quaisquer dados adicionais que você queira que apareçam no JSON Schema gerado, incluindo `examples`. - -//// - /// tip | Dica -Você pode usar a mesma técnica para estender o JSON Schema e adicionar suas próprias informações extras personalizadas. +Você poderia usar a mesma técnica para estender o JSON Schema e adicionar suas próprias informações extras personalizadas. Por exemplo, você poderia usá-la para adicionar metadados para uma interface de usuário de front-end, etc. @@ -50,7 +28,7 @@ Por exemplo, você poderia usá-la para adicionar metadados para uma interface d O OpenAPI 3.1.0 (usado desde o FastAPI 0.99.0) adicionou suporte a `examples`, que faz parte do padrão **JSON Schema**. -Antes disso, ele suportava apenas a palavra‑chave `example` com um único exemplo. Isso ainda é suportado pelo OpenAPI 3.1.0, mas é descontinuado e não faz parte do padrão JSON Schema. Portanto, é recomendado migrar de `example` para `examples`. 🤓 +Antes disso, ele suportava apenas a palavra‑chave `example` com um único exemplo. Isso ainda é suportado pelo OpenAPI 3.1.0, mas é descontinuado e não faz parte do padrão JSON Schema. Portanto, você é incentivado a migrar de `example` para `examples`. 🤓 Você pode ler mais no final desta página. @@ -102,7 +80,7 @@ No entanto, no momento em que isto foi escrito, Antes do **JSON Schema** suportar `examples`, o OpenAPI já tinha suporte para um campo diferente também chamado `examples`. -Esse `examples` específico do OpenAPI vai em outra seção da especificação. Ele fica nos **detalhes de cada função de operação de rota**, não dentro de cada JSON Schema. +Esse `examples` **específico do OpenAPI** vai em outra seção da especificação OpenAPI. Ele fica nos **detalhes de cada *operação de rota***, não dentro de cada JSON Schema. E o Swagger UI tem suportado esse campo `examples` particular há algum tempo. Então, você pode usá-lo para **mostrar** diferentes **exemplos na UI da documentação**. @@ -189,9 +167,9 @@ Depois, o JSON Schema adicionou um campo LLM, переводящая документацию, `general_prompt` в `scripts/translate.py` и языковой специфичный промпт в `docs/{language code}/llm-prompt.md`. Языковой специфичный промпт добавляется к `general_prompt`. +Этот документ проверяет, понимает ли LLM, переводящая документацию, `general_prompt` в `scripts/translate.py` и языковой специфичный промпт в `docs/{language code}/llm-prompt.md`. Языковой специфичный промпт добавляется к `general_prompt`. -Тесты, добавленные здесь, увидят все создатели языковых промптов. +Тесты, добавленные здесь, увидят все создатели языковых специфичных промптов. Использование: @@ -11,7 +11,7 @@ * Проверьте, всё ли в порядке в переводе. * При необходимости улучшите ваш языковой специфичный промпт, общий промпт или английский документ. * Затем вручную исправьте оставшиеся проблемы в переводе, чтобы он был хорошим. -* Переведите заново, имея хороший перевод на месте. Идеальным результатом будет ситуация, когда LLM больше не вносит изменений в перевод. Это означает, что общий промпт и ваш языковой специфичный промпт максимально хороши (иногда он будет делать несколько, казалось бы, случайных изменений, причина в том, что LLM — недетерминированные алгоритмы). +* Переведите заново, имея хороший перевод на месте. Идеальным результатом будет ситуация, когда LLM больше не вносит изменений в перевод. Это означает, что общий промпт и ваш языковой специфичный промпт настолько хороши, насколько это возможно (иногда он будет делать несколько, казалось бы, случайных изменений, причина в том, что LLM — недетерминированные алгоритмы). Тесты: @@ -197,15 +197,15 @@ works(foo="bar") # Это работает 🎉 ### abbr даёт полную расшифровку { #the-abbr-gives-a-full-phrase } -* GTD -* lt -* XWT -* PSGI +* GTD +* lt +* XWT +* PSGI ### abbr даёт полную расшифровку и объяснение { #the-abbr-gives-a-full-phrase-and-an-explanation } -* MDN -* I/O. +* MDN +* I/O. //// diff --git a/docs/ru/docs/advanced/path-operation-advanced-configuration.md b/docs/ru/docs/advanced/path-operation-advanced-configuration.md index eaf9ad052..86d3a5b63 100644 --- a/docs/ru/docs/advanced/path-operation-advanced-configuration.md +++ b/docs/ru/docs/advanced/path-operation-advanced-configuration.md @@ -14,7 +14,7 @@ {* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *} -### Использование имени функции-обработчика пути как operationId { #using-the-path-operation-function-name-as-the-operationid } +### Использование имени *функции-обработчика пути* как operationId { #using-the-path-operation-function-name-as-the-operationid } Если вы хотите использовать имена функций ваших API в качестве `operationId`, вы можете пройти по всем из них и переопределить `operation_id` каждой *операции пути* с помощью их `APIRoute.name`. @@ -38,7 +38,7 @@ ## Исключить из OpenAPI { #exclude-from-openapi } -Чтобы исключить *операцию пути* из генерируемой схемы OpenAPI (а значит, и из автоматической документации), используйте параметр `include_in_schema` и установите его в `False`: +Чтобы исключить *операцию пути* из генерируемой схемы OpenAPI (а значит, и из автоматических систем документации), используйте параметр `include_in_schema` и установите его в `False`: {* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *} @@ -48,7 +48,7 @@ Добавление `\f` (экранированного символа «form feed») заставит **FastAPI** обрезать текст, используемый для OpenAPI, в этой точке. -Эта часть не попадёт в документацию, но другие инструменты (например, Sphinx) смогут использовать остальное. +Это не отобразится в документации, но другие инструменты (например, Sphinx) смогут использовать остальное. {* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *} @@ -56,7 +56,7 @@ Вы, вероятно, уже видели, как объявлять `response_model` и `status_code` для *операции пути*. -Это определяет метаданные об основном ответе *операции пути*. +Это определяет метаданные об основном HTTP-ответе *операции пути*. Также можно объявлять дополнительные ответы с их моделями, статус-кодами и т.д. @@ -76,7 +76,7 @@ Там есть `tags`, `parameters`, `requestBody`, `responses` и т.д. -Эта спецификация OpenAPI, специфичная для *операции пути*, обычно генерируется автоматически **FastAPI**, но вы также можете её расширить. +Эта специфичная для *операции пути* схема OpenAPI обычно генерируется автоматически **FastAPI**, но вы также можете её расширить. /// tip | Совет @@ -129,13 +129,13 @@ } ``` -### Пользовательская схема OpenAPI для операции пути { #custom-openapi-path-operation-schema } +### Пользовательская схема OpenAPI для *операции пути* { #custom-openapi-path-operation-schema } -Словарь в `openapi_extra` будет объединён с автоматически сгенерированной схемой OpenAPI для *операции пути*. +Словарь в `openapi_extra` будет глубоко объединён с автоматически сгенерированной схемой OpenAPI для *операции пути*. Таким образом, вы можете добавить дополнительные данные к автоматически сгенерированной схеме. -Например, вы можете решить читать и валидировать запрос своим кодом, не используя автоматические возможности FastAPI и Pydantic, но при этом захотите описать запрос в схеме OpenAPI. +Например, вы можете решить читать и валидировать HTTP-запрос своим кодом, не используя автоматические возможности FastAPI и Pydantic, но при этом захотите описать HTTP-запрос в схеме OpenAPI. Это можно сделать с помощью `openapi_extra`: @@ -149,52 +149,20 @@ Используя тот же приём, вы можете воспользоваться Pydantic-моделью, чтобы определить JSON Schema, которая затем будет включена в пользовательский раздел схемы OpenAPI для *операции пути*. -И вы можете сделать это, даже если тип данных в запросе — не JSON. +И вы можете сделать это, даже если тип данных в HTTP-запросе — не JSON. -Например, в этом приложении мы не используем встроенную функциональность FastAPI для извлечения JSON Schema из моделей Pydantic, равно как и автоматическую валидацию JSON. Мы объявляем тип содержимого запроса как YAML, а не JSON: - -//// tab | Pydantic v2 +Например, в этом приложении мы не используем встроенную функциональность FastAPI для извлечения JSON Schema из моделей Pydantic, равно как и автоматическую валидацию JSON. Мы объявляем тип содержимого HTTP-запроса как YAML, а не JSON: {* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *} -//// - -//// tab | Pydantic v1 - -{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *} - -//// - -/// info | Информация - -В Pydantic версии 1 метод для получения JSON Schema модели назывался `Item.schema()`, в Pydantic версии 2 метод называется `Item.model_json_schema()`. - -/// - Тем не менее, хотя мы не используем встроенную функциональность по умолчанию, мы всё равно используем Pydantic-модель, чтобы вручную сгенерировать JSON Schema для данных, которые мы хотим получить в YAML. -Затем мы работаем с запросом напрямую и извлекаем тело как `bytes`. Это означает, что FastAPI даже не попытается распарсить полезную нагрузку запроса как JSON. +Затем мы работаем с HTTP-запросом напрямую и извлекаем тело как `bytes`. Это означает, что FastAPI даже не попытается распарсить полезную нагрузку HTTP-запроса как JSON. -А затем в нашем коде мы напрямую парсим этот YAML и снова используем ту же Pydantic-модель для валидации YAML-содержимого: - -//// tab | Pydantic v2 +А затем в нашем коде мы напрямую парсим это содержимое YAML и снова используем ту же Pydantic-модель, чтобы валидировать YAML-содержимое: {* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *} -//// - -//// tab | Pydantic v1 - -{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *} - -//// - -/// info | Информация - -В Pydantic версии 1 метод для парсинга и валидации объекта назывался `Item.parse_obj()`, в Pydantic версии 2 метод называется `Item.model_validate()`. - -/// - /// tip | Совет Здесь мы переиспользуем ту же Pydantic-модель. diff --git a/docs/ru/docs/advanced/settings.md b/docs/ru/docs/advanced/settings.md index b96ee44a3..8408faebf 100644 --- a/docs/ru/docs/advanced/settings.md +++ b/docs/ru/docs/advanced/settings.md @@ -46,12 +46,6 @@ $ pip install "fastapi[all]" -/// info | Информация - -В Pydantic v1 он входил в основной пакет. Теперь он распространяется как отдельный пакет, чтобы вы могли установить его только при необходимости. - -/// - ### Создание объекта `Settings` { #create-the-settings-object } Импортируйте `BaseSettings` из Pydantic и создайте подкласс, очень похожий на Pydantic‑модель. @@ -60,24 +54,8 @@ $ pip install "fastapi[all]" Вы можете использовать все те же возможности валидации и инструменты, что и для Pydantic‑моделей, например разные типы данных и дополнительную валидацию через `Field()`. -//// tab | Pydantic v2 - {* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *} -//// - -//// tab | Pydantic v1 - -/// info | Информация - -В Pydantic v1 вы бы импортировали `BaseSettings` напрямую из `pydantic`, а не из `pydantic_settings`. - -/// - -{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *} - -//// - /// tip | Совет Если вам нужно что-то быстро скопировать и вставить, не используйте этот пример — воспользуйтесь последним ниже. @@ -215,8 +193,6 @@ APP_NAME="ChimichangApp" Затем обновите ваш `config.py` так: -//// tab | Pydantic v2 - {* ../../docs_src/settings/app03_an_py39/config.py hl[9] *} /// tip | Совет @@ -225,26 +201,6 @@ APP_NAME="ChimichangApp" /// -//// - -//// tab | Pydantic v1 - -{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *} - -/// tip | Совет - -Класс `Config` используется только для конфигурации Pydantic. Подробнее см. Pydantic Model Config. - -/// - -//// - -/// info | Информация - -В Pydantic версии 1 конфигурация задавалась во внутреннем классе `Config`, в Pydantic версии 2 — в атрибуте `model_config`. Этот атрибут принимает `dict`, и чтобы получить автозавершение и ошибки «на лету», вы можете импортировать и использовать `SettingsConfigDict` для описания этого `dict`. - -/// - Здесь мы задаем параметр конфигурации `env_file` внутри вашего класса Pydantic `Settings` и устанавливаем значение равным имени файла dotenv, который хотим использовать. ### Создание `Settings` только один раз с помощью `lru_cache` { #creating-the-settings-only-once-with-lru-cache } diff --git a/docs/ru/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md b/docs/ru/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md index 95481bc66..2b47c08f6 100644 --- a/docs/ru/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md +++ b/docs/ru/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md @@ -2,21 +2,23 @@ Если у вас старое приложение FastAPI, возможно, вы используете Pydantic версии 1. -FastAPI поддерживает и Pydantic v1, и v2 начиная с версии 0.100.0. +FastAPI версии 0.100.0 поддерживал либо Pydantic v1, либо v2. Он использовал ту версию, которая была установлена. -Если у вас был установлен Pydantic v2, использовался он. Если вместо этого был установлен Pydantic v1 — использовался он. +FastAPI версии 0.119.0 добавил частичную поддержку Pydantic v1 изнутри Pydantic v2 (как `pydantic.v1`), чтобы упростить миграцию на v2. -Сейчас Pydantic v1 объявлен устаревшим, и поддержка его будет удалена в следующих версиях FastAPI, поэтому вам следует **перейти на Pydantic v2**. Так вы получите последние возможности, улучшения и исправления. +FastAPI 0.126.0 убрал поддержку Pydantic v1, при этом ещё некоторое время продолжал поддерживать `pydantic.v1`. /// warning | Предупреждение -Кроме того, команда Pydantic прекратила поддержку Pydantic v1 для последних версий Python, начиная с **Python 3.14**. +Команда Pydantic прекратила поддержку Pydantic v1 для последних версий Python, начиная с **Python 3.14**. + +Это включает `pydantic.v1`, который больше не поддерживается в Python 3.14 и выше. Если вы хотите использовать последние возможности Python, вам нужно убедиться, что вы используете Pydantic v2. /// -Если у вас старое приложение FastAPI с Pydantic v1, здесь я покажу, как мигрировать на Pydantic v2, и **новые возможности в FastAPI 0.119.0**, которые помогут выполнить постепенную миграцию. +Если у вас старое приложение FastAPI с Pydantic v1, здесь я покажу, как мигрировать на Pydantic v2, и **возможности FastAPI 0.119.0**, которые помогут выполнить постепенную миграцию. ## Официальное руководство { #official-guide } @@ -38,13 +40,13 @@ FastAPI поддерживает и Pydantic v1, и v2 начиная с вер Вы можете использовать `bump-pydantic` от той же команды Pydantic. -Этот инструмент поможет автоматически внести большую часть необходимых изменений в код. +Этот инструмент поможет автоматически изменить большую часть кода, который нужно изменить. -После этого запустите тесты и проверьте, что всё работает. Если да — на этом всё. 😎 +После этого вы можете запустить тесты и проверить, что всё работает. Если да — на этом всё. 😎 ## Pydantic v1 в v2 { #pydantic-v1-in-v2 } -Pydantic v2 включает всё из Pydantic v1 как подмодуль `pydantic.v1`. +Pydantic v2 включает всё из Pydantic v1 как подмодуль `pydantic.v1`. Но это больше не поддерживается в версиях Python выше 3.13. Это означает, что вы можете установить последнюю версию Pydantic v2 и импортировать и использовать старые компоненты Pydantic v1 из этого подмодуля так, как если бы у вас был установлен старый Pydantic v1. @@ -52,7 +54,7 @@ Pydantic v2 включает всё из Pydantic v1 как подмодуль ` ### Поддержка FastAPI для Pydantic v1 внутри v2 { #fastapi-support-for-pydantic-v1-in-v2 } -Начиная с FastAPI 0.119.0, есть также частичная поддержка Pydantic v1 в составе Pydantic v2, чтобы упростить миграцию на v2. +Начиная с FastAPI 0.119.0, есть также частичная поддержка Pydantic v1 изнутри Pydantic v2, чтобы упростить миграцию на v2. Таким образом, вы можете обновить Pydantic до последней версии 2 и сменить импорты на подмодуль `pydantic.v1` — во многих случаях всё просто заработает. @@ -106,7 +108,7 @@ graph TB style V2Field fill:#f9fff3 ``` -В некоторых случаях можно использовать и модели Pydantic v1, и v2 в одной и той же операции пути (обработчике пути) вашего приложения FastAPI: +В некоторых случаях можно использовать и модели Pydantic v1, и v2 в одной и той же **операции пути** (обработчике пути) вашего приложения FastAPI: {* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *} @@ -122,12 +124,12 @@ graph TB /// tip | Совет -Сначала попробуйте `bump-pydantic`. Если тесты проходят и всё работает, вы справились одной командой. ✨ +Сначала попробуйте `bump-pydantic`: если тесты проходят и всё работает, вы справились одной командой. ✨ /// Если `bump-pydantic` не подходит для вашего случая, вы можете использовать поддержку одновременной работы моделей Pydantic v1 и v2 в одном приложении, чтобы мигрировать на Pydantic v2 постепенно. -Сначала обновите Pydantic до последней 2-й версии и измените импорты так, чтобы все ваши модели использовали `pydantic.v1`. +Сначала вы можете обновить Pydantic до последней 2-й версии и изменить импорты так, чтобы все ваши модели использовали `pydantic.v1`. -Затем начните мигрировать ваши модели с Pydantic v1 на v2 группами, поэтапно. 🚶 +Затем вы можете начать мигрировать ваши модели с Pydantic v1 на v2 группами, поэтапно. 🚶 diff --git a/docs/ru/docs/how-to/separate-openapi-schemas.md b/docs/ru/docs/how-to/separate-openapi-schemas.md index 5b1214016..8f6c83e7e 100644 --- a/docs/ru/docs/how-to/separate-openapi-schemas.md +++ b/docs/ru/docs/how-to/separate-openapi-schemas.md @@ -2,7 +2,7 @@ При использовании **Pydantic v2** сгенерированный OpenAPI становится чуть более точным и **корректным**, чем раньше. 😎 -На самом деле, в некоторых случаях в OpenAPI будет даже **две JSON схемы** для одной и той же Pydantic‑модели: для входа и для выхода — в зависимости от наличия **значений по умолчанию**. +На самом деле, в некоторых случаях в OpenAPI будет даже **две JSON-схемы** для одной и той же Pydantic‑модели: для входа и для выхода — в зависимости от наличия **значений по умолчанию**. Посмотрим, как это работает, и как это изменить при необходимости. @@ -34,7 +34,7 @@ {* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *} -…то, поскольку у `description` есть значение по умолчанию, даже если вы **ничего не вернёте** для этого поля, оно всё равно будет иметь это **значение по умолчанию**. +…то, поскольку у `description` есть значение по умолчанию, если вы **ничего не вернёте** для этого поля, оно всё равно будет иметь это **значение по умолчанию**. ### Модель для данных ответа { #model-for-output-response-data } @@ -46,13 +46,13 @@ Это означает, что у него **всегда будет какое‑то значение**, просто иногда это значение может быть `None` (или `null` в JSON). -Следовательно, клиентам, использующим ваш API, не нужно проверять наличие этого значения: они могут **исходить из того, что поле всегда присутствует**, а в некоторых случаях имеет значение по умолчанию `None`. +Это означает, что клиентам, использующим ваш API, не нужно проверять, существует ли это значение или нет: они могут **исходить из того, что поле всегда присутствует**, но в некоторых случаях оно будет иметь значение по умолчанию `None`. В OpenAPI это описывается тем, что поле помечается как **обязательное**, поскольку оно всегда присутствует. Из‑за этого JSON Schema для модели может отличаться в зависимости от использования для **входа** или **выхода**: -* для **входа** `description` не будет обязательным +* для **входа** `description` **не будет обязательным** * для **выхода** оно будет **обязательным** (и при этом может быть `None`, или, в терминах JSON, `null`) ### Выходная модель в документации { #model-for-output-in-docs } @@ -81,9 +81,9 @@ Однако бывают случаи, когда вы хотите иметь **одну и ту же схему для входа и выхода**. -Главный сценарий — когда у вас уже есть сгенерированный клиентский код/SDK, и вы пока не хотите обновлять весь этот автогенерируемый код/SDK (рано или поздно вы это сделаете, но не сейчас). +Главный сценарий — когда у вас уже есть сгенерированный клиентский код/SDK, и вы пока не хотите обновлять весь этот автогенерируемый клиентский код/SDK, вероятно, вы захотите сделать это в какой-то момент, но, возможно, не прямо сейчас. -В таком случае вы можете отключить эту функциональность в FastAPI с помощью параметра `separate_input_output_schemas=False`. +В таком случае вы можете отключить эту функциональность в **FastAPI** с помощью параметра `separate_input_output_schemas=False`. /// info | Информация @@ -95,10 +95,8 @@ ### Одна и та же схема для входной и выходной моделей в документации { #same-schema-for-input-and-output-models-in-docs } -Теперь для этой модели будет одна общая схема и для входа, и для выхода — только `Item`, и в ней `description` будет **не обязательным**: +И теперь для модели будет одна общая схема и для входа, и для выхода — только `Item`, и в ней `description` будет **не обязательным**:
- -Это то же поведение, что и в Pydantic v1. 🤓 diff --git a/docs/ru/docs/index.md b/docs/ru/docs/index.md index b562cbe5b..02b1c9a28 100644 --- a/docs/ru/docs/index.md +++ b/docs/ru/docs/index.md @@ -5,10 +5,10 @@

- FastAPI + FastAPI

- Фреймворк FastAPI: высокая производительность, прост в изучении, быстрый в разработке, готов к продакшн + Фреймворк FastAPI: высокая производительность, прост в изучении, позволяет быстро писать код, готов к продакшн

@@ -40,7 +40,7 @@ FastAPI — это современный, быстрый (высокопрои * **Скорость**: Очень высокая производительность, на уровне **NodeJS** и **Go** (благодаря Starlette и Pydantic). [Один из самых быстрых доступных фреймворков Python](#performance). * **Быстрота разработки**: Увеличьте скорость разработки фич примерно на 200–300%. * * **Меньше ошибок**: Сократите примерно на 40% количество ошибок, вызванных человеком (разработчиком). * -* **Интуитивность**: Отличная поддержка редактора кода. Автозавершение везде. Меньше времени на отладку. +* **Интуитивность**: Отличная поддержка редактора кода. Автозавершение везде. Меньше времени на отладку. * **Простота**: Разработан так, чтобы его было легко использовать и осваивать. Меньше времени на чтение документации. * **Краткость**: Минимизируйте дублирование кода. Несколько возможностей из каждого объявления параметров. Меньше ошибок. * **Надежность**: Получите код, готовый к продакшн. С автоматической интерактивной документацией. @@ -117,6 +117,12 @@ FastAPI — это современный, быстрый (высокопрои --- +## Мини-документальный фильм о FastAPI { #fastapi-mini-documentary } + +В конце 2025 года вышел мини-документальный фильм о FastAPI, вы можете посмотреть его онлайн: + +FastAPI Mini Documentary + ## **Typer**, FastAPI для CLI { #typer-the-fastapi-of-clis } @@ -257,7 +263,7 @@ INFO: Application startup complete. * Получает HTTP-запросы по _путям_ `/` и `/items/{item_id}`. * Оба _пути_ используют `GET` операции (также известные как HTTP _методы_). -* _Путь_ `/items/{item_id}` имеет _параметр пути_ `item_id`, который должен быть `int`. +* _Путь_ `/items/{item_id}` имеет _path-параметр_ `item_id`, который должен быть `int`. * _Путь_ `/items/{item_id}` имеет необязательный `str` _параметр запроса_ `q`. ### Интерактивная документация API { #interactive-api-docs } @@ -278,9 +284,9 @@ INFO: Application startup complete. ## Пример обновления { #example-upgrade } -Теперь измените файл `main.py`, чтобы принимать тело запроса из `PUT` запроса. +Теперь измените файл `main.py`, чтобы принимать тело запроса из `PUT` HTTP-запроса. -Объявите тело, используя стандартные типы Python, спасибо Pydantic. +Объявите тело запроса, используя стандартные типы Python, спасибо Pydantic. ```Python hl_lines="4 9-12 25-27" from typing import Union @@ -318,7 +324,7 @@ def update_item(item_id: int, item: Item): Перейдите на http://127.0.0.1:8000/docs. -* Интерактивная документация API будет автоматически обновлена, включая новое тело: +* Интерактивная документация API будет автоматически обновлена, включая новое тело запроса: ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) @@ -334,13 +340,13 @@ def update_item(item_id: int, item: Item): Теперь откройте http://127.0.0.1:8000/redoc. -* Альтернативная документация также отразит новый параметр запроса и тело: +* Альтернативная документация также отразит новый параметр запроса и тело запроса: ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) ### Подведём итоги { #recap } -Итак, вы объявляете **один раз** типы параметров, тела запроса и т.д. как параметры функции. +Итак, вы объявляете **один раз** типы параметров, тело запроса и т.д. как параметры функции. Вы делаете это с помощью стандартных современных типов Python. @@ -390,13 +396,13 @@ item: Item Возвращаясь к предыдущему примеру кода, **FastAPI** будет: -* Валидировать наличие `item_id` в пути для `GET` и `PUT` запросов. -* Валидировать, что `item_id` имеет тип `int` для `GET` и `PUT` запросов. +* Валидировать наличие `item_id` в пути для `GET` и `PUT` HTTP-запросов. +* Валидировать, что `item_id` имеет тип `int` для `GET` и `PUT` HTTP-запросов. * Если это не так, клиент увидит полезную понятную ошибку. -* Проверять, есть ли необязательный параметр запроса с именем `q` (например, `http://127.0.0.1:8000/items/foo?q=somequery`) для `GET` запросов. +* Проверять, есть ли необязательный параметр запроса с именем `q` (например, `http://127.0.0.1:8000/items/foo?q=somequery`) для `GET` HTTP-запросов. * Поскольку параметр `q` объявлен с `= None`, он необязателен. * Без `None` он был бы обязательным (как тело запроса в случае с `PUT`). -* Для `PUT` запросов к `/items/{item_id}` читать тело запроса как JSON: +* Для `PUT` HTTP-запросов к `/items/{item_id}` читать тело запроса как JSON: * Проверять, что есть обязательный атрибут `name`, который должен быть `str`. * Проверять, что есть обязательный атрибут `price`, который должен быть `float`. * Проверять, что есть необязательный атрибут `is_offer`, который должен быть `bool`, если он присутствует. @@ -435,11 +441,11 @@ item: Item Более полный пример с дополнительными возможностями см. в Учебник - Руководство пользователя. -**Осторожно, спойлер**: учебник - руководство включает: +**Осторожно, спойлер**: учебник - руководство пользователя включает: * Объявление **параметров** из других источников: **HTTP-заголовки**, **cookies**, **поля формы** и **файлы**. * Как задать **ограничения валидации** вроде `maximum_length` или `regex`. -* Очень мощную и простую в использовании систему **внедрения зависимостей**. +* Очень мощную и простую в использовании систему **внедрения зависимостей**. * Безопасность и аутентификацию, включая поддержку **OAuth2** с **JWT токенами** и **HTTP Basic** аутентификацию. * Более продвинутые (но столь же простые) приёмы объявления **глубоко вложенных JSON-моделей** (спасибо Pydantic). * Интеграцию **GraphQL** с Strawberry и другими библиотеками. @@ -524,11 +530,11 @@ FastAPI зависит от Pydantic и Starlette. * httpx — обязателен, если вы хотите использовать `TestClient`. * jinja2 — обязателен, если вы хотите использовать конфигурацию шаблонов по умолчанию. -* python-multipart — обязателен, если вы хотите поддерживать «парсинг» форм через `request.form()`. +* python-multipart - обязателен, если вы хотите поддерживать «парсинг» форм через `request.form()`. Используется FastAPI: -* uvicorn — сервер, который загружает и обслуживает ваше приложение. Включает `uvicorn[standard]`, содержащий некоторые зависимости (например, `uvloop`), нужные для высокой производительности. +* uvicorn — сервер, который загружает и «отдаёт» ваше приложение. Включает `uvicorn[standard]`, содержащий некоторые зависимости (например, `uvloop`), нужные для высокой производительности. * `fastapi-cli[standard]` — чтобы предоставить команду `fastapi`. * Включает `fastapi-cloud-cli`, который позволяет развернуть ваше приложение FastAPI в FastAPI Cloud. diff --git a/docs/ru/docs/tutorial/bigger-applications.md b/docs/ru/docs/tutorial/bigger-applications.md index 5e5d6ada9..76304523c 100644 --- a/docs/ru/docs/tutorial/bigger-applications.md +++ b/docs/ru/docs/tutorial/bigger-applications.md @@ -1,4 +1,4 @@ -# Большие приложения, в которых много файлов { #bigger-applications-multiple-files } +# Большие приложения — несколько файлов { #bigger-applications-multiple-files } При построении приложения или веб-API нам редко удается поместить всё в один файл. @@ -31,7 +31,7 @@ /// tip | Подсказка -Обратите внимание, что в каждом каталоге и подкаталоге имеется файл `__init__.py` +Есть несколько файлов `__init__.py`: по одному в каждом каталоге или подкаталоге. Это как раз то, что позволяет импортировать код из одного файла в другой. @@ -43,61 +43,63 @@ from app.routers import items /// -* Всё помещается в каталоге `app`. В нём также находится пустой файл `app/__init__.py`. Таким образом, `app` является "Python-пакетом" (коллекцией модулей Python). -* Он содержит файл `app/main.py`. Данный файл является частью пакета (т.е. находится внутри каталога, содержащего файл `__init__.py`), и, соответственно, он является модулем пакета: `app.main`. +* Всё помещается в каталоге `app`. В нём также находится пустой файл `app/__init__.py`. Таким образом, `app` является "Python-пакетом" (коллекцией "Python-модулей"): `app`. +* Он содержит файл `app/main.py`. Данный файл является частью Python-пакета (т.е. находится внутри каталога, содержащего файл `__init__.py`), и, соответственно, он является модулем этого пакета: `app.main`. * Он также содержит файл `app/dependencies.py`, который также, как и `app/main.py`, является модулем: `app.dependencies`. -* Здесь также находится подкаталог `app/routers/`, содержащий `__init__.py`. Он является суб-пакетом: `app.routers`. -* Файл `app/routers/items.py` находится внутри пакета `app/routers/`. Таким образом, он является суб-модулем: `app.routers.items`. -* Точно также `app/routers/users.py` является ещё одним суб-модулем: `app.routers.users`. -* Подкаталог `app/internal/`, содержащий файл `__init__.py`, является ещё одним суб-пакетом: `app.internal`. -* А файл `app/internal/admin.py` является ещё одним суб-модулем: `app.internal.admin`. +* Здесь также находится подкаталог `app/routers/`, содержащий `__init__.py`. Он является Python-подпакетом: `app.routers`. +* Файл `app/routers/items.py` находится внутри пакета `app/routers/`. Таким образом, он является подмодулем: `app.routers.items`. +* Точно так же `app/routers/users.py` является ещё одним подмодулем: `app.routers.users`. +* Подкаталог `app/internal/`, содержащий файл `__init__.py`, является ещё одним Python-подпакетом: `app.internal`. +* А файл `app/internal/admin.py` является ещё одним подмодулем: `app.internal.admin`. Та же самая файловая структура приложения, но с комментариями: -``` +```bash . ├── app # "app" пакет │   ├── __init__.py # этот файл превращает "app" в "Python-пакет" │   ├── main.py # модуль "main", напр.: import app.main │   ├── dependencies.py # модуль "dependencies", напр.: import app.dependencies -│   └── routers # суб-пакет "routers" -│   │ ├── __init__.py # превращает "routers" в суб-пакет -│   │ ├── items.py # суб-модуль "items", напр.: import app.routers.items -│   │ └── users.py # суб-модуль "users", напр.: import app.routers.users -│   └── internal # суб-пакет "internal" -│   ├── __init__.py # превращает "internal" в суб-пакет -│   └── admin.py # суб-модуль "admin", напр.: import app.internal.admin +│   └── routers # подпакет "routers" +│   │ ├── __init__.py # превращает "routers" в подпакет +│   │ ├── items.py # подмодуль "items", напр.: import app.routers.items +│   │ └── users.py # подмодуль "users", напр.: import app.routers.users +│   └── internal # подпакет "internal" +│   ├── __init__.py # превращает "internal" в подпакет +│   └── admin.py # подмодуль "admin", напр.: import app.internal.admin ``` ## `APIRouter` { #apirouter } -Давайте предположим, что для работы с пользователями используется отдельный файл (суб-модуль) `/app/routers/users.py`. +Давайте предположим, что для работы с пользователями используется отдельный файл (подмодуль) `/app/routers/users.py`. -Для лучшей организации приложения, вы хотите отделить операции пути, связанные с пользователями, от остального кода. +Вы хотите отделить *операции пути*, связанные с пользователями, от остального кода, чтобы сохранить порядок. -Но так, чтобы эти операции по-прежнему оставались частью **FastAPI** приложения/веб-API (частью одного пакета) +Но это всё равно часть того же приложения/веб-API на **FastAPI** (часть того же «Python-пакета»). -С помощью `APIRouter` вы можете создать *операции пути* (*эндпоинты*) для данного модуля. +С помощью `APIRouter` вы можете создать *операции пути* для этого модуля. ### Импорт `APIRouter` { #import-apirouter } -Точно также, как и в случае с классом `FastAPI`, вам нужно импортировать и создать объект класса `APIRouter`. +Точно так же, как и в случае с классом `FastAPI`, вам нужно импортировать и создать его «экземпляр»: {* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *} -### Создание *эндпоинтов* с помощью `APIRouter` { #path-operations-with-apirouter } +### *Операции пути* с `APIRouter` { #path-operations-with-apirouter } -В дальнейшем используйте `APIRouter` для объявления *эндпоинтов*, точно также, как вы используете класс `FastAPI`: +И затем вы используете его, чтобы объявить ваши *операции пути*. + +Используйте его так же, как вы использовали бы класс `FastAPI`: {* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *} -Вы можете думать об `APIRouter` как об "уменьшенной версии" класса FastAPI`. +Вы можете думать об `APIRouter` как об «мини-классе `FastAPI`». -`APIRouter` поддерживает все те же самые опции. +Поддерживаются все те же опции. -`APIRouter` поддерживает все те же самые параметры, такие как `parameters`, `responses`, `dependencies`, `tags`, и т. д. +Все те же `parameters`, `responses`, `dependencies`, `tags` и т.д. /// tip | Подсказка @@ -105,21 +107,21 @@ from app.routers import items /// -Мы собираемся подключить данный `APIRouter` к нашему основному приложению на `FastAPI`, но сначала давайте проверим зависимости и создадим ещё один модуль с `APIRouter`. +Мы собираемся подключить данный `APIRouter` к нашему основному приложению на `FastAPI`, но сначала давайте проверим зависимости и ещё один `APIRouter`. ## Зависимости { #dependencies } -Нам понадобятся некоторые зависимости, которые мы будем использовать в разных местах нашего приложения. +Мы видим, что нам понадобятся некоторые зависимости, которые будут использоваться в нескольких местах приложения. -Мы поместим их в отдельный модуль `dependencies` (`app/dependencies.py`). +Поэтому мы поместим их в отдельный модуль `dependencies` (`app/dependencies.py`). -Теперь мы воспользуемся простой зависимостью, чтобы прочитать кастомизированный `X-Token` из заголовка: +Теперь мы воспользуемся простой зависимостью, чтобы прочитать кастомный HTTP-заголовок `X-Token`: {* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *} /// tip | Подсказка -Для простоты мы воспользовались неким воображаемым заголовоком. +Для простоты мы воспользовались выдуманным заголовком. В реальных случаях для получения наилучших результатов используйте интегрированные [утилиты безопасности](security/index.md){.internal-link target=_blank}. @@ -127,30 +129,29 @@ from app.routers import items ## Ещё один модуль с `APIRouter` { #another-module-with-apirouter } -Давайте также предположим, что у вас есть *эндпоинты*, отвечающие за обработку "items", и они находятся в модуле `app/routers/items.py`. +Давайте также предположим, что у вас есть эндпоинты, отвечающие за обработку «items» в вашем приложении, и они находятся в модуле `app/routers/items.py`. -У вас определены следующие *операции пути* (*эндпоинты*): +У вас определены *операции пути* для: * `/items/` * `/items/{item_id}` -Тут всё точно также, как и в ситуации с `app/routers/users.py`. +Тут всё та же структура, как и в случае с `app/routers/users.py`. -Но теперь мы хотим поступить немного умнее и слегка упростить код. +Но мы хотим поступить умнее и слегка упростить код. -Мы знаем, что все *эндпоинты* данного модуля имеют некоторые общие свойства: +Мы знаем, что все *операции пути* этого модуля имеют одинаковые: -* Префикс пути: `/items`. -* Теги: (один единственный тег: `items`). -* Дополнительные ответы (responses) -* Зависимости: использование созданной нами зависимости `X-token` +* `prefix` пути: `/items`. +* `tags`: (один единственный тег: `items`). +* Дополнительные `responses`. +* `dependencies`: всем им нужна та зависимость `X-Token`, которую мы создали. -Таким образом, вместо того чтобы добавлять все эти свойства в функцию каждого отдельного *эндпоинта*, -мы добавим их в `APIRouter`. +Таким образом, вместо того чтобы добавлять всё это в каждую *операцию пути*, мы можем добавить это в `APIRouter`. {* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *} -Так как каждый *эндпоинт* начинается с символа `/`: +Так как путь каждой *операции пути* должен начинаться с `/`, как здесь: ```Python hl_lines="1" @router.get("/{item_id}") @@ -162,73 +163,74 @@ async def read_item(item_id: str): В нашем случае префиксом является `/items`. -Мы также можем добавить в наш маршрутизатор (router) список `тегов` (`tags`) и дополнительных `ответов` (`responses`), которые являются общими для каждого *эндпоинта*. +Мы также можем добавить список `tags` и дополнительные `responses`, которые будут применяться ко всем *операциям пути*, включённым в этот маршрутизатор. -И ещё мы можем добавить в наш маршрутизатор список `зависимостей`, которые должны вызываться при каждом обращении к *эндпоинтам*. +И ещё мы можем добавить список `dependencies`, которые будут добавлены ко всем *операциям пути* в маршрутизаторе и будут выполняться/разрешаться для каждого HTTP-запроса к ним. /// tip | Подсказка -Обратите внимание, что также, как и в случае с зависимостями в декораторах *эндпоинтов* ([зависимости в декораторах операций пути](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), никакого значения в *функцию эндпоинта* передано не будет. +Обратите внимание, что так же, как и в случае с [зависимостями в декораторах *операций пути*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, никакое значение не будет передано в вашу *функцию-обработчик пути*. /// -В результате мы получим следующие эндпоинты: +В результате пути для items теперь такие: * `/items/` * `/items/{item_id}` ...как мы и планировали. -* Они будут помечены тегами из заданного списка, в нашем случае это `"items"`. - * Эти теги особенно полезны для системы автоматической интерактивной документации (с использованием OpenAPI). -* Каждый из них будет включать предопределенные ответы `responses`. -* Каждый *эндпоинт* будет иметь список зависимостей (`dependencies`), исполняемых перед вызовом *эндпоинта*. - * Если вы определили зависимости в самой операции пути, **то она также будет выполнена**. - * Сначала выполняются зависимости маршрутизатора, затем вызываются [зависимости в декораторе](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, и, наконец, обычные параметрические зависимости. - * Вы также можете добавить [зависимости `Security` с `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}. +* Они будут помечены списком тегов, содержащим одну строку `"items"`. + * Эти «теги» особенно полезны для систем автоматической интерактивной документации (с использованием OpenAPI). +* Все они будут включать предопределённые `responses`. +* Все эти *операции пути* будут иметь список `dependencies`, вычисляемых/выполняемых перед ними. + * Если вы также объявите зависимости в конкретной *операции пути*, **они тоже будут выполнены**. + * Сначала выполняются зависимости маршрутизатора, затем [`dependencies` в декораторе](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, и затем обычные параметрические зависимости. + * Вы также можете добавить [`Security`-зависимости с `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}. /// tip | Подсказка -Например, с помощью зависимостей в `APIRouter` мы можем потребовать аутентификации для доступа ко всей группе *эндпоинтов*, не указывая зависимости для каждой отдельной функции *эндпоинта*. +Например, с помощью зависимостей в `APIRouter` мы можем потребовать аутентификации для доступа ко всей группе *операций пути*. Даже если зависимости не добавляются по отдельности к каждой из них. /// /// check | Заметка -Параметры `prefix`, `tags`, `responses` и `dependencies` относятся к функционалу **FastAPI**, помогающему избежать дублирования кода. +Параметры `prefix`, `tags`, `responses` и `dependencies` — это (как и во многих других случаях) просто возможность **FastAPI**, помогающая избежать дублирования кода. /// ### Импорт зависимостей { #import-the-dependencies } -Наш код находится в модуле `app.routers.items` (файл `app/routers/items.py`). +Этот код находится в модуле `app.routers.items`, в файле `app/routers/items.py`. -И нам нужно вызвать функцию зависимости из модуля `app.dependencies` (файл `app/dependencies.py`). +И нам нужно получить функцию зависимости из модуля `app.dependencies`, файла `app/dependencies.py`. -Мы используем операцию относительного импорта `..` для импорта зависимости: +Поэтому мы используем относительный импорт с `..` для зависимостей: {* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *} -#### Как работает относительный импорт? { #how-relative-imports-work } +#### Как работает относительный импорт { #how-relative-imports-work } /// tip | Подсказка -Если вы прекрасно знаете, как работает импорт в Python, то переходите к следующему разделу. +Если вы прекрасно знаете, как работает импорт, переходите к следующему разделу ниже. /// -Одна точка `.`, как в данном примере: +Одна точка `.`, как здесь: ```Python from .dependencies import get_token_header ``` + означает: -* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` расположен в каталоге `app/routers/`)... -* ... найдите модуль `dependencies` (файл `app/routers/dependencies.py`)... -* ... и импортируйте из него функцию `get_token_header`. +* Начать в том же пакете, в котором находится этот модуль (файл `app/routers/items.py`) (каталог `app/routers/`)... +* найти модуль `dependencies` (воображаемый файл `app/routers/dependencies.py`)... +* и импортировать из него функцию `get_token_header`. -К сожалению, такого файла не существует, и наши зависимости находятся в файле `app/dependencies.py`. +Но такого файла не существует, наши зависимости находятся в файле `app/dependencies.py`. Вспомните, как выглядит файловая структура нашего приложения: @@ -236,7 +238,7 @@ from .dependencies import get_token_header --- -Две точки `..`, как в данном примере: +Две точки `..`, как здесь: ```Python from ..dependencies import get_token_header @@ -244,12 +246,12 @@ from ..dependencies import get_token_header означают: -* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` находится в каталоге `app/routers/`)... -* ... перейдите в родительский пакет (каталог `app/`)... -* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)... -* ... и импортируйте из него функцию `get_token_header`. +* Начать в том же пакете, в котором находится этот модуль (файл `app/routers/items.py`) (каталог `app/routers/`)... +* перейти в родительский пакет (каталог `app/`)... +* и там найти модуль `dependencies` (файл `app/dependencies.py`)... +* и импортировать из него функцию `get_token_header`. -Это работает верно! 🎉 +Это работает корректно! 🎉 --- @@ -261,29 +263,29 @@ from ...dependencies import get_token_header то это бы означало: -* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` находится в каталоге `app/routers/`)... -* ... перейдите в родительский пакет (каталог `app/`)... -* ... затем перейдите в родительский пакет текущего пакета (такого пакета не существует, `app` находится на самом верхнем уровне 😱)... -* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)... -* ... и импортируйте из него функцию `get_token_header`. +* Начать в том же пакете, в котором находится этот модуль (файл `app/routers/items.py`) расположен в (каталоге `app/routers/`)... +* перейти в родительский пакет (каталог `app/`)... +* затем перейти в родительский пакет этого пакета (родительского пакета нет, `app` — верхний уровень 😱)... +* и там найти модуль `dependencies` (файл `app/dependencies.py`)... +* и импортировать из него функцию `get_token_header`. -Это будет относиться к некоторому пакету, находящемуся на один уровень выше чем `app/` и содержащему свой собственный файл `__init__.py`. Но ничего такого у нас нет. Поэтому это приведет к ошибке в нашем примере. 🚨 +Это ссылалось бы на какой-то пакет выше `app/`, со своим файлом `__init__.py` и т.п. Но у нас такого нет. Поэтому это вызвало бы ошибку в нашем примере. 🚨 -Теперь вы знаете, как работает импорт в Python, и сможете использовать относительное импортирование в своих собственных приложениях любого уровня сложности. 🤓 +Но теперь вы знаете, как это работает, так что можете использовать относительные импорты в своих приложениях, независимо от того, насколько они сложные. 🤓 -### Добавление пользовательских тегов (`tags`), ответов (`responses`) и зависимостей (`dependencies`) { #add-some-custom-tags-responses-and-dependencies } +### Добавление пользовательских `tags`, `responses` и `dependencies` { #add-some-custom-tags-responses-and-dependencies } -Мы не будем добавлять префикс `/items` и список тегов `tags=["items"]` для каждого *эндпоинта*, т.к. мы уже их добавили с помощью `APIRouter`. +Мы не добавляем префикс `/items` и `tags=["items"]` к каждой *операции пути*, потому что мы добавили их в `APIRouter`. -Но помимо этого мы можем добавить новые теги для каждого отдельного *эндпоинта*, а также некоторые дополнительные ответы (`responses`), характерные для данного *эндпоинта*: +Но мы всё равно можем добавить _ещё_ `tags`, которые будут применяться к конкретной *операции пути*, а также дополнительные `responses`, специфичные для этой *операции пути*: {* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *} /// tip | Подсказка -Последний *эндпоинт* будет иметь следующую комбинацию тегов: `["items", "custom"]`. +Эта последняя операция пути будет иметь комбинацию тегов: `["items", "custom"]`. -А также в его документации будут содержаться оба ответа: один для `404` и другой для `403`. +И в документации у неё будут оба ответа: один для `404` и один для `403`. /// @@ -293,29 +295,29 @@ from ...dependencies import get_token_header Именно сюда вы импортируете и именно здесь вы используете класс `FastAPI`. -Это основной файл вашего приложения, который объединяет всё в одно целое. +Это основной файл вашего приложения, который связывает всё воедино. -И теперь, когда большая часть логики приложения разделена на отдельные модули, основной файл `app/main.py` будет достаточно простым. +И так как большая часть вашей логики теперь будет находиться в отдельных специфичных модулях, основной файл будет довольно простым. ### Импорт `FastAPI` { #import-fastapi } -Вы импортируете и создаете класс `FastAPI` как обычно. +Вы импортируете и создаёте класс `FastAPI` как обычно. -Мы даже можем объявить [глобальные зависимости](dependencies/global-dependencies.md){.internal-link target=_blank}, которые будут объединены с зависимостями для каждого отдельного маршрутизатора: +И мы даже можем объявить [глобальные зависимости](dependencies/global-dependencies.md){.internal-link target=_blank}, которые будут объединены с зависимостями для каждого `APIRouter`: {* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *} ### Импорт `APIRouter` { #import-the-apirouter } -Теперь мы импортируем другие суб-модули, содержащие `APIRouter`: +Теперь мы импортируем другие подмодули, содержащие `APIRouter`: {* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *} -Так как файлы `app/routers/users.py` и `app/routers/items.py` являются суб-модулями одного и того же Python-пакета `app`, то мы сможем их импортировать, воспользовавшись операцией относительного импорта `.`. +Так как файлы `app/routers/users.py` и `app/routers/items.py` являются подмодулями, входящими в один и тот же Python-пакет `app`, мы можем использовать одну точку `.` для импорта через «относительные импорты». -### Как работает импорт? { #how-the-importing-works } +### Как работает импорт { #how-the-importing-works } -Данная строка кода: +Этот фрагмент: ```Python from .routers import items, users @@ -323,15 +325,15 @@ from .routers import items, users означает: -* Начните с пакета, в котором содержится данный модуль (файл `app/main.py` содержится в каталоге `app/`)... -* ... найдите суб-пакет `routers` (каталог `app/routers/`)... -* ... и из него импортируйте суб-модули `items` (файл `app/routers/items.py`) и `users` (файл `app/routers/users.py`)... +* Начать в том же пакете, в котором находится этот модуль (файл `app/main.py`) расположен в (каталоге `app/`)... +* найти подпакет `routers` (каталог `app/routers/`)... +* и импортировать из него подмодули `items` (файл `app/routers/items.py`) и `users` (файл `app/routers/users.py`)... -В модуле `items` содержится переменная `router` (`items.router`), та самая, которую мы создали в файле `app/routers/items.py`, она является объектом класса `APIRouter`. +В модуле `items` будет переменная `router` (`items.router`). Это та же самая, которую мы создали в файле `app/routers/items.py`, это объект `APIRouter`. -И затем мы сделаем то же самое для модуля `users`. +И затем мы делаем то же самое для модуля `users`. -Мы также могли бы импортировать и другим методом: +Мы также могли бы импортировать их так: ```Python from app.routers import items, users @@ -339,44 +341,44 @@ from app.routers import items, users /// info | Примечание -Первая версия является примером относительного импорта: +Первая версия — это «относительный импорт»: ```Python from .routers import items, users ``` -Вторая версия является примером абсолютного импорта: +Вторая версия — это «абсолютный импорт»: ```Python from app.routers import items, users ``` -Узнать больше о пакетах и модулях в Python вы можете из официальной документации Python о модулях +Чтобы узнать больше о Python-пакетах и модулях, прочитайте официальную документацию Python о модулях. /// -### Избегайте конфликтов имен { #avoid-name-collisions } +### Избегайте конфликтов имён { #avoid-name-collisions } -Вместо того чтобы импортировать только переменную `router`, мы импортируем непосредственно суб-модуль `items`. +Мы импортируем подмодуль `items` напрямую, вместо того чтобы импортировать только его переменную `router`. -Мы делаем это потому, что у нас есть ещё одна переменная `router` в суб-модуле `users`. +Это потому, что у нас также есть другая переменная с именем `router` в подмодуле `users`. -Если бы мы импортировали их одну за другой, как показано в примере: +Если бы мы импортировали их одну за другой, как здесь: ```Python from .routers.items import router from .routers.users import router ``` -то переменная `router` из `users` переписал бы переменную `router` из `items`, и у нас не было бы возможности использовать их одновременно. +то `router` из `users` перезаписал бы `router` из `items`, и мы не смогли бы использовать их одновременно. -Поэтому, для того чтобы использовать обе эти переменные в одном файле, мы импортировали соответствующие суб-модули: +Поэтому, чтобы иметь возможность использовать обе в одном файле, мы импортируем подмодули напрямую: {* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *} -### Подключение маршрутизаторов (`APIRouter`) для `users` и для `items` { #include-the-apirouters-for-users-and-items } +### Подключение `APIRouter` для `users` и `items` { #include-the-apirouters-for-users-and-items } -Давайте подключим маршрутизаторы (`router`) из суб-модулей `users` и `items`: +Теперь давайте подключим `router` из подмодулей `users` и `items`: {* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *} @@ -388,79 +390,78 @@ from .routers.users import router /// -С помощью `app.include_router()` мы можем добавить каждый из маршрутизаторов (`APIRouter`) в основное приложение `FastAPI`. +С помощью `app.include_router()` мы можем добавить каждый `APIRouter` в основное приложение `FastAPI`. -Он подключит все маршруты заданного маршрутизатора к нашему приложению. +Он включит все маршруты этого маршрутизатора как часть приложения. /// note | Технические детали -Фактически, внутри он создаст все *операции пути* для каждой операции пути объявленной в `APIRouter`. +Фактически, внутри он создаст *операцию пути* для каждой *операции пути*, объявленной в `APIRouter`. -И под капотом всё будет работать так, как будто бы мы имеем дело с одним файлом приложения. +Так что под капотом всё будет работать так, как будто всё было одним приложением. /// /// check | Заметка -При подключении маршрутизаторов не стоит беспокоиться о производительности. +При подключении маршрутизаторов не нужно беспокоиться о производительности. -Операция подключения займёт микросекунды и понадобится только при запуске приложения. +Это займёт микросекунды и произойдёт только при старте. -Таким образом, это не повлияет на производительность. ⚡ +Так что это не повлияет на производительность. ⚡ /// -### Подключение `APIRouter` с пользовательскими префиксом (`prefix`), тегами (`tags`), ответами (`responses`), и зависимостями (`dependencies`) { #include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies } +### Подключение `APIRouter` с пользовательскими `prefix`, `tags`, `responses` и `dependencies` { #include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies } Теперь давайте представим, что ваша организация передала вам файл `app/internal/admin.py`. -Он содержит `APIRouter` с некоторыми *эндпоитами* администрирования, которые ваша организация использует для нескольких проектов. +Он содержит `APIRouter` с некоторыми административными *операциями пути*, которые ваша организация использует в нескольких проектах. -В данном примере это сделать очень просто. Но давайте предположим, что поскольку файл используется для нескольких проектов, -то мы не можем модифицировать его, добавляя префиксы (`prefix`), зависимости (`dependencies`), теги (`tags`), и т.д. непосредственно в `APIRouter`: +Для этого примера всё будет очень просто. Но допустим, что поскольку он используется совместно с другими проектами в организации, мы не можем модифицировать его и добавить `prefix`, `dependencies`, `tags` и т.д. непосредственно в `APIRouter`: {* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *} -Но, несмотря на это, мы хотим использовать кастомный префикс (`prefix`) для подключенного маршрутизатора (`APIRouter`), в результате чего, каждая *операция пути* будет начинаться с `/admin`. Также мы хотим защитить наш маршрутизатор с помощью зависимостей, созданных для нашего проекта. И ещё мы хотим включить теги (`tags`) и ответы (`responses`). +Но мы всё равно хотим задать пользовательский `prefix` при подключении `APIRouter`, чтобы все его *операции пути* начинались с `/admin`, хотим защитить его с помощью `dependencies`, которые у нас уже есть для этого проекта, и хотим включить `tags` и `responses`. -Мы можем применить все вышеперечисленные настройки, не изменяя начальный `APIRouter`. Нам всего лишь нужно передать нужные параметры в `app.include_router()`. +Мы можем объявить всё это, не изменяя исходный `APIRouter`, передав эти параметры в `app.include_router()`: {* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *} -Таким образом, оригинальный `APIRouter` не будет модифицирован, и мы сможем использовать файл `app/internal/admin.py` сразу в нескольких проектах организации. +Таким образом исходный `APIRouter` не будет модифицирован, и мы сможем использовать файл `app/internal/admin.py` сразу в нескольких проектах организации. -В результате, в нашем приложении каждый *эндпоинт* модуля `admin` будет иметь: +В результате в нашем приложении каждая из *операций пути* из модуля `admin` будет иметь: * Префикс `/admin`. * Тег `admin`. * Зависимость `get_token_header`. * Ответ `418`. 🍵 -Это будет иметь место исключительно для `APIRouter` в нашем приложении, и не затронет любой другой код, использующий его. +Но это повлияет только на этот `APIRouter` в нашем приложении, а не на любой другой код, который его использует. -Например, другие проекты, могут использовать тот же самый `APIRouter` с другими методами аутентификации. +Так что, например, другие проекты могут использовать тот же `APIRouter` с другим методом аутентификации. -### Подключение отдельного *эндпоинта* { #include-a-path-operation } +### Подключение *операции пути* { #include-a-path-operation } -Мы также можем добавить *эндпоинт* непосредственно в основное приложение `FastAPI`. +Мы также можем добавлять *операции пути* напрямую в приложение `FastAPI`. -Здесь мы это делаем ... просто, чтобы показать, что это возможно 🤷: +Здесь мы делаем это... просто чтобы показать, что можем 🤷: {* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *} -и это будет работать корректно вместе с другими *эндпоинтами*, добавленными с помощью `app.include_router()`. +и это будет работать корректно вместе со всеми другими *операциями пути*, добавленными через `app.include_router()`. -/// info | Сложные технические детали +/// info | Очень технические детали -**Примечание**: это сложная техническая деталь, которую, скорее всего, **вы можете пропустить**. +**Примечание**: это очень техническая деталь, которую, вероятно, можно **просто пропустить**. --- -Маршрутизаторы (`APIRouter`) не "монтируются" по-отдельности и не изолируются от остального приложения. +`APIRouter` не «монтируются», они не изолированы от остального приложения. -Это происходит потому, что нужно включить их *эндпоинты* в OpenAPI схему и в интерфейс пользователя. +Это потому, что мы хотим включить их *операции пути* в OpenAPI-схему и пользовательские интерфейсы. -В силу того, что мы не можем их изолировать и "примонтировать" независимо от остальных, *эндпоинты* клонируются (пересоздаются) и не подключаются напрямую. +Так как мы не можем просто изолировать их и «смонтировать» независимо от остального, *операции пути* «клонируются» (пересоздаются), а не включаются напрямую. /// @@ -480,24 +481,24 @@ $ fastapi dev app/main.py Откройте документацию по адресу http://127.0.0.1:8000/docs. -Вы увидите автоматическую API документацию. Она включает в себя маршруты из суб-модулей, используя верные маршруты, префиксы и теги: +Вы увидите автоматическую документацию API, включая пути из всех подмодулей, с использованием корректных путей (и префиксов) и корректных тегов: -## Подключение существующего маршрута через новый префикс (`prefix`) { #include-the-same-router-multiple-times-with-different-prefix } +## Подключение одного и того же маршрутизатора несколько раз с разными `prefix` { #include-the-same-router-multiple-times-with-different-prefix } -Вы можете использовать `.include_router()` несколько раз с одним и тем же маршрутом, применив различные префиксы. +Вы можете использовать `.include_router()` несколько раз с *одним и тем же* маршрутизатором, используя разные префиксы. -Это может быть полезным, если нужно предоставить доступ к одному и тому же API через различные префиксы, например, `/api/v1` и `/api/latest`. +Это может быть полезно, например, чтобы предоставить доступ к одному и тому же API с разными префиксами, например `/api/v1` и `/api/latest`. -Это продвинутый способ, который вам может и не пригодится. Мы приводим его на случай, если вдруг вам это понадобится. +Это продвинутое использование, которое вам может и не понадобиться, но оно есть на случай, если понадобится. -## Включение одного маршрутизатора (`APIRouter`) в другой { #include-an-apirouter-in-another } +## Подключение `APIRouter` в другой `APIRouter` { #include-an-apirouter-in-another } -Точно так же, как вы включаете `APIRouter` в приложение `FastAPI`, вы можете включить `APIRouter` в другой `APIRouter`: +Точно так же, как вы можете подключить `APIRouter` к приложению `FastAPI`, вы можете подключить `APIRouter` к другому `APIRouter`, используя: ```Python router.include_router(other_router) ``` -Удостоверьтесь, что вы сделали это до того, как подключить маршрутизатор (`router`) к вашему `FastAPI` приложению, и *эндпоинты* маршрутизатора `other_router` были также подключены. +Убедитесь, что вы сделали это до подключения `router` к приложению `FastAPI`, чтобы *операции пути* из `other_router` также были подключены. diff --git a/docs/ru/docs/tutorial/body-updates.md b/docs/ru/docs/tutorial/body-updates.md index 73f4e66c7..4a7adb255 100644 --- a/docs/ru/docs/tutorial/body-updates.md +++ b/docs/ru/docs/tutorial/body-updates.md @@ -2,13 +2,13 @@ ## Обновление с заменой при помощи `PUT` { #update-replacing-with-put } -Для полного обновления элемента можно воспользоваться операцией HTTP `PUT`. +Чтобы обновить элемент, вы можете использовать операцию HTTP `PUT`. Вы можете использовать `jsonable_encoder`, чтобы преобразовать входные данные в данные, которые можно сохранить как JSON (например, в NoSQL-базе данных). Например, преобразование `datetime` в `str`. {* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *} -`PUT` используется для получения данных, которые должны полностью заменить существующие данные. +`PUT` используется для получения данных, которые должны заменить существующие данные. ### Предупреждение о замене { #warning-about-replacing } @@ -24,11 +24,11 @@ поскольку оно не включает уже сохраненный атрибут `"tax": 20.2`, входная модель примет значение по умолчанию `"tax": 10.5`. -И данные будут сохранены с этим "новым" `tax`, равным `10,5`. +И данные будут сохранены с этим «новым» `tax`, равным `10.5`. ## Частичное обновление с помощью `PATCH` { #partial-updates-with-patch } -Также можно использовать HTTP `PATCH` операцию для *частичного* обновления данных. +Также можно использовать операцию HTTP `PATCH` для *частичного* обновления данных. Это означает, что можно передавать только те данные, которые необходимо обновить, оставляя остальные нетронутыми. @@ -46,19 +46,13 @@ ### Использование параметра `exclude_unset` в Pydantic { #using-pydantics-exclude-unset-parameter } -Если необходимо выполнить частичное обновление, то очень полезно использовать параметр `exclude_unset` в методе `.model_dump()` модели Pydantic. +Если вы хотите получать частичные обновления, очень полезно использовать параметр `exclude_unset` в `.model_dump()` модели Pydantic. Например, `item.model_dump(exclude_unset=True)`. -/// info | Информация +В результате будет сгенерирован `dict`, содержащий только те данные, которые были заданы при создании модели `item`, без учета значений по умолчанию. -В Pydantic v1 метод назывался `.dict()`, в Pydantic v2 он помечен как устаревший (но все еще поддерживается) и переименован в `.model_dump()`. - -Примеры здесь используют `.dict()` для совместимости с Pydantic v1, но если вы можете использовать Pydantic v2, лучше используйте `.model_dump()`. - -/// - -В результате будет сгенерирован словарь, содержащий только те данные, которые были заданы при создании модели `item`, без учета значений по умолчанию. Затем вы можете использовать это для создания словаря только с теми данными, которые были установлены (отправлены в запросе), опуская значения по умолчанию: +Затем вы можете использовать это для создания `dict` только с теми данными, которые были установлены (отправлены в запросе), опуская значения по умолчанию: {* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *} @@ -66,14 +60,6 @@ Теперь можно создать копию существующей модели, используя `.model_copy()`, и передать параметр `update` с `dict`, содержащим данные для обновления. -/// info | Информация - -В Pydantic v1 метод назывался `.copy()`, в Pydantic v2 он помечен как устаревший (но все еще поддерживается) и переименован в `.model_copy()`. - -Примеры здесь используют `.copy()` для совместимости с Pydantic v1, но если вы можете использовать Pydantic v2, лучше используйте `.model_copy()`. - -/// - Например, `stored_item_model.model_copy(update=update_data)`: {* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *} @@ -84,9 +70,9 @@ * (Опционально) использовать `PATCH` вместо `PUT`. * Извлечь сохранённые данные. -* Поместить эти данные в Pydantic модель. +* Поместить эти данные в Pydantic-модель. * Сгенерировать `dict` без значений по умолчанию из входной модели (с использованием `exclude_unset`). - * Таким образом, можно обновлять только те значения, которые действительно установлены пользователем, вместо того чтобы переопределять значения, уже сохраненные в модели по умолчанию. + * Таким образом, можно обновлять только те значения, которые действительно установлены пользователем, вместо того чтобы переопределять уже сохраненные значения значениями по умолчанию из вашей модели. * Создать копию хранимой модели, обновив ее атрибуты полученными частичными обновлениями (с помощью параметра `update`). * Преобразовать скопированную модель в то, что может быть сохранено в вашей БД (например, с помощью `jsonable_encoder`). * Это сравнимо с повторным использованием метода модели `.model_dump()`, но при этом происходит проверка (и преобразование) значений в типы данных, которые могут быть преобразованы в JSON, например, `datetime` в `str`. @@ -97,7 +83,7 @@ /// tip | Подсказка -Эту же технику можно использовать и для операции HTTP `PUT`. +На самом деле эту же технику можно использовать и для операции HTTP `PUT`. Но в приведенном примере используется `PATCH`, поскольку он был создан именно для таких случаев использования. diff --git a/docs/ru/docs/tutorial/body.md b/docs/ru/docs/tutorial/body.md index b61f3e7a0..537d7ebc9 100644 --- a/docs/ru/docs/tutorial/body.md +++ b/docs/ru/docs/tutorial/body.md @@ -32,9 +32,10 @@ {* ../../docs_src/body/tutorial001_py310.py hl[5:9] *} + Так же, как при объявлении параметров запроса: когда атрибут модели имеет значение по умолчанию, он не обязателен. Иначе он обязателен. Используйте `None`, чтобы сделать его просто необязательным. -Например, модель выше описывает такой JSON "объект" (или Python `dict`): +Например, модель выше описывает такой JSON "`object`" (или Python `dict`): ```JSON { @@ -45,7 +46,7 @@ } ``` -...так как `description` и `tax` являются необязательными (со значением по умолчанию `None`), такой JSON "объект" тоже будет корректным: +...так как `description` и `tax` являются необязательными (со значением по умолчанию `None`), такой JSON "`object`" тоже будет корректным: ```JSON { @@ -73,7 +74,7 @@ * Передаст полученные данные в параметр `item`. * Поскольку внутри функции вы объявили его с типом `Item`, у вас будет поддержка со стороны редактора кода (автозавершение и т. п.) для всех атрибутов и их типов. * Сгенерирует определения JSON Schema для вашей модели; вы можете использовать их и в других местах, если это имеет смысл для вашего проекта. -* Эти схемы будут частью сгенерированной схемы OpenAPI и будут использоваться автоматической документацией UIs. +* Эти схемы будут частью сгенерированной схемы OpenAPI и будут использоваться автоматической документацией UIs. ## Автоматическая документация { #automatic-docs } @@ -127,14 +128,6 @@ JSON Schema ваших моделей будет частью сгенериро {* ../../docs_src/body/tutorial002_py310.py *} -/// info | Информация - -В Pydantic v1 метод назывался `.dict()`, в Pydantic v2 он был помечен как устаревший (но всё ещё поддерживается) и переименован в `.model_dump()`. - -Примеры здесь используют `.dict()` для совместимости с Pydantic v1, но если вы можете использовать Pydantic v2, используйте `.model_dump()`. - -/// - ## Тело запроса + параметры пути { #request-body-path-parameters } Вы можете одновременно объявить параметры пути и тело запроса. @@ -143,6 +136,7 @@ JSON Schema ваших моделей будет частью сгенериро {* ../../docs_src/body/tutorial003_py310.py hl[15:16] *} + ## Тело запроса + параметры пути + параметры запроса { #request-body-path-query-parameters } Вы также можете одновременно объявить параметры **тела**, **пути** и **запроса**. @@ -153,7 +147,7 @@ JSON Schema ваших моделей будет частью сгенериро Параметры функции будут распознаны следующим образом: -* Если параметр также объявлен в **пути**, он будет использоваться как параметр пути. +* Если параметр также объявлен в **пути**, он будет использоваться как path-параметр. * Если параметр имеет **скалярный тип** (например, `int`, `float`, `str`, `bool` и т. п.), он будет интерпретирован как параметр **запроса**. * Если параметр объявлен как тип **модели Pydantic**, он будет интерпретирован как **тело** запроса. @@ -161,7 +155,7 @@ JSON Schema ваших моделей будет частью сгенериро FastAPI понимает, что значение `q` не является обязательным из-за значения по умолчанию `= None`. -Аннотации типов `str | None` (Python 3.10+) или `Union[str, None]` (Python 3.9+) не используются FastAPI для определения обязательности; он узнает, что параметр не обязателен, потому что у него есть значение по умолчанию `= None`. +Аннотации типов `str | None` (Python 3.10+) или `Union` в `Union[str, None]` (Python 3.9+) не используются FastAPI для определения обязательности; он узнает, что параметр не обязателен, потому что у него есть значение по умолчанию `= None`. Но добавление аннотаций типов позволит вашему редактору кода лучше вас поддерживать и обнаруживать ошибки. @@ -169,4 +163,4 @@ FastAPI понимает, что значение `q` не является об ## Без Pydantic { #without-pydantic } -Если вы не хотите использовать модели Pydantic, вы также можете использовать параметры **Body**. См. раздел документации [Тело — Несколько параметров: Единичные значения в теле](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}. +Если вы не хотите использовать модели Pydantic, вы также можете использовать параметры **Body**. См. раздел документации [Тело запроса - Несколько параметров: Единичные значения в теле](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}. diff --git a/docs/ru/docs/tutorial/extra-models.md b/docs/ru/docs/tutorial/extra-models.md index 2f0ce4e33..03156f2b4 100644 --- a/docs/ru/docs/tutorial/extra-models.md +++ b/docs/ru/docs/tutorial/extra-models.md @@ -22,21 +22,13 @@ {* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *} -/// info | Информация +### Про `**user_in.model_dump()` { #about-user-in-model-dump } -В Pydantic v1 метод назывался `.dict()`, в Pydantic v2 он помечен как устаревший (но всё ещё поддерживается) и переименован в `.model_dump()`. +#### `.model_dump()` из Pydantic { #pydantics-model-dump } -В примерах здесь используется `.dict()` для совместимости с Pydantic v1, но если вы используете Pydantic v2, следует использовать `.model_dump()`. +`user_in` — это Pydantic-модель класса `UserIn`. -/// - -### Про `**user_in.dict()` { #about-user-in-dict } - -#### `.dict()` из Pydantic { #pydantics-dict } - -`user_in` - это Pydantic-модель класса `UserIn`. - -У Pydantic-моделей есть метод `.dict()`, который возвращает `dict` с данными модели. +У Pydantic-моделей есть метод `.model_dump()`, который возвращает `dict` с данными модели. Поэтому, если мы создадим Pydantic-объект `user_in` таким способом: @@ -47,10 +39,10 @@ user_in = UserIn(username="john", password="secret", email="john.doe@example.com и затем вызовем: ```Python -user_dict = user_in.dict() +user_dict = user_in.model_dump() ``` -то теперь у нас есть `dict` с данными модели в переменной `user_dict` (это `dict` вместо объекта Pydantic-модели). +то теперь у нас есть `dict` с данными в переменной `user_dict` (это `dict` вместо объекта Pydantic-модели). И если мы вызовем: @@ -58,7 +50,7 @@ user_dict = user_in.dict() print(user_dict) ``` -мы можем получить `dict` с такими данными: +мы получим Python `dict` с: ```Python { @@ -71,7 +63,7 @@ print(user_dict) #### Распаковка `dict` { #unpacking-a-dict } -Если мы возьмём `dict` наподобие `user_dict` и передадим его в функцию (или класс), используя `**user_dict`, Python распакует его. Он передаст ключи и значения `user_dict` напрямую как аргументы типа ключ-значение. +Если мы возьмём `dict` наподобие `user_dict` и передадим его в функцию (или класс), используя `**user_dict`, Python его "распакует". Он передаст ключи и значения `user_dict` напрямую как аргументы типа ключ-значение. Поэтому, продолжая описанный выше пример с `user_dict`, написание такого кода: @@ -79,7 +71,7 @@ print(user_dict) UserInDB(**user_dict) ``` -Будет работать так же, как примерно такой код: +будет эквивалентно: ```Python UserInDB( @@ -90,7 +82,7 @@ UserInDB( ) ``` -Или, если для большей точности мы напрямую используем `user_dict` с любым потенциальным содержимым, то этот пример будет выглядеть так: +Или, более точно, если использовать `user_dict` напрямую, с любым содержимым, которое он может иметь в будущем: ```Python UserInDB( @@ -101,22 +93,22 @@ UserInDB( ) ``` -#### Pydantic-модель из содержимого другой модели { #a-pydantic-model-from-the-contents-of-another } +#### Pydantic-модель из содержимого другой { #a-pydantic-model-from-the-contents-of-another } -Как в примере выше мы получили `user_dict` из `user_in.dict()`, этот код: +Как в примере выше мы получили `user_dict` из `user_in.model_dump()`, этот код: ```Python -user_dict = user_in.dict() +user_dict = user_in.model_dump() UserInDB(**user_dict) ``` будет равнозначен такому: ```Python -UserInDB(**user_in.dict()) +UserInDB(**user_in.model_dump()) ``` -...потому что `user_in.dict()` - это `dict`, и затем мы указываем, чтобы Python его "распаковал", когда передаём его в `UserInDB` и ставим перед ним `**`. +...потому что `user_in.model_dump()` — это `dict`, и затем мы указываем, чтобы Python его "распаковал", когда передаём его в `UserInDB` с префиксом `**`. Таким образом мы получаем Pydantic-модель на основе данных из другой Pydantic-модели. @@ -125,10 +117,10 @@ UserInDB(**user_in.dict()) И затем, если мы добавим дополнительный именованный аргумент `hashed_password=hashed_password` как здесь: ```Python -UserInDB(**user_in.dict(), hashed_password=hashed_password) +UserInDB(**user_in.model_dump(), hashed_password=hashed_password) ``` -... то мы получим что-то подобное: +...то в итоге получится что-то подобное: ```Python UserInDB( @@ -142,13 +134,13 @@ UserInDB( /// warning | Предупреждение -Вспомогательные функции `fake_password_hasher` и `fake_save_user` используются только для демонстрации возможного потока данных и, конечно, не обеспечивают настоящую безопасность. +Вспомогательные дополнительные функции `fake_password_hasher` и `fake_save_user` используются только для демонстрации возможного потока данных и, конечно, не обеспечивают настоящую безопасность. /// ## Сократите дублирование { #reduce-duplication } -Сокращение дублирования кода - это одна из главных идей **FastAPI**. +Сокращение дублирования кода — это одна из главных идей **FastAPI**. Поскольку дублирование кода повышает риск появления багов, проблем с безопасностью, проблем десинхронизации кода (когда вы обновляете код в одном месте, но не обновляете в другом), и т.д. @@ -166,7 +158,7 @@ UserInDB( ## `Union` или `anyOf` { #union-or-anyof } -Вы можете определить ответ как `Union` из двух или более типов. Это означает, что ответ должен соответствовать одному из них. +Вы можете объявить HTTP-ответ как `Union` из двух или более типов. Это означает, что HTTP-ответ может быть любым из них. Он будет определён в OpenAPI как `anyOf`. @@ -174,7 +166,7 @@ UserInDB( /// note | Примечание -При объявлении `Union`, сначала указывайте наиболее детальные типы, затем менее детальные. В примере ниже более детальный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`. +При объявлении `Union` сначала указывайте наиболее специфичный тип, затем менее специфичный. В примере ниже более специфичный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`. /// @@ -192,19 +184,19 @@ UserInDB( some_variable: PlaneItem | CarItem ``` -Но если мы помещаем его в `response_model=PlaneItem | CarItem` мы получим ошибку, потому что Python попытается произвести **некорректную операцию** между `PlaneItem` и `CarItem` вместо того, чтобы интерпретировать это как аннотацию типа. +Но если мы поместим это в присваивание `response_model=PlaneItem | CarItem`, мы получим ошибку, потому что Python попытается произвести **некорректную операцию** между `PlaneItem` и `CarItem` вместо того, чтобы интерпретировать это как аннотацию типа. ## Список моделей { #list-of-models } -Таким же образом вы можете определять ответы как списки объектов. +Таким же образом вы можете объявлять HTTP-ответы, возвращающие списки объектов. -Для этого используйте `typing.List` из стандартной библиотеки Python (или просто `list` в Python 3.9 и выше): +Для этого используйте стандартный `typing.List` в Python (или просто `list` в Python 3.9 и выше): {* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *} ## Ответ с произвольным `dict` { #response-with-arbitrary-dict } -Вы также можете определить ответ, используя произвольный одноуровневый `dict` и определяя только типы ключей и значений без использования Pydantic-моделей. +Вы также можете объявить HTTP-ответ, используя обычный произвольный `dict`, объявив только тип ключей и значений, без использования Pydantic-модели. Это полезно, если вы заранее не знаете корректных названий полей/атрибутов (которые будут нужны при использовании Pydantic-модели). @@ -214,6 +206,6 @@ some_variable: PlaneItem | CarItem ## Резюме { #recap } -Используйте несколько Pydantic-моделей и свободно применяйте наследование для каждой из них. +Используйте несколько Pydantic-моделей и свободно применяйте наследование для каждого случая. -Вам не обязательно иметь единственную модель данных для каждой сущности, если эта сущность должна иметь возможность быть в разных "состояниях". Как в случае с "сущностью" пользователя, у которого есть состояния с полями `password`, `password_hash` и без пароля. +Вам не обязательно иметь единственную модель данных для каждой сущности, если эта сущность должна иметь возможность быть в разных "состояниях". Как в случае с "сущностью" пользователя, у которого есть состояние, включающее `password`, `password_hash` и отсутствие пароля. diff --git a/docs/ru/docs/tutorial/query-params-str-validations.md b/docs/ru/docs/tutorial/query-params-str-validations.md index 3a4ecc37d..2bc2fb22c 100644 --- a/docs/ru/docs/tutorial/query-params-str-validations.md +++ b/docs/ru/docs/tutorial/query-params-str-validations.md @@ -8,7 +8,7 @@ Query-параметр `q` имеет тип `str | None`, это означает, что он имеет тип `str`, но также может быть `None`. Значение по умолчанию действительно `None`, поэтому FastAPI будет знать, что он не обязателен. -/// note | Технические детали +/// note | Примечание FastAPI поймёт, что значение `q` не обязательно, из‑за значения по умолчанию `= None`. @@ -177,7 +177,7 @@ q: str = Query(default="rick") **Значение по умолчанию** у **параметра функции** — это **настоящее значение по умолчанию**, что более интуитивно для Python. 😌 -Вы можете **вызвать** эту же функцию в **других местах** без FastAPI, и она будет **работать как ожидается**. Если есть **обязательный** параметр (без значения по умолчанию), ваш **редактор кода** сообщит об ошибке, **Python** тоже пожалуется, если вы запустите её без передачи обязательного параметра. +Вы можете **вызвать** эту же функцию в **других местах** без FastAPI, и она будет **работать как ожидается**. Если есть **обязательный** параметр (без значения по умолчанию), ваш **редактор** сообщит об ошибке, **Python** тоже пожалуется, если вы запустите её без передачи обязательного параметра. Если вы не используете `Annotated`, а применяете **(устаревший) стиль со значением по умолчанию**, то при вызове этой функции без FastAPI в **других местах** вам нужно **помнить** о том, что надо передать аргументы, чтобы всё работало корректно, иначе значения будут не такими, как вы ожидаете (например, вместо `str` будет `QueryInfo` или что-то подобное). И ни редактор, ни Python не будут ругаться при самом вызове функции — ошибка проявится лишь при операциях внутри. @@ -191,7 +191,7 @@ q: str = Query(default="rick") ## Регулярные выражения { #add-regular-expressions } -Вы можете определить регулярное выражение `pattern`, которому должен соответствовать параметр: +Вы можете определить регулярное выражение `pattern`, которому должен соответствовать параметр: {* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *} @@ -205,20 +205,6 @@ q: str = Query(default="rick") Теперь вы знаете, что когда они понадобятся, вы сможете использовать их в **FastAPI**. -### `regex` из Pydantic v1 вместо `pattern` { #pydantic-v1-regex-instead-of-pattern } - -До Pydantic версии 2 и до FastAPI 0.100.0 этот параметр назывался `regex`, а не `pattern`, но сейчас он устарел. - -Вы всё ещё можете встретить такой код: - -//// tab | Pydantic v1 - -{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *} - -//// - -Имейте в виду, что это устарело, и код следует обновить на использование нового параметра `pattern`. 🤓 - ## Значения по умолчанию { #default-values } Конечно, можно использовать и другие значения по умолчанию, не только `None`. @@ -279,7 +265,7 @@ q: Annotated[str | None, Query(min_length=3)] = None http://localhost:8000/items/?q=foo&q=bar ``` -вы получите множественные значения query-параметра `q` (`foo` и `bar`) в виде Python-`list` внутри вашей *функции обработки пути*, в *параметре функции* `q`. +вы получите множественные значения *query-параметров* `q` (`foo` и `bar`) в виде Python-`list` внутри вашей *функции-обработчика пути*, в *параметре функции* `q`. Таким образом, ответ на этот URL будет: @@ -331,7 +317,7 @@ http://localhost:8000/items/ {* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *} -/// note | Технические детали +/// note | Примечание Имейте в виду, что в этом случае FastAPI не будет проверять содержимое списка. @@ -345,7 +331,7 @@ http://localhost:8000/items/ Эта информация будет включена в сгенерированную OpenAPI-схему и использована интерфейсами документации и внешними инструментами. -/// note | Технические детали +/// note | Примечание Помните, что разные инструменты могут иметь разный уровень поддержки OpenAPI. @@ -415,7 +401,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems /// -Например, эта кастомная проверка убеждается, что ID элемента начинается с `isbn-` для номера книги ISBN или с `imdb-` для ID URL фильма на IMDB: +Например, эта кастомная проверка убеждается, что ID элемента начинается с `isbn-` для номера книги ISBN или с `imdb-` для ID URL фильма на IMDB: {* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *} @@ -455,7 +441,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems Затем с `random.choice()` можно получить **случайное значение** из списка — то есть кортеж вида `(id, name)`. Это будет что‑то вроде `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`. -После этого мы **распаковываем** эти два значения кортежа в переменные `id` и `name`. +После этого мы **присваиваем эти два значения** кортежа переменным `id` и `name`. Так что, если пользователь не передал ID элемента, он всё равно получит случайную рекомендацию. diff --git a/docs/ru/docs/tutorial/response-model.md b/docs/ru/docs/tutorial/response-model.md index 07308c1db..22a811cd5 100644 --- a/docs/ru/docs/tutorial/response-model.md +++ b/docs/ru/docs/tutorial/response-model.md @@ -6,11 +6,11 @@ {* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *} -FastAPI будет использовать этот тип ответа для: +FastAPI будет использовать этот возвращаемый тип, чтобы: -* **Валидации** возвращаемых данных. - * Если данные невалидны (например, отсутствует поле), это означает, что код *вашего* приложения работает некорректно и возвращает не то, что должен. В таком случае будет возвращена ошибка сервера вместо неправильных данных. Так вы и ваши клиенты можете быть уверены, что получите ожидаемые данные и ожидаемую структуру. -* Добавления **JSON Schema** для ответа в OpenAPI *операции пути*. +* **Валидировать** возвращаемые данные. + * Если данные невалидны (например, отсутствует поле), это означает, что код *вашего* приложения работает некорректно и возвращает не то, что должен. В таком случае будет возвращена ошибка сервера вместо неправильных данных. Так вы и ваши клиенты можете быть уверены, что получите ожидаемые данные и ожидаемую структуру данных. +* Добавить **JSON Schema** для ответа в OpenAPI *операции пути*. * Это будет использовано **автоматической документацией**. * Это также будет использовано инструментами автоматической генерации клиентского кода. @@ -23,7 +23,7 @@ FastAPI будет использовать этот тип ответа для: Бывают случаи, когда вам нужно или хочется возвращать данные, которые не в точности соответствуют объявленному типу. -Например, вы можете хотеть **возвращать словарь (dict)** или объект из базы данных, но **объявить его как Pydantic-модель**. Тогда Pydantic-модель выполнит документирование данных, валидацию и т.п. для объекта, который вы вернули (например, словаря или объекта из базы данных). +Например, вы можете хотеть **возвращать словарь** или объект из базы данных, но **объявить его как Pydantic-модель**. Тогда Pydantic-модель выполнит документирование данных, валидацию и т.п. для объекта, который вы вернули (например, словаря или объекта из базы данных). Если вы добавите аннотацию возвращаемого типа, инструменты и редакторы кода начнут жаловаться (и будут правы), что функция возвращает тип (например, dict), отличный от объявленного (например, Pydantic-модель). @@ -47,13 +47,13 @@ FastAPI будет использовать этот тип ответа для: `response_model` принимает тот же тип, что вы бы объявили для поля Pydantic-модели, то есть это может быть одна Pydantic-модель, а может быть, например, `list` Pydantic-моделей, как `List[Item]`. -FastAPI будет использовать `response_model` для документации, валидации и т. п., а также для **конвертации и фильтрации выходных данных** к объявленному типу. +FastAPI будет использовать этот `response_model` для документирования, валидации данных и т.п., а также для **конвертации и фильтрации выходных данных** к объявленному типу. /// tip | Совет -Если у вас в редакторе кода, mypy и т. п. включены строгие проверки типов, вы можете объявить возвращаемый тип функции как `Any`. +Если у вас в редакторе кода, mypy и т.п. включены строгие проверки типов, вы можете объявить возвращаемый тип функции как `Any`. -Так вы сообщите редактору, что намеренно возвращаете что угодно. Но FastAPI всё равно выполнит документацию данных, валидацию, фильтрацию и т.д. с помощью `response_model`. +Так вы сообщите редактору, что намеренно возвращаете что угодно. Но FastAPI всё равно выполнит документирование, валидацию, фильтрацию данных и т.д. с помощью `response_model`. /// @@ -61,7 +61,7 @@ FastAPI будет использовать `response_model` для докуме Если вы объявите и возвращаемый тип, и `response_model`, приоритет будет у `response_model`, именно его использует FastAPI. -Так вы можете добавить корректные аннотации типов к своим функциям, даже если фактически возвращаете тип, отличный от модели ответа, чтобы ими пользовались редактор и инструменты вроде mypy. И при этом FastAPI продолжит выполнять валидацию данных, документацию и т.д. с использованием `response_model`. +Так вы можете добавить корректные аннотации типов к своим функциям, даже если фактически возвращаете тип, отличный от модели ответа, чтобы ими пользовались редактор кода и инструменты вроде mypy. И при этом FastAPI продолжит выполнять валидацию данных, документацию и т.д. с использованием `response_model`. Вы также можете указать `response_model=None`, чтобы отключить создание модели ответа для данной *операции пути*. Это может понадобиться, если вы добавляете аннотации типов для вещей, не являющихся валидными полями Pydantic. Пример вы увидите ниже. @@ -75,7 +75,7 @@ FastAPI будет использовать `response_model` для докуме Чтобы использовать `EmailStr`, сначала установите `email-validator`. -Создайте [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активируйте его и затем установите пакет, например: +Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, а затем установите пакет, например: ```console $ pip install email-validator @@ -105,7 +105,7 @@ $ pip install "pydantic[email]" /// -## Добавить модель для ответа { #add-an-output-model } +## Добавить выходную модель { #add-an-output-model } Вместо этого мы можем создать входную модель с паролем в открытом виде и выходную модель без него: @@ -123,7 +123,7 @@ $ pip install "pydantic[email]" ### `response_model` или возвращаемый тип { #response-model-or-return-type } -В этом случае, поскольку две модели различаются, если бы мы аннотировали возвращаемый тип функции как `UserOut`, редактор и инструменты пожаловались бы, что мы возвращаем неверный тип, так как это разные классы. +В этом случае, поскольку две модели различаются, если бы мы аннотировали возвращаемый тип функции как `UserOut`, редактор кода и инструменты пожаловались бы, что мы возвращаем неверный тип, так как это разные классы. Поэтому в этом примере мы должны объявить тип ответа в параметре `response_model`. @@ -135,33 +135,33 @@ $ pip install "pydantic[email]" Мы хотим, чтобы FastAPI продолжал **фильтровать** данные с помощью модели ответа. Так что, даже если функция возвращает больше данных, в ответ будут включены только поля, объявленные в модели ответа. -В предыдущем примере, поскольку классы были разными, нам пришлось использовать параметр `response_model`. Но это также означает, что мы теряем поддержку от редактора и инструментов, проверяющих возвращаемый тип функции. +В предыдущем примере, поскольку классы были разными, нам пришлось использовать параметр `response_model`. Но это также означает, что мы теряем поддержку от редактора кода и инструментов, проверяющих возвращаемый тип функции. Однако в большинстве таких случаев нам нужно лишь **отфильтровать/убрать** некоторые данные, как в этом примере. -И в этих случаях мы можем использовать классы и наследование, чтобы воспользоваться **аннотациями типов** функций для лучшей поддержки в редакторе и инструментах и при этом получить **фильтрацию данных** от FastAPI. +И в этих случаях мы можем использовать классы и наследование, чтобы воспользоваться **аннотациями типов** функций для лучшей поддержки в редакторе кода и инструментах и при этом получить **фильтрацию данных** от FastAPI. {* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *} -Так мы получаем поддержку инструментов (редакторы, mypy) — код корректен с точки зрения типов — и одновременно получаем фильтрацию данных от FastAPI. +Так мы получаем поддержку инструментов — редакторов кода и mypy, так как этот код корректен с точки зрения типов — и одновременно получаем фильтрацию данных от FastAPI. Как это работает? Давайте разберёмся. 🤓 ### Аннотации типов и инструменты { #type-annotations-and-tooling } -Сначала посмотрим, как это увидят редакторы, mypy и другие инструменты. +Сначала посмотрим, как это увидят редактор кода, mypy и другие инструменты. -`BaseUser` содержит базовые поля. Затем `UserIn` наследуется от `BaseUser` и добавляет поле `password`, то есть он включает все поля обеих моделей. +`BaseUser` содержит базовые поля. Затем `UserIn` наследуется от `BaseUser` и добавляет поле `password`, то есть он будет включать все поля обеих моделей. Мы аннотируем возвращаемый тип функции как `BaseUser`, но фактически возвращаем экземпляр `UserIn`. -Редактор, mypy и другие инструменты не будут возражать, потому что с точки зрения типов `UserIn` — подкласс `BaseUser`, что означает, что это *валидный* тип везде, где ожидается что-то, являющееся `BaseUser`. +Редактор кода, mypy и другие инструменты не будут возражать, потому что с точки зрения типов `UserIn` — подкласс `BaseUser`, что означает, что это *валидный* тип везде, где ожидается что-то, являющееся `BaseUser`. ### Фильтрация данных FastAPI { #fastapi-data-filtering } -Теперь, для FastAPI: он увидит возвращаемый тип и убедится, что то, что вы возвращаете, включает **только** поля, объявленные в этом типе. +Теперь для FastAPI: он увидит возвращаемый тип и убедится, что то, что вы возвращаете, включает **только** поля, объявленные в этом типе. -FastAPI делает несколько вещей внутри вместе с Pydantic, чтобы гарантировать, что те же правила наследования классов не используются для фильтрации возвращаемых данных, иначе вы могли бы вернуть гораздо больше данных, чем ожидали. +FastAPI делает несколько вещей внутри вместе с Pydantic, чтобы гарантировать, что те же правила наследования классов не используются для фильтрации возвращаемых данных, иначе вы могли бы в итоге вернуть намного больше данных, чем ожидали. Таким образом вы получаете лучшее из обоих миров: аннотации типов с **поддержкой инструментов** и **фильтрацию данных**. @@ -171,17 +171,17 @@ FastAPI делает несколько вещей внутри вместе с -И обе модели используются в интерактивной документации API: +И обе модели будут использоваться в интерактивной документации API: ## Другие аннотации возвращаемых типов { #other-return-type-annotations } -Бывают случаи, когда вы возвращаете что-то, что не является валидным полем Pydantic, и аннотируете это в функции только ради поддержки инструментов (редактор, mypy и т. д.). +Бывают случаи, когда вы возвращаете что-то, что не является валидным полем Pydantic, и аннотируете это в функции только ради поддержки инструментов (редактор кода, mypy и т.д.). ### Возврат Response напрямую { #return-a-response-directly } -Самый распространённый случай — [возвращать Response напрямую, как описано далее в разделах для продвинутых](../advanced/response-directly.md){.internal-link target=_blank}. +Самый распространённый случай — [возвращать Response напрямую, как описано далее в разделах документации для продвинутых](../advanced/response-directly.md){.internal-link target=_blank}. {* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *} @@ -195,7 +195,7 @@ FastAPI делает несколько вещей внутри вместе с {* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *} -Это тоже сработает, так как `RedirectResponse` — подкласс `Response`, и FastAPI автоматически обработает этот случай. +Это тоже сработает, так как `RedirectResponse` — подкласс `Response`, и FastAPI автоматически обработает этот простой случай. ### Некорректные аннотации возвращаемых типов { #invalid-return-type-annotations } @@ -209,15 +209,15 @@ FastAPI делает несколько вещей внутри вместе с ### Отключить модель ответа { #disable-response-model } -Продолжая пример выше, вы можете не хотеть использовать стандартную валидацию данных, документацию, фильтрацию и т.д., выполняемые FastAPI. +Продолжая пример выше, вы можете не хотеть использовать стандартные валидацию данных, документирование, фильтрацию и т.п., выполняемые FastAPI. -Но при этом вы можете хотеть сохранить аннотацию возвращаемого типа в функции, чтобы пользоваться поддержкой инструментов (редакторы, проверки типов вроде mypy). +Но при этом вы можете хотеть сохранить аннотацию возвращаемого типа в функции, чтобы пользоваться поддержкой инструментов вроде редакторов кода и инструментов проверки типов (например, mypy). В этом случае вы можете отключить генерацию модели ответа, установив `response_model=None`: {* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *} -Так FastAPI пропустит генерацию модели ответа, и вы сможете использовать любые аннотации возвращаемых типов, не влияя на ваше приложение FastAPI. 🤓 +Так FastAPI пропустит генерацию модели ответа, и вы сможете использовать любые аннотации возвращаемых типов, которые вам нужны, без влияния на ваше приложение FastAPI. 🤓 ## Параметры кодирования модели ответа { #response-model-encoding-parameters } @@ -252,20 +252,6 @@ FastAPI делает несколько вещей внутри вместе с /// info | Информация -В Pydantic v1 метод назывался `.dict()`, в Pydantic v2 он был помечен как устаревший (но всё ещё поддерживается) и переименован в `.model_dump()`. - -Примеры здесь используют `.dict()` для совместимости с Pydantic v1, но если вы используете Pydantic v2, применяйте `.model_dump()`. - -/// - -/// info | Информация - -FastAPI использует метод `.dict()` у Pydantic-моделей с параметром `exclude_unset`, чтобы добиться такого поведения. - -/// - -/// info | Информация - Вы также можете использовать: * `response_model_exclude_defaults=True` @@ -312,7 +298,7 @@ FastAPI достаточно умен (на самом деле, это Pydantic Обратите внимание, что значения по умолчанию могут быть любыми, не только `None`. -Это может быть список (`[]`), число с плавающей точкой `10.5` и т. д. +Это может быть список (`[]`), число с плавающей точкой `10.5` и т.д. /// @@ -346,7 +332,7 @@ FastAPI достаточно умен (на самом деле, это Pydantic #### Использование `list` вместо `set` { #using-lists-instead-of-sets } -Если вы забыли использовать `set` и применили `list` или `tuple`, FastAPI всё равно преобразует это в `set`, и всё будет работать корректно: +Если вы забыли использовать `set` и применили `list` или `tuple` вместо него, FastAPI всё равно преобразует это в `set`, и всё будет работать корректно: {* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *} diff --git a/docs/ru/docs/tutorial/schema-extra-example.md b/docs/ru/docs/tutorial/schema-extra-example.md index 5891f0d12..e4a97c880 100644 --- a/docs/ru/docs/tutorial/schema-extra-example.md +++ b/docs/ru/docs/tutorial/schema-extra-example.md @@ -8,36 +8,14 @@ Вы можете объявить `examples` для модели Pydantic, которые будут добавлены в сгенерированную JSON Schema. -//// tab | Pydantic v2 - {* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *} -//// - -//// tab | Pydantic v1 - -{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *} - -//// - Эта дополнительная информация будет добавлена как есть в выходную **JSON Schema** этой модели и будет использоваться в документации API. -//// tab | Pydantic v2 - -В Pydantic версии 2 вы будете использовать атрибут `model_config`, который принимает `dict`, как описано в Документации Pydantic: Конфигурация. +Вы можете использовать атрибут `model_config`, который принимает `dict`, как описано в Документации Pydantic: Конфигурация. Вы можете задать `"json_schema_extra"` с `dict`, содержащим любые дополнительные данные, которые вы хотите видеть в сгенерированной JSON Schema, включая `examples`. -//// - -//// tab | Pydantic v1 - -В Pydantic версии 1 вы будете использовать внутренний класс `Config` и `schema_extra`, как описано в Документации Pydantic: Настройка схемы. - -Вы можете задать `schema_extra` со `dict`, содержащим любые дополнительные данные, которые вы хотите видеть в сгенерированной JSON Schema, включая `examples`. - -//// - /// tip | Подсказка Вы можете использовать тот же приём, чтобы расширить JSON Schema и добавить свою собственную дополнительную информацию. @@ -124,7 +102,7 @@ OpenAPI 3.1.0 (используется начиная с FastAPI 0.99.0) доб Ключи `dict` идентифицируют каждый пример, а каждое значение — это ещё один `dict`. -Каждый конкретный пример‑`dict` в `examples` может содержать: +Каждый конкретный пример `dict` в `examples` может содержать: * `summary`: Краткое описание примера. * `description`: Подробное описание, которое может содержать текст в Markdown. @@ -135,7 +113,7 @@ OpenAPI 3.1.0 (используется начиная с FastAPI 0.99.0) доб {* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *} -### OpenAPI-примеры в UI документации { #openapi-examples-in-the-docs-ui } +### OpenAPI-примеры в UI документации { #openapi-examples-in-the-docs-ui } С `openapi_examples`, добавленным в `Body()`, страница `/docs` будет выглядеть так: @@ -213,7 +191,7 @@ OpenAPI также добавила поля `example` и `examples` в друг ### Swagger UI и специфичные для OpenAPI `examples` { #swagger-ui-and-openapi-specific-examples } -Раньше, поскольку Swagger UI не поддерживал несколько примеров JSON Schema (по состоянию на 2023-08-26), у пользователей не было способа показать несколько примеров в документации. +Теперь, поскольку Swagger UI не поддерживал несколько примеров JSON Schema (по состоянию на 2023-08-26), у пользователей не было способа показать несколько примеров в документации. Чтобы решить это, FastAPI `0.103.0` **добавил поддержку** объявления того же старого, **специфичного для OpenAPI**, поля `examples` с новым параметром `openapi_examples`. 🤓 diff --git a/docs/tr/llm-prompt.md b/docs/tr/llm-prompt.md index 297b0a0e6..2ba922ec5 100644 --- a/docs/tr/llm-prompt.md +++ b/docs/tr/llm-prompt.md @@ -4,10 +4,16 @@ Translate to Turkish (Türkçe). Language code: tr. +### Core principle + +Don't translate word-by-word. Rewrite naturally in Turkish as if writing the doc from scratch. Preserve meaning, but prioritize fluency over literal accuracy. + ### Grammar and tone - Use instructional Turkish, consistent with existing Turkish docs. -- Use imperative/guide language when appropriate (e.g. “açalım”, “gidin”, “kopyalayalım”). +- Use imperative/guide language (e.g. "açalım", "gidin", "kopyalayalım", "bir bakalım"). +- Avoid filler words and overly long sentences. +- Ensure sentences make sense in Turkish context — adjust structure, conjunctions, and verb forms as needed for natural flow (e.g. use "Ancak" instead of "Ve" when connecting contrasting sentences, use "-maktadır/-mektedir" for formal statements). ### Headings @@ -15,13 +21,23 @@ Language code: tr. ### Quotes -- Alıntı stili mevcut Türkçe dokümanlarla tutarlı tutun (genellikle metin içinde ASCII tırnak işaretleri kullanılır). -- Satır içi kod, kod blokları, URL'ler veya dosya yolları içindeki tırnak işaretlerini asla değiştirmeyin. +- Keep quote style consistent with existing Turkish docs (typically ASCII quotes in text). +- Never modify quotes inside inline code, code blocks, URLs, or file paths. ### Ellipsis -- Üç nokta (...) stili mevcut Türkçe dokümanlarla tutarlı tutun. -- Kod, URL veya CLI örneklerindeki `...` ifadesini asla değiştirmeyin. +- Keep ellipsis style (`...`) consistent with existing Turkish docs. +- Never modify `...` in code, URLs, or CLI examples. + +### Consistency + +- Use the same translation for the same term throughout the document. +- If you translate a concept one way, keep it consistent across all occurrences. + +### Links and references + +- Never modify link syntax like `{.internal-link target=_blank}`. +- Keep markdown link structure intact: `[text](url){.internal-link}`. ### Preferred translations / glossary