00:00:00Você é um fã fervoroso de Python? Tipo, você é alguém que só quer escrever código Python
00:00:05e mais nada? Bem, se esse for o seu caso, eu tenho a solução ideal. É um framework chamado
00:00:11Reflex, que visa resolver o atrito e a complexidade de transformar código Python full-stack
00:00:17em aplicações web prontas para produção. Neste vídeo, vamos ver o que é
00:00:22o Reflex, como ele funciona e se todo esse hype realmente faz sentido.
00:00:30O principal problema que o Reflex tenta resolver é a necessidade de desenvolvedores Python aprenderem
00:00:36uma stack inteiramente diferente, incluindo JavaScript, React, roteamento e bundlers, apenas para
00:00:43criar uma interface web funcional para seu código. O Reflex permite criar apps full-stack
00:00:50100% em Python puro, para que você foque em uma única linguagem em toda a stack sem
00:00:56trocas de contexto. Eles afirmam que, desde o lançamento, desenvolvedores já criaram mais de 1 milhão de apps
00:01:03com esse framework e que 30% das empresas Fortune 500 o utilizam em suas
00:01:10ferramentas internas. Recentemente, eles investiram pesado em IA e lançaram uma
00:01:15ferramenta chamada Reflex Build, que basicamente permite criar seu app a partir de um único prompt.
00:01:21Além disso, suportam integrações com outros SDKs e ferramentas para conectar facilmente seu app
00:01:26a serviços populares como Databricks, Okta, Stripe, AWS, etc. Tudo isso parece impressionante,
00:01:34mas quero colocar a mão na massa e testar esse código eu mesmo para ver como funciona na prática.
00:01:40Vamos começar criando um novo diretório, ReflexTest, e entrar nele via cd. Daqui,
00:01:44a documentação diz que podemos rodar estes três comandos para iniciar nosso projeto Reflex. Vamos começar
00:01:48rodando pip install reflex e depois reflex init. Aqui, temos a opção de começar com um
00:01:53dos templates deles. Mas para esta demo, vamos simplificar e escolher a opção
00:01:57de app reflex em branco. Feito isso, podemos abrir o projeto no editor de código. Abrindo a
00:02:02pasta reflex test, é no arquivo reflex test.py que todo o nosso app reside. Podemos ver
00:02:09que ele tem uma seção de componentes RX e uma classe de estado. Vamos rodar Reflex Build no terminal
00:02:15para iniciar o app. Ele abre a aplicação na porta 3000 e podemos ver o resultado aqui no navegador.
00:02:20Agora, vamos ver como o Reflex gerencia o estado. Podemos começar adicionando uma variável simples de contagem.
00:02:25E para alterar esse valor, também precisamos definir uma função para isso. Então, abaixo da
00:02:29variável count, definimos uma função increment que apenas aumenta o contador em um. É
00:02:34recomendado adicionar o decorador RX event no topo, o que permite a checagem estática de tipos e
00:02:39garante que os manipuladores de eventos recebam o número e os tipos corretos de argumentos. Então,
00:02:44adicionamos um botão simples no retorno do componente RX. Ele mostrará a contagem no campo
00:02:48de texto e disparará a função de incremento ao clicar. O Reflex suporta hot reloading. Se
00:02:53salvarmos o arquivo e abrirmos o navegador, veremos o botão que incrementa o valor
00:02:58toda vez que o pressionamos. Agora vamos tentar algo mais interessante. Vamos criar um array de itens
00:03:02no nosso estado. Em teoria, deveríamos conseguir renderizar esses itens como uma lista usando
00:03:08este loop for inline. Mas isso não funcionará porque esse valor não é conhecido em tempo de compilação.
00:03:13Veja, o Reflex funciona assim: quando você roda o app, o front-end é compilado para JavaScript
00:03:18que roda no navegador, o que o Reflex chama de tempo de compilação. O back-end continua
00:03:23em Python e roda no servidor durante a execução do app. Isso é chamado de runtime
00:03:27no Reflex. Então, não podemos usar um loop for de Python puro na renderização do componente,
00:03:32embora possamos fazer operações Python fora do bloco de renderização. Mas como iteramos itens no
00:03:37bloco do componente? Para isso, precisamos definir uma função simples render item que vai
00:03:42exibir nosso item assim. E então usamos a função RxForEach no bloco de renderização
00:03:47do componente para fazer o loop. Agora vemos nossos itens renderizados corretamente. O mesmo vale para
00:03:53renderização condicional. Não podemos usar comandos if-else comuns no bloco de retorno. Em vez disso,
00:03:58precisamos usar a função RxConditional. E se clicarmos no botão mais de cinco
00:04:02vezes, veremos o texto aparecer no app. A última coisa a verificar é como buscar e
00:04:08renderizar dados. Para esta demo, vamos buscar um fato aleatório inútil da API “random useless facts”
00:04:12e exibi-lo em uma caixa de texto. Primeiro, adicionamos um booleano para indicar se os
00:04:17dados estão sendo carregados e uma string vazia para armazenar o fato. Depois, definimos uma
00:04:22função assíncrona de busca de dados que define o carregamento como verdadeiro. Ela usará a
00:04:27biblioteca HTTPX para buscar o fato aleatório e salvá-lo na variável de estado fact. Também estou
00:04:33adicionando um pequeno atraso de um segundo com async IO para vermos o carregamento em tempo
00:04:38real. Terminada a operação, voltamos o booleano de carregamento para falso. Note que
00:04:43adicionamos a operação yield aqui. Sempre que quisermos atualizar a UI várias vezes em um
00:04:48manipulador de eventos, usamos yield para enviar uma atualização ao renderizador. Neste caso, assim
00:04:52que o estado de carregamento muda, queremos atualizar a UI. Não esqueçamos de
00:04:57importar HTTPX e async IO no topo. Por fim, na função de renderização, usamos uma simples
00:05:03função RX conditional para mostrar um spinner de loading ou o fato, conforme o estado atual. E se
00:05:08quisermos que esta função dispare sempre que a página carregar, adicionamos um decorador ao
00:05:12componente RX que ativará a função fetch data no carregamento da página. Agora, ao recarregar, vemos
00:05:18o fato aleatório sendo buscado e renderizado na tela. A última coisa que quero fazer
00:05:22aqui é examinar a pasta .web. Como podemos ver, tudo o que escrevemos é compilado e
00:05:27renderizado em um app React por baixo dos panos, que utiliza Vite e Tailwind. Ele inclusive
00:05:33possui um React Router para o gerenciamento de rotas. Sinceramente, assim que vi isso, fiquei muito
00:05:38decepcionado. Achei que tivessem criado um compilador JavaScript customizado ou algo original.
00:05:42Mas isso significa que o Reflex é apenas mais uma camada de abstração sobre o React. Então, tenho
00:05:47sentimentos mistos sobre o Reflex. Por um lado, a ideia de ter um framework full-stack
00:05:53em Python que permite escrever tudo em Python puro é muito legal. Mas foi decepcionante
00:05:59descobrir que, internamente, ele apenas envelopa um app React em vez de usar Python nativo. Isso
00:06:05torna tudo mais complexo, pois você é forçado a reaprender uma nova arquitetura e entender
00:06:11como o Reflex gerencia o estado, sem falar nos casos específicos que podem ocorrer; talvez fosse
00:06:16melhor ficar com o React, que é um framework sólido e testado. Se eu fosse criar
00:06:22um projeto com back-end em Python, ainda usaria um framework JavaScript para o front-end.
00:06:28O Reflex não me convenceu a adotar Python no full-stack. Mas essa é apenas a minha opinião. O que
00:06:34você acha do Reflex? Gosta dessa ideia de um framework full-stack em Python como este?
00:06:39Estou curioso para saber sua opinião. E se gostou deste vídeo, não deixe de
00:06:44clicar no botão de gostei aqui embaixo. E não se esqueça de se inscrever no canal.
00:06:50Aqui foi o Andris, da Better Stack, e vejo vocês nos próximos vídeos.