diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index d5730e247..a6a68584a 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -9,6 +9,7 @@ hide: ### Translations +* 🌐 Update Portuguese Translation for `docs/pt/docs/async.md`. PR [#13863](https://github.com/fastapi/fastapi/pull/13863) by [@EdmilsonRodrigues](https://github.com/EdmilsonRodrigues). * 📝 Fix highlight line in `docs/ja/docs/tutorial/body.md`. PR [#13927](https://github.com/fastapi/fastapi/pull/13927) by [@KoyoMiyazaki](https://github.com/KoyoMiyazaki). * 🌐 Add Persian translation for `docs/fa/docs/environment-variables.md`. PR [#13923](https://github.com/fastapi/fastapi/pull/13923) by [@Mohammad222PR](https://github.com/Mohammad222PR). * 🌐 Add Persian translation for `docs/fa/docs/python-types.md`. PR [#13524](https://github.com/fastapi/fastapi/pull/13524) by [@Mohammad222PR](https://github.com/Mohammad222PR). diff --git a/docs/pt/docs/async.md b/docs/pt/docs/async.md index 0d6bdbf0e..4425eba77 100644 --- a/docs/pt/docs/async.md +++ b/docs/pt/docs/async.md @@ -40,7 +40,7 @@ def results(): --- -Se sua aplicação (de alguma forma) nĂŁo tem que se comunicar com nada mais e tem que esperar que o respondam, use `async def`. +Se sua aplicação (de alguma forma) nĂŁo tem que se comunicar com nada mais e esperar que o respondam, use `async def`. --- @@ -52,7 +52,7 @@ Se vocĂȘ simplesmente nĂŁo sabe, use apenas `def`. De qualquer forma, em ambos os casos acima, FastAPI irĂĄ trabalhar assincronamente e ser extremamente rĂĄpido. -Seguindo os passos acima, ele serĂĄ capaz de fazer algumas otimizaçÔes de performance. +Mas, seguindo os passos acima, ele serĂĄ capaz de fazer algumas otimizaçÔes de performance. ## Detalhes TĂ©cnicos @@ -66,36 +66,36 @@ Vamos ver aquela frase por partes na seção abaixo: ## CĂłdigo assĂ­ncrono -CĂłdigo assĂ­ncrono apenas significa que a linguagem 💬 tem um jeito de dizer para o computador / programa đŸ€– que em certo ponto, ele đŸ€– terĂĄ que esperar por *algo* para finalizar em outro lugar. Vamos dizer que esse *algo* seja chamado "arquivo lento" 📝. +CĂłdigo assĂ­ncrono apenas significa que a linguagem 💬 tem um jeito de dizer para o computador / programa đŸ€– que em certo ponto do cĂłdigo, ele đŸ€– terĂĄ que esperar *algo* finalizar em outro lugar. Vamos dizer que esse *algo* seja chamado "arquivo lento" 📝. -EntĂŁo, durante esse tempo, o computador pode ir e fazer outro trabalho, enquanto o "arquivo lento" 📝 termine. +EntĂŁo, durante esse tempo, o computador pode ir e fazer outro trabalho, enquanto o "arquivo lento" 📝 termina. -EntĂŁo o computador / programa đŸ€– irĂĄ voltar toda hora que tiver uma chance porquĂȘ ele ainda estĂĄ esperando o "arquivo lento", ou ele đŸ€– nunca irĂĄ terminar todo o trabalho que tem atĂ© esse ponto. E ele đŸ€– irĂĄ ver se alguma das tarefas que estava esperando jĂĄ terminaram, fazendo o que quer que tinham que fazer. +EntĂŁo o computador / programa đŸ€– irĂĄ voltar sempre que tiver uma chance, seja porque ele estĂĄ esperando novamente, ou quando ele đŸ€– terminar todo o trabalho que tem atĂ© esse ponto. E ele đŸ€– irĂĄ ver se alguma das tarefas que estava esperando jĂĄ terminaram de fazer o que quer que tinham que fazer. -Depois, ele đŸ€– pega a primeira tarefa para finalizar (vamos dizer, nosso "arquivo lento" 📝) e continua o que ele tem que fazer com isso. +Depois, ele đŸ€– pega a primeira tarefa para finalizar (vamos dizer, nosso "arquivo lento" 📝) e continua o que tem que fazer com ela. -Esse "esperar por algo" normalmente se refere a operaçÔes I/O que sĂŁo relativamente "lentas" (comparadas a velocidade do processador e da memĂłria RAM), como esperar por: +Esse "esperar por algo" normalmente se refere a operaçÔes I/O que sĂŁo relativamente "lentas" (comparadas Ă  velocidade do processador e da memĂłria RAM), como esperar por: * dados do cliente para serem enviados atravĂ©s da rede -* dados enviados pelo seu programa para serem recebidos pelo clente atravĂ©s da rede -* conteĂșdo de um arquivo no disco pra ser lido pelo sistema e entregar ao seu programa +* dados enviados pelo seu programa serem recebidos pelo clente atravĂ©s da rede +* conteĂșdo de um arquivo no disco ser lido pelo sistema e entregue ao seu programa * conteĂșdo que seu programa deu ao sistema para ser escrito no disco -* uma operação remota API -* uma operação no banco de dados para finalizar -* uma solicitação no banco de dados esperando o retorno do resultado +* uma operação em uma API remota +* uma operação no banco de dados finalizar +* uma solicitação no banco de dados retornar o resultado * etc. -Enquanto o tempo de execução Ă© consumido mais pela espera das operaçÔes I/O, essas operaçÔes sĂŁo chamadas de operaçÔes "limitadas por I/O". +Quanto o tempo de execução Ă© consumido majoritariamente pela espera de operaçÔes I/O, essas operaçÔes sĂŁo chamadas operaçÔes "limitadas por I/O". -Isso Ă© chamado de "assĂ­ncrono" porquĂȘ o computador / programa nĂŁo tem que ser "sincronizado" com a tarefa lenta, esperando pelo exato momento que a tarefa finalize, enquanto nĂŁo faz nada, para ser capaz de pegar o resultado da tarefa e dar continuidade ao trabalho. +Isso Ă© chamado de "assĂ­ncrono" porque o computador / programa nĂŁo tem que ser "sincronizado" com a tarefa lenta, esperando pelo momento exato em que a tarefa finaliza, enquanto nĂŁo faz nada, para ser capaz de pegar o resultado da tarefa e dar continuidade ao trabalho. -Ao invĂ©s disso, sendo um sistema "assĂ­ncrono", uma vez finalizada, a tarefa pode esperar um pouco (alguns microssegundos) para que o computador / programa finalize o que quer que esteja fazendo,e entĂŁo volte para pegar o resultado e continue trabalhando com ele. +Ao invĂ©s disso, sendo um sistema "assĂ­ncrono", uma vez finalizada, a tarefa pode esperar na fila um pouco (alguns microssegundos) para que o computador / programa finalize o que quer que esteja fazendo, e entĂŁo volte para pegar o resultado e continue trabalhando com ele. -Para "sĂ­ncrono" (contrĂĄrio de "assĂ­ncrono") tambĂ©m Ă© utilizado o termo "sequencial", porquĂȘ o computador / programa segue todos os passos, na sequĂȘncia, antes de trocar para uma tarefa diferente, mesmo se alguns passos envolvam esperar. +Para "sĂ­ncrono" (contrĂĄrio de "assĂ­ncrono") tambĂ©m Ă© utilizado o termo "sequencial", porquĂȘ o computador / programa segue todos os passos, em sequĂȘncia, antes de trocar para uma tarefa diferente, mesmo se alguns passos envolvam esperar. ### ConcorrĂȘncia e hambĂșrgueres -Essa idĂ©ia de cĂłdigo **assĂ­ncrono** descrito acima Ă© algo Ă s vezes chamado de **"concorrĂȘncia"**. E Ă© diferente de **"paralelismo"**. +Essa idĂ©ia de cĂłdigo **assĂ­ncrono** descrita acima Ă© Ă s vezes chamado de **"concorrĂȘncia"**. Isso Ă© diferente de **"paralelismo"**. **ConcorrĂȘncia** e **paralelismo** ambos sĂŁo relacionados a "diferentes coisas acontecendo mais ou menos ao mesmo tempo". @@ -105,117 +105,115 @@ Para ver essa diferença, imagine a seguinte histĂłria sobre hambĂșrgueres: ### HambĂșrgueres concorrentes -VocĂȘ vai com seu _crush_ :heart_eyes: na lanchonete, fica na fila enquanto o caixa pega os pedidos das pessoas na sua frente. +VocĂȘ vai com seu _crush_ na lanchonete, e fica na fila enquanto o caixa pega os pedidos das pessoas na sua frente. 😍 -EntĂŁo chega a sua vez, vocĂȘ pede dois saborosos hambĂșrgueres para vocĂȘ e seu _crush_ :heart_eyes:. +EntĂŁo chega a sua vez, vocĂȘ pede dois saborosos hambĂșrgueres para vocĂȘ e seu _crush_. 🍔🍔 -VocĂȘ paga. +O caixa diz alguma coisa para o cozinheiro na cozinha para que eles saivam que tĂȘm que preparar seus hambĂșrgueres (mesmo que ele esteja atualmente preparando os lanches dos outros clientes). -O caixa diz alguma coisa para o cara na cozinha para que ele tenha que preparar seus hambĂșrgueres (mesmo embora ele esteja preparando os lanches dos outros clientes). +VocĂȘ paga. 💾 O caixa te entrega seu nĂșmero de chamada. -Enquanto vocĂȘ espera, vocĂȘ vai com seu _crush_ :heart_eyes: e pega uma mesa, senta e conversa com seu _crush_ :heart_eyes: por um bom tempo (como seus hambĂșrgueres sĂŁo muito saborosos, leva um tempo para serem preparados). +Enquanto vocĂȘ espera, vocĂȘ vai com seu _crush_ e pega uma mesa, senta e conversa com seu _crush_ por um bom tempo (jĂĄ que seus hambĂșrgueres sĂŁo muito saborosos, e leva um tempo para serem preparados). -Enquanto vocĂȘ estĂĄ sentado na mesa com seu _crush_ :heart_eyes:, esperando os hambĂșrgueres, vocĂȘ pode gastar o tempo admirando como lindo, maravilhoso e esperto Ă© seu _crush_ :heart_eyes:. +JĂĄ que vocĂȘ estĂĄ sentado na mesa com seu _crush_, esperando os hambĂșrgueres, vocĂȘ pode passar esse tempo admirando o quĂŁo lindo, maravilhoso e esperto Ă© seu _crush_ ✹😍✹. -Enquanto espera e conversa com seu _crush_ :heart_eyes:, de tempos em tempos, vocĂȘ verifica o nĂșmero de chamada exibido no balcĂŁo para ver se jĂĄ Ă© sua vez. +Enquanto espera e conversa com seu _crush_, de tempos em tempos, vocĂȘ verifica o nĂșmero da chamada exibido no balcĂŁo para ver se jĂĄ Ă© sua vez. -EntĂŁo a certo ponto, Ă© finalmente sua vez. VocĂȘ vai no balcĂŁo, pega seus hambĂșrgueres e volta para a mesa. +EntĂŁo em algum momento, Ă© finalmente sua vez. VocĂȘ vai ao balcĂŁo, pega seus hambĂșrgueres e volta para a mesa. -VocĂȘ e seu _crush_ :heart_eyes: comem os hambĂșrgueres e aproveitam o tempo. +VocĂȘ e seu _crush_ comem os hambĂșrgueres e aproveitam o tempo. ✹ --- -Imagine que vocĂȘ seja o computador / programa nessa histĂłria. +Imagine que vocĂȘ seja o computador / programa nessa histĂłria. -Enquanto vocĂȘ estĂĄ na fila, tranquilo, esperando por sua vez, nĂŁo estĂĄ fazendo nada "produtivo". Mas a fila Ă© rĂĄpida porquĂȘ o caixa sĂł estĂĄ pegando os pedidos, entĂŁo estĂĄ tudo bem. +Enquanto vocĂȘ estĂĄ na fila, vocĂȘ estĂĄ somente ocioso 😮, esperando por sua vez, sem fazer nada muito "produtivo". Mas a fila Ă© rĂĄpida porque o caixa sĂł estĂĄ pegando os pedidos (nĂŁo os preparando), entĂŁo estĂĄ tudo bem. -EntĂŁo, quando Ă© sua vez, vocĂȘ faz o trabalho "produtivo" de verdade, vocĂȘ processa o menu, decide o que quer, pega a escolha de seu _crush_ :heart_eyes:, paga, verifica se entregou o valor correto em dinheiro ou cartĂŁo de crĂ©dito, verifica se foi cobrado corretamente, verifica se seu pedido estĂĄ correto etc. +EntĂŁo, quando Ă© sua vez, vocĂȘ faz trabalho realmente "produtivo", vocĂȘ processa o menu, decide o que quer, pega a escolha de seu _crush_, paga, verifica se entregou o cartĂŁo ou a cĂ©dula correta, verifica se foi cobrado corretamente, verifica se seu pedido estĂĄ correto etc. -Mas entĂŁo, embora vocĂȘ ainda nĂŁo tenha os hambĂșrgueres, seu trabalho no caixa estĂĄ "pausado", porquĂȘ vocĂȘ tem que esperar seus hambĂșrgueres estarem prontos. +Mas entĂŁo, embora vocĂȘ ainda nĂŁo tenha os hambĂșrgueres, seu trabalho no caixa estĂĄ "pausado" ⏞, porque vocĂȘ tem que esperar 🕙 seus hambĂșrgueres ficarem prontos. -Mas enquanto vocĂȘ se afasta do balcĂŁo e senta na mesa com o nĂșmero da sua chamada, vocĂȘ pode trocar sua atenção para seu _crush_ :heart_eyes:, e "trabalhar" nisso. EntĂŁo vocĂȘ estĂĄ novamente fazendo algo muito "produtivo", como flertar com seu _crush_ :heart_eyes:. +Contudo, Ă  medida que vocĂȘ se afasta do balcĂŁo e senta na mesa, com um nĂșmero para sua chamada, vocĂȘ pode trocar 🔀 sua atenção para seu _crush_, e "trabalhar" ⏯ đŸ€“ nisso. EntĂŁo vocĂȘ estĂĄ novamente fazendo algo muito "produtivo", como flertar com seu _crush_ 😍. -EntĂŁo o caixa diz que "seus hambĂșrgueres estĂŁo prontos" colocando seu nĂșmero no balcĂŁo, mas vocĂȘ nĂŁo corre que nem um maluco imediatamente quando o nĂșmero exibido Ă© o seu. VocĂȘ sabe que ninguĂ©m irĂĄ roubar seus hambĂșrgueres porquĂȘ vocĂȘ tem o nĂșmero de chamada, e os outros tem os nĂșmeros deles. +EntĂŁo o caixa 💁 diz que "seus hambĂșrgueres estĂŁo prontos" colocando seu nĂșmero no balcĂŁo, mas vocĂȘ nĂŁo corre que nem um maluco imediatamente quando o nĂșmero exibido Ă© o seu. VocĂȘ sabe que ninguĂ©m irĂĄ roubar seus hambĂșrgueres porque vocĂȘ tem o seu nĂșmero da chamada, e os outros tĂȘm os deles. -EntĂŁo vocĂȘ espera que seu _crush_ :heart_eyes: termine a histĂłria que estava contando (terminar o trabalho atual / tarefa sendo processada), sorri gentilmente e diz que vocĂȘ estĂĄ indo buscar os hambĂșrgueres. +EntĂŁo vocĂȘ espera seu _crush_ terminar a histĂłria que estava contando (terminar o trabalho atual ⏯ / tarefa sendo processada đŸ€“), sorri gentilmente e diz que vocĂȘ estĂĄ indo buscar os hambĂșrgueres. -EntĂŁo vocĂȘ vai no balcĂŁo, para a tarefa inicial que agora estĂĄ finalizada, pega os hambĂșrgueres, e leva para a mesa. Isso finaliza esse passo / tarefa da interação com o balcĂŁo. Agora Ă© criada uma nova tarefa, "comer hambĂșrgueres", mas a tarefa anterior, "pegar os hambĂșrgueres" jĂĄ estĂĄ finalizada. +EntĂŁo vocĂȘ vai ao balcĂŁo 🔀, para a tarefa inicial que agora estĂĄ finalizada⏯, pega os hambĂșrgueres, agradece, e leva-os para a mesa. Isso finaliza esse passo / tarefa da interação com o balcĂŁo âč. Isso, por sua vez, cria uma nova tarefa, a de "comer hambĂșrgueres" 🔀 ⏯, mas a tarefa anterior de "pegar os hambĂșrgueres" jĂĄ estĂĄ finalizada âč. ### HambĂșrgueres paralelos -VocĂȘ vai com seu _crush_ :heart_eyes: em uma lanchonete paralela. +Agora vamos imaginar que esses nĂŁo sĂŁo "HambĂșrgueres Concorrentes", e sim "HambĂșrgueres Paralelos" -VocĂȘ fica na fila enquanto alguns (vamos dizer 8) caixas pegam os pedidos das pessoas na sua frente. +VocĂȘ vai com seu _crush_ na lanchonete paralela. -Todo mundo antes de vocĂȘ estĂĄ esperando pelos hambĂșrgueres estarem prontos antes de deixar o caixa porquĂȘ cada um dos 8 caixas vai e prepara o hambĂșrguer antes de pegar o prĂłximo pedido. +VocĂȘ fica na fila enquanto vĂĄrios (vamos dizer 8) caixas que tambĂ©m sĂŁo cozinheiros pegam os pedidos das pessoas na sua frente. -EntĂŁo Ă© finalmente sua vez, e pede 2 hambĂșrgueres muito saborosos para vocĂȘ e seu _crush_ :heart_eyes:. +Todo mundo na sua frente estĂĄ esperando seus hambĂșrgueres ficarem prontos antes de deixar o caixa porque cada um dos 8 caixas vai e prepara o hambĂșrguer logo apĂłs receber o pedido, antes de pegar o prĂłximo pedido. -VocĂȘ paga. +EntĂŁo Ă© finalmente sua vez, vocĂȘ pede 2 hambĂșrgueres muito saborosos para vocĂȘ e seu _crush_. + +VocĂȘ paga 💾. O caixa vai para a cozinha. -VocĂȘ espera, na frente do balcĂŁo, para que ninguĂ©m pegue seus hambĂșrgueres antes de vocĂȘ, jĂĄ que nĂŁo tem nĂșmeros de chamadas. +VocĂȘ espera, na frente do balcĂŁo 🕙, para que ninguĂ©m pegue seus hambĂșrgueres antes de vocĂȘ, jĂĄ que nĂŁo tem nĂșmeros de chamadas. -Enquanto vocĂȘ e seu _crush_ :heart_eyes: estĂŁo ocupados nĂŁo permitindo que ninguĂ©m passe a frente e pegue seus hambĂșrgueres assim que estiverem prontos, vocĂȘ nĂŁo pode dar atenção ao seu _crush_ :heart_eyes:. +Como vocĂȘ e seu _crush_ estĂŁo ocupados nĂŁo permitindo que ninguĂ©m passe na frente e pegue seus hambĂșrgueres assim que estiverem prontos, vocĂȘ nĂŁo pode dar atenção ao seu _crush_. 😞 -Isso Ă© trabalho "sĂ­ncrono", vocĂȘ estĂĄ "sincronizado" com o caixa / cozinheiro. VocĂȘ tem que esperar e estar lĂĄ no exato momento que o caixa / cozinheiro terminar os hambĂșrgueres e dĂĄ-los a vocĂȘ, ou entĂŁo, outro alguĂ©m pode pegĂĄ-los. +Isso Ă© trabalho "sĂ­ncrono", vocĂȘ estĂĄ "sincronizado" com o caixa / cozinheiro👹‍🍳. VocĂȘ tem que esperar 🕙 e estar lĂĄ no exato momento que o caixa / cozinheiro 👹‍🍳 terminar os hambĂșrgueres e os der a vocĂȘ, ou entĂŁo, outro alguĂ©m pode pegĂĄ-los. -EntĂŁo seu caixa / cozinheiro finalmente volta com seus hambĂșrgueres, depois de um longo tempo esperando por eles em frente ao balcĂŁo. +EntĂŁo seu caixa / cozinheiro 👹‍🍳 finalmente volta com seus hambĂșrgueres, depois de um longo tempo esperando 🕙 por eles em frente ao balcĂŁo. -VocĂȘ pega seus hambĂșrgueres e vai para a mesa com seu _crush_ :heart_eyes:. +VocĂȘ pega seus hambĂșrgueres e vai para a mesa com seu _crush_. -VocĂȘs comem os hambĂșrgueres, e o trabalho estĂĄ terminado. +VocĂȘs comem os hambĂșrgueres, e o trabalho estĂĄ terminado. âč -NĂŁo houve muita conversa ou flerte jĂĄ que a maior parte do tempo foi gasto esperando os lanches na frente do balcĂŁo. +NĂŁo houve muita conversa ou flerte jĂĄ que a maior parte do tempo foi gasto esperando 🕙 na frente do balcĂŁo. 😞 --- -Nesse cenĂĄrio dos hambĂșrgueres paralelos, vocĂȘ Ă© um computador / programa com dois processadores (vocĂȘ e seu _crush_ :heart_eyes:), ambos esperando e dedicando a atenção de estar "esperando no balcĂŁo" por um bom tempo. +Nesse cenĂĄrio dos hambĂșrgueres paralelos, vocĂȘ Ă© um computador / programa com dois processadores (vocĂȘ e seu _crush_), ambos esperando 🕙 e dedicando sua atenção ⏯ "esperando no balcĂŁo" 🕙 por um bom tempo. -A lanchonete paralela tem 8 processadores (caixas / cozinheiros). Enquanto a lanchonete dos hambĂșrgueres concorrentes tinham apenas 2 (um caixa e um cozinheiro). +A lanchonete paralela tem 8 processadores (caixas / cozinheiros), enquanto a lanchonete dos hambĂșrgueres concorrentes tinha apenas 2 (um caixa e um cozinheiro). -Ainda assim, a Ășltima experiĂȘncia nĂŁo foi a melhor. +Ainda assim, a experiĂȘncia final nĂŁo foi a melhor. 😞 --- -Essa poderia ser a histĂłria paralela equivalente aos hambĂșrgueres. +Essa seria o equivalente paralelo Ă  histĂłrio dos hambĂșrgueres. 🍔 Para um exemplo "mais real", imagine um banco. -AtĂ© recentemente, a maioria dos bancos tinha muitos caixas e uma grande fila. +AtĂ© recentemente, a maioria dos bancos tinham muitos caixas đŸ‘šâ€đŸ’ŒđŸ‘šâ€đŸ’ŒđŸ‘šâ€đŸ’ŒđŸ‘šâ€đŸ’Œ e uma grande fila 🕙🕙🕙🕙🕙🕙🕙🕙. -Todos os caixas fazendo todo o trabalho, um cliente apĂłs o outro. +Todos os caixas fazendo todo o trabalho, um cliente apĂłs o outro đŸ‘šâ€đŸ’ŒâŻ. -E vocĂȘ tinha que esperar na fila por um longo tempo ou poderia perder a vez. +E vocĂȘ tinha que esperar 🕙 na fila por um longo tempo ou poderia perder a vez. -VocĂȘ provavelmente nĂŁo gostaria de levar seu _crush_ :heart_eyes: com vocĂȘ para um rolezinho no banco. +VocĂȘ provavelmente nĂŁo gostaria de levar seu _crush_ 😍 com vocĂȘ para um rolezinho no banco 🏩. ### ConclusĂŁo dos hambĂșrgueres -Nesse cenĂĄrio dos "hambĂșrgueres com seu _crush_ :heart_eyes:", como tem muita espera, faz mais sentido ter um sistema concorrente. +Nesse cenĂĄrio dos "hambĂșrgueres com seu _crush_", como tem muita espera, faz mais sentido ter um sistema concorrente ⏾🔀⏯. Esse Ă© o caso da maioria das aplicaçÔes web. -Geralmente sĂŁo muitos usuĂĄrios, e seu servidor estĂĄ esperando pelas suas conexĂ”es nĂŁo tĂŁo boas para enviar as requisiçÔes. - -E entĂŁo esperando novamente pelas respostas voltarem. - -Essa "espera" Ă© medida em microssegundos, e ainda assim, somando tudo, Ă© um monte de espera no final. +Muitos, muitos usuĂĄrios, mas seu servidor estĂĄ esperando 🕙 pela sua conexĂŁo nĂŁo tĂŁo boa enviar suas requisiçÔes. -Por isso que faz muito mais sentido utilizar cĂłdigo assĂ­ncrono para APIs web. +E entĂŁo esperando 🕙 novamente as respostas voltarem. -A maioria dos frameworks Python existentes mais populares (incluindo Flask e Django) foram criados antes que os novos recursos assĂ­ncronos existissem em Python. EntĂŁo, os meios que eles podem ser colocados em produção para suportar execução paralela mais a forma antiga de execução assĂ­ncrona nĂŁo sĂŁo tĂŁo poderosos quanto as novas capacidades. +Essa "espera" 🕙 Ă© medida em microssegundos, mas ainda assim, somando tudo, Ă© um monte de espera no final. -Mesmo embora a especificação principal para web assĂ­ncrono em Python (ASGI) foi desenvolvida no Django, para adicionar suporte para WebSockets. +Por isso que faz bastante sentido utilizar cĂłdigo assĂ­ncrono ⏾🔀⏯ para APIs web. -Esse tipo de assincronicidade Ă© o que fez NodeJS popular (embora NodeJS nĂŁo seja paralelo) e que essa seja a força do Go como uma linguagem de programa. +Esse tipo de assincronicidade Ă© o que fez NodeJS popular (embora NodeJS nĂŁo seja paralelo) e essa Ă© a força do Go como uma linguagem de programação. E esse Ă© o mesmo nĂ­vel de performance que vocĂȘ tem com o **FastAPI**. -E como vocĂȘ pode ter paralelismo e sincronicidade ao mesmo tempo, vocĂȘ tem uma maior performance do que a maioria dos frameworks NodeJS testados e lado a lado com Go, que Ă© uma linguagem compilada prĂłxima ao C (tudo graças ao Starlette). +E como vocĂȘ pode ter paralelismo e assincronicidade ao mesmo tempo, vocĂȘ tem uma maior performance do que a maioria dos frameworks NodeJS testados e lado a lado com Go, que Ă© uma linguagem compilada, mais prĂłxima ao C (tudo graças ao Starlette). ### ConcorrĂȘncia Ă© melhor que paralelismo? @@ -225,64 +223,64 @@ ConcorrĂȘncia Ă© diferente de paralelismo. E Ă© melhor em cenĂĄrios **especĂ­fic EntĂŁo, para equilibrar tudo, imagine a seguinte historinha: -> VocĂȘ tem que limpar uma grande casa suja. +> VocĂȘ tem que limpar uma casa grande e suja. *Sim, essa Ă© toda a histĂłria*. --- -NĂŁo hĂĄ espera em lugar algum, apenas um monte de trabalho para ser feito, em mĂșltiplos cĂŽmodos da casa. +NĂŁo hĂĄ espera 🕙 em lugar algum, apenas um monte de trabalho para ser feito, em mĂșltiplos cĂŽmodos da casa. -VocĂȘ poderia ter chamadas como no exemplo dos hambĂșrgueres, primeiro a sala de estar, entĂŁo a cozinha, mas vocĂȘ nĂŁo estĂĄ esperando por nada, apenas limpar e limpar, as chamadas nĂŁo afetariam em nada. +VocĂȘ poderia ter turnos como no exemplo dos hambĂșrgueres, primeiro a sala de estar, entĂŁo a cozinha, mas como vocĂȘ nĂŁo estĂĄ esperando por nada, apenas limpando e limpando, as chamadas nĂŁo afetariam em nada. -Levaria o mesmo tempo para finalizar com ou sem chamadas (concorrĂȘncia) e vocĂȘ teria feito o mesmo tanto de trabalho. +Levaria o mesmo tempo para finalizar com ou sem turnos (concorrĂȘncia) e vocĂȘ teria feito o mesmo tanto de trabalho. Mas nesse caso, se vocĂȘ trouxesse os 8 ex-caixas / cozinheiros / agora-faxineiros, e cada um deles (mais vocĂȘ) pudessem dividir a casa para limpĂĄ-la, vocĂȘs fariam toda a limpeza em **paralelo**, com a ajuda extra, e terminariam muito mais cedo. Nesse cenĂĄrio, cada um dos faxineiros (incluindo vocĂȘ) poderia ser um processador, fazendo a sua parte do trabalho. -E a maior parte do tempo de execução Ă© tomada por trabalho (ao invĂ©s de ficar esperando), e o trabalho em um computador Ă© feito pela CPU, que podem gerar problemas que sĂŁo chamados de "limite de CPU". +E a maior parte do tempo de execução Ă© tomada por trabalho real (ao invĂ©s de ficar esperando), e o trabalho em um computador Ă© feito pela CPU. Eles chamam esses problemas de "limitados por CPU". --- -Exemplos comuns de limite de CPU sĂŁo coisas que exigem processamento matemĂĄtico complexo. +Exemplos comuns de operaçÔes limitadas por CPU sĂŁo coisas que exigem processamento matemĂĄtico complexo. Por exemplo: * **Processamento de ĂĄudio** ou **imagem** -* **VisĂŁo do Computador**: uma imagem Ă© composta por milhĂ”es de pixels, cada pixel tem 3 valores (cores, processamento que normalmente exige alguma computação em todos esses pixels ao mesmo tempo) +* **VisĂŁo Computacional**: uma imagem Ă© composta por milhĂ”es de pixels, cada pixel tem 3 valores / cores, processar isso normalmente exige alguma computação em todos esses pixels ao mesmo tempo -* **Machine Learning**: Normalmente exige muita multiplicação de matrizes e vetores. Pense numa grande folha de papel com nĂșmeros e multiplicando todos eles juntos e ao mesmo tempo. +* **Machine Learning**: Normalmente exige muita multiplicação de matrizes e vetores. Pense numa grande planilha com nĂșmeros e em multiplicar todos eles juntos e ao mesmo tempo. -* **Deep Learning**: Esse Ă© um subcampo do Machine Learning, entĂŁo o mesmo se aplica. A diferença Ă© que nĂŁo hĂĄ apenas uma grande folha de papel com nĂșmeros para multiplicar, mas um grande conjunto de folhas de papel, e em muitos casos, vocĂȘ utiliza um processador especial para construir e/ou usar modelos. +* **Deep Learning**: Esse Ă© um subcampo do Machine Learning, entĂŁo, o mesmo se aplica. A diferença Ă© que nĂŁo hĂĄ apenas uma grande planilha com nĂșmeros para multiplicar, mas um grande conjunto delas, e em muitos casos, vocĂȘ utiliza um processador especial para construir e/ou usar esses modelos. ### ConcorrĂȘncia + Paralelismo: Web + Machine learning Com **FastAPI** vocĂȘ pode levar a vantagem da concorrĂȘncia que Ă© muito comum para desenvolvimento web (o mesmo atrativo de NodeJS). -Mas vocĂȘ tambĂ©m pode explorar os benefĂ­cios do paralelismo e multiprocessamento (tendo mĂșltiplos processadores rodando em paralelo) para trabalhos pesados que geram **limite de CPU** como aqueles em sistemas de Machine Learning. +Mas vocĂȘ tambĂ©m pode explorar os benefĂ­cios do paralelismo e multiprocessamento (tendo mĂșltiplos processadores rodando em paralelo) para trabalhos **limitados por CPU** como aqueles em sistemas de Machine Learning. -Isso, mais o simples fato que Python Ă© a principal linguagem para **Data Science**, Machine Learning e especialmente Deep Learning, faz do FastAPI uma Ăłtima escolha para APIs web e aplicaçÔes com Data Science / Machine Learning (entre muitas outras). +Isso, somado ao simples fato que Python Ă© a principal linguagem para **Data Science**, Machine Learning e especialmente Deep Learning, faz do FastAPI uma Ăłtima escolha para APIs web e aplicaçÔes com Data Science / Machine Learning (entre muitas outras). Para ver como alcançar esse paralelismo em produção veja a seção sobre [Deployment](deployment/index.md){.internal-link target=_blank}. ## `async` e `await` -VersĂ”es modernas do Python tem um modo muito intuitivo para definir cĂłdigo assĂ­ncrono. Isso faz parecer normal o cĂłdigo "sequencial" e fazer o "esperar" para vocĂȘ nos momentos certos. +VersĂ”es modernas do Python tĂȘm um modo muito intuitivo para definir cĂłdigo assĂ­ncrono. Isso faz parecer do mesmo jeito do cĂłdigo normal "sequencial" e fazer a "espera" para vocĂȘ nos momentos certos. -Quando tem uma operação que exigirĂĄ espera antes de dar os resultados e tem suporte para esses recursos Python, vocĂȘ pode escrever assim: +Quando tem uma operação que exigirĂĄ espera antes de dar os resultados e tem suporte para esses novos recursos do Python, vocĂȘ pode escrever assim: ```Python burgers = await get_burgers(2) ``` -A chave aqui Ă© o `await`. Ele diz ao Python que ele tem que esperar por `get_burgers(2)` para finalizar suas coisas antes de armazenar os resultados em `burgers`. Com isso, o Python saberĂĄ que ele pode ir e fazer outras coisas nesse meio tempo (como receber outra requisição). +A chave aqui Ă© o `await`. Ele diz ao Python que ele tem que esperar por `get_burgers(2)` finalizar suas coisas 🕙 antes de armazenar os resultados em `burgers`. Com isso, o Python saberĂĄ que ele pode ir e fazer outras coisas 🔀 ⏯ nesse meio tempo (como receber outra requisição). Para o `await` funcionar, tem que estar dentro de uma função que suporte essa assincronicidade. Para fazer isso, apenas declare a função com `async def`: ```Python hl_lines="1" async def get_burgers(number: int): - # Fazer alguma coisa assĂ­ncrona para criar os hambĂșrgueres + # Faz alguma coisa assĂ­ncrona para criar os hambĂșrgueres return burgers ``` @@ -295,9 +293,9 @@ def get_sequential_burgers(number: int): return burgers ``` -Com `async def`, o Python sabe que, dentro dessa função, tem que estar ciente das expressĂ”es `await`, e que isso pode "pausar" a execução dessa função, e poderĂĄ fazer outra coisa antes de voltar. +Com `async def`, o Python sabe que, dentro dessa função, ele deve estar ciente das expressĂ”es `await`, e que isso poderĂĄ "pausar" ⏞ a execução dessa função, e ir fazer outra coisa 🔀 antes de voltar. -Quando vocĂȘ quiser chamar uma função `async def`, vocĂȘ tem que "esperar". EntĂŁo, isso nĂŁo funcionarĂĄ: +Quando vocĂȘ quiser chamar uma função `async def`, vocĂȘ tem que "esperar" ela. EntĂŁo, isso nĂŁo funcionarĂĄ: ```Python # Isso nĂŁo irĂĄ funcionar, porquĂȘ get_burgers foi definido com: async def @@ -319,13 +317,24 @@ async def read_burgers(): VocĂȘ deve ter observado que `await` pode ser usado somente dentro de funçÔes definidas com `async def`. -Mas ao mesmo tempo, funçÔes definidas com `async def` tem que ser aguardadas. EntĂŁo, funçÔes com `async def` pdem ser chamadas somente dentro de funçÔes definidas com `async def` tambĂ©m. +Mas ao mesmo tempo, funçÔes definidas com `async def` tĂȘm que ser "aguardadas". EntĂŁo, funçÔes com `async def` pdem ser chamadas somente dentro de funçÔes definidas com `async def` tambĂ©m. EntĂŁo, sobre o ovo e a galinha, como vocĂȘ chama a primeira função async? Se vocĂȘ estivar trabalhando com **FastAPI** nĂŁo terĂĄ que se preocupar com isso, porquĂȘ essa "primeira" função serĂĄ a sua *função de operação de rota*, e o FastAPI saberĂĄ como fazer a coisa certa. -Mas se vocĂȘ quiser usar `async` / `await` sem FastAPI, verifique a documentação oficial Python. +Mas se vocĂȘ quiser usar `async` / `await` sem FastAPI, vocĂȘ tambĂ©m pode fazĂȘ-lo. + +### Escreva seu prĂłprio cĂłdigo assĂ­ncrono + +Starlette (e **FastAPI**) sĂŁo baseados no AnyIO, o que o torna compatĂ­vel com ambos o asyncio da biblioteca padrĂŁo do Python, e o Trio. + +Em particular, vocĂȘ pode usar diretamente o AnyIO para seus casos de uso avançados de concorrĂȘncia que requerem padrĂ”es mais avançados no seu prĂłprio cĂłdigo. + +E atĂ© se vocĂȘ nĂŁo estiver utilizando FastAPI, vocĂȘ tambĂ©m pode escrever suas prĂłprias aplicaçÔes assĂ­ncronas com o AnyIO por ser altamente compatĂ­vel e ganhar seus benefĂ­cios (e.g. *concorrĂȘncia estruturada*). + +Eu criei outra biblioteca em cima do AnyIO, como uma fina camada acima, para melhorar um pouco as anotaçÔes de tipo e obter melhor **autocompletar**, **erros de linha**, etc. Ela tambĂ©m possui uma introdução amigĂĄvel e um tutorial para ajudar vocĂȘ a **entender** e escrever **seu prĂłprio cĂłdigo async**: Asyncer. Seria particularmente Ăștil se vocĂȘ precisar **combinar cĂłdigo async com cĂłdigo regular** (bloqueador/sĂ­ncrono). + ### Outras formas de cĂłdigo assĂ­ncrono @@ -337,25 +346,25 @@ Essa mesma sintaxe (ou quase a mesma) foi tambĂ©m incluĂ­da recentemente em vers Mas antes disso, controlar cĂłdigo assĂ­ncrono era bem mais complexo e difĂ­cil. -Nas versĂ”es anteriores do Python, vocĂȘ poderia utilizar threads ou Gevent. Mas o cĂłdigo Ă© um pouco mais complexo de entender, debugar, e pensar sobre. +Nas versĂ”es anteriores do Python, vocĂȘ poderia utilizar threads ou Gevent. Mas o cĂłdigo Ă© bem mais complexo de entender, debugar, e pensar sobre. -Nas versĂ”es anteriores do NodeJS / Navegador JavaScript, vocĂȘ poderia utilizar "callbacks". O que leva ao inferno do callback. +Nas versĂ”es anteriores do NodeJS / Navegador JavaScript, vocĂȘ utilizaria "callbacks". O que leva ao inferno do callback. ## Corrotinas -**Corrotina** Ă© apenas um jeito bonitinho para a coisa que Ă© retornada de uma função `async def`. O Python sabe que Ă© uma função que pode começar e terminar em algum ponto, mas que pode ser pausada internamente tambĂ©m, sempre que tiver um `await` dentro dela. +**Corrotina** Ă© apenas um jeito bonitinho para a coisa que Ă© retornada de uma função `async def`. O Python sabe que Ă© algo como uma função, que pode começar e que vai terminar em algum ponto, mas que pode ser pausada ⏞ internamente tambĂ©m, sempre que tiver um `await` dentro dela. -Mas toda essa funcionalidade de cĂłdigo assĂ­ncrono com `async` e `await` Ă© muitas vezes resumida como "corrotina". É comparĂĄvel ao principal recurso chave do Go, a "Gorotina". +Mas toda essa funcionalidade de cĂłdigo assĂ­ncrono com `async` e `await` Ă© muitas vezes resumida como usando "corrotinas". É comparĂĄvel ao principal recurso chave do Go, a "Gorrotina". ## ConclusĂŁo -Vamos ver a mesma frase com o conteĂșdo cima: +Vamos ver a mesma frase de cima: -> VersĂ”es modernas do Python tem suporte para **"cĂłdigo assĂ­ncrono"** usando algo chamado **"corrotinas"**, com sintaxe **`async` e `await`**. +> VersĂ”es modernas do Python tĂȘm suporte para **"cĂłdigo assĂ­ncrono"** usando algo chamado **"corrotinas"**, com sintaxe **`async` e `await`**. -Isso pode fazer mais sentido agora. +Isso pode fazer mais sentido agora. ✹ -Tudo isso Ă© o que deixa o FastAPI poderoso (atravĂ©s do Starlette) e que o faz ter uma performance impressionante. +Tudo isso Ă© o que empodera o FastAPI (atravĂ©s do Starlette) e que o faz ter uma performance tĂŁo impressionante. ## Detalhes muito tĂ©cnicos @@ -365,25 +374,25 @@ VocĂȘ pode provavelmente pular isso. Esses sĂŁo detalhes muito tĂ©cnicos de como **FastAPI** funciona por baixo do capĂŽ. -Se vocĂȘ tem algum conhecimento tĂ©cnico (corrotinas, threads, blocking etc) e estĂĄ curioso sobre como o FastAPI controla o `async def` vs normal `def`, vĂĄ em frente. +Se vocĂȘ tem certo conhecimento tĂ©cnico (corrotinas, threads, blocking etc) e estĂĄ curioso sobre como o FastAPI controla o `async def` vs normal `def`, vĂĄ em frente. /// ### FunçÔes de operação de rota -Quando vocĂȘ declara uma *função de operação de rota* com `def` normal ao invĂ©s de `async def`, ela Ă© rodada em uma threadpool externa que entĂŁo Ă© aguardada, ao invĂ©s de ser chamada diretamente (ela poderia bloquear o servidor). +Quando vocĂȘ declara uma *função de operação de rota* com `def` normal ao invĂ©s de `async def`, ela Ă© rodada em uma threadpool externa que Ă© entĂŁo aguardada, ao invĂ©s de ser chamada diretamente (jĂĄ que ela bloquearia o servidor). -Se vocĂȘ estĂĄ chegando de outro framework assĂ­ncrono que nĂŁo faz o trabalho descrito acima e vocĂȘ estĂĄ acostumado a definir triviais *funçÔes de operação de rota* com simples `def` para ter um mĂ­nimo ganho de performance (cerca de 100 nanosegundos), por favor observe que no **FastAPI** o efeito pode ser bem o oposto. Nesses casos, Ă© melhor usar `async def` a menos que suas *funçÔes de operação de rota* utilizem cĂłdigo que performem bloqueamento IO. +Se vocĂȘ estĂĄ chegando de outro framework assĂ­ncrono que nĂŁo funciona como descrito acima e vocĂȘ estĂĄ acostumado a definir *funçÔes de operação de rota* triviais somente de computação com simples `def` para ter um mĂ­nimo ganho de performance (cerca de 100 nanosegundos), por favor observe que no **FastAPI** o efeito pode ser bem o oposto. Nesses casos, Ă© melhor usar `async def` a menos que suas *funçÔes de operação de rota* utilizem cĂłdigo que performe bloqueamento IO. -Ainda, em ambas as situaçÔes, as chances sĂŁo que o **FastAPI** serĂĄ [ainda mais rĂĄpido](index.md#performance){.internal-link target=_blank} do que (ou ao menos comparĂĄvel a) seus frameworks antecessores. +Ainda, em ambas as situaçÔes, as chances sĂŁo que o **FastAPI** [ainda serĂĄ mais rĂĄpido](index.md#performance){.internal-link target=_blank} do que (ou ao menos comparĂĄvel a) seu framework anterior. ### DependĂȘncias -O mesmo se aplica para as dependĂȘncias. Se uma dependĂȘncia tem as funçÔes com padrĂŁo `def` ao invĂ©s de `async def`, ela Ă© rodada no threadpool externo. +O mesmo se aplica para as [dependĂȘncias](tutorial/dependencies/index.md){.internal-link target=_blank}. Se uma dependĂȘncia tem as funçÔes com padrĂŁo `def` ao invĂ©s de `async def`, ela Ă© rodada no threadpool externo. ### Sub-dependĂȘncias -VocĂȘ pode ter mĂșltiplas dependĂȘncias e sub-dependĂȘncias exigindo uma a outra (como parĂąmetros de definiçÔes de funçÔes), algumas delas podem ser criadas com `async def` e algumas com `def` normal. Isso ainda poderia funcionar, e aquelas criadas com `def` podem ser chamadas em uma thread externa ao invĂ©s de serem "aguardadas". +VocĂȘ pode ter mĂșltiplas dependĂȘncias e [sub-dependĂȘncias](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} requisitando uma Ă  outra (como parĂąmetros de definiçÔes de funçÔes), algumas delas podem ser criadas com `async def` e algumas com `def` normal. Isso ainda funcionaria, e aquelas criadas com `def` normal seriam chamadas em uma thread externa (do threadpool) ao invĂ©s de serem "aguardadas". ### Outras funçÔes de utilidade @@ -395,6 +404,6 @@ Se sua função de utilidade Ă© uma função normal com `def`, ela serĂĄ chamada --- -Novamente, esses sĂŁo detalhes muito tĂ©cnicos que provavelmente possam ser Ășteis caso vocĂȘ esteja procurando por eles. +Novamente, esses sĂŁo detalhes muito tĂ©cnicos que provavelmente seriam Ășteis caso vocĂȘ esteja procurando por eles. Caso contrĂĄrio, vocĂȘ deve ficar bem com as dicas da seção acima: Com pressa?.