O .env que você não deveria ter commitado

O .env que você não deveria ter commitado

Existe uma busca no GitHub que retorna milhares de resultados úteis para um atacante: filename:.env DB_PASSWORD. Repositórios públicos com arquivos .env commitados por acidente, contendo senhas de banco, chaves de API, segredos JWT — tudo em texto claro, indexado, pesquisável. Não é incompetência. É o resultado natural de uma prática que parece razoável: colocar credenciais num arquivo, adicionar esse arquivo ao .gitignore, e confiar que o .gitignore vai proteger. Funciona até o dia que não funciona — um git add . no momento errado, um novo membro do time que clona o repo e cria o .env a partir do .env.example sem perceber que o exemplo já tem valores reais, ou um editor que cria arquivos temporários fora do padrão ignorado. ...

6 de abril de 2026 · 12 min · 2546 words · Riverfount
JWT: três erros que todo mundo comete na primeira implementação

JWT: três erros que todo mundo comete na primeira implementação

Você abre o README do PyJWT, copia o exemplo de dez linhas, gera um token, valida do outro lado — e funciona. O token tem o user_id, expira em uma hora, a assinatura bate. O que pode estar errado? Bastante coisa. JWT é um dos padrões mais mal implementados em aplicações web, não porque seja complicado, mas porque os exemplos básicos funcionam mesmo com configurações que criam vulnerabilidades sérias. O código roda, os testes passam, e os problemas aparecem meses depois — ou não aparecem, porque ninguém tentou explorar. ...

26 de março de 2026 · 9 min · 1773 words · Riverfount
A GIL finalmente saiu do caminho: o que muda com o Python 3.14 free-threaded

A GIL finalmente saiu do caminho: o que muda com o Python 3.14 free-threaded

Você tem quatro núcleos disponíveis. Seu script Python usa um. Isso nunca foi um bug — era uma decisão de design que durava desde 1992. O Python 3.14 não remove essa limitação de vez, mas dá o passo mais concreto até agora para deixá-la para trás. O que é a GIL e por que ela importa A Global Interpreter Lock é um mutex que garante que apenas uma thread execute bytecode Python por vez dentro de um processo CPython. Ela existe por uma razão pragmática: simplifica imensamente o gerenciamento de memória e a integração com extensões C, que historicamente assumem que esse lock existe. ...

23 de março de 2026 · 9 min · 1728 words · Riverfount
Injeção de dependência do jeito certo: IoC com Dishka e FastAPI

Injeção de dependência do jeito certo: IoC com Dishka e FastAPI

Você já escreveu algo assim numa aplicação FastAPI? 1 2 3 4 5 6 7 8 9 @router.get("/orders/{order_id}") async def get_order(order_id: int): db = SessionLocal() try: repo = OrderRepository(db) service = OrderService(repo, settings.TAX_RATE) return await service.get_order(order_id) finally: db.close() O código funciona. Mas há um problema sério: cada endpoint é responsável por montar sua própria árvore de dependências. Quando OrderService precisar de um CacheClient e de um EventPublisher, quem vai sofrer é quem escreve — e depois testa — cada endpoint. O FastAPI tem seu próprio sistema de Depends() que resolve parte disso, mas tem limites quando a aplicação cresce e os grafos de dependência ficam complexos. É aqui que entra o conceito de Inversão de Controle e, mais especificamente, uma biblioteca que acerta onde o Depends() tropeça: o Dishka. ...

20 de março de 2026 · 10 min · 1995 words · Riverfount
Você provavelmente não precisa desse try/finally

Você provavelmente não precisa desse try/finally

Existe um padrão que aparece em quase todo projeto Python com mais de algumas semanas de vida. Ele tem variações, mas o esqueleto é sempre o mesmo: 1 2 3 4 5 6 conn = get_db_connection() try: resultado = conn.execute(query) return resultado finally: conn.close() Funciona. Fecha a conexão mesmo se der exceção. Ninguém vai questionar em code review. O problema é que esse bloco vai se repetir em todo lugar que precisar de uma conexão — e quando a lógica de encerramento mudar (adicionar log, métricas, rollback), você vai caçar essa duplicação pelo projeto inteiro. ...

19 de março de 2026 · 7 min · 1385 words · Riverfount
Por que seu script Python consome mais memória do que deveria

Por que seu script Python consome mais memória do que deveria

Se você já usou o memory_profiler para inspecionar um script que processa arquivos grandes, provavelmente se deparou com um gráfico de consumo de RAM que sobe em escada — e não desce. O arquivo tem 500 MB, o script consome 600, 700, às vezes mais de 1 GB, e o culpado raramente é o que parece. Este artigo começa exatamente aí: num script real com consumo excessivo de memória, explica por que ele se comporta assim, e mostra como generators e itertools resolvem o problema sem mudar a lógica de negócio. ...

17 de março de 2026 · 10 min · 1927 words · Riverfount
Testes que Realmente Testam: pytest Além do Básico

Testes que Realmente Testam: pytest Além do Básico

No artigo sobre injeção de dependência ficou um problema em aberto. A classe OrderService não dava para testar sem subir banco, sem fazer chamada HTTP real, sem criar arquivo em disco. A solução apresentada foi injetar as dependências pelo construtor — o que deixa o código testável. Mas testável não significa testado. Este artigo fecha esse loop. O objetivo aqui não é ensinar assert 1 == 1. É mostrar as ferramentas que separam uma suite de testes que protege o código de uma suite que só infla a cobertura: fixtures com escopo controlado, parametrize para eliminar duplicação, e mocks com pytest-mock para isolar dependências externas de verdade. ...

16 de março de 2026 · 11 min · 2255 words · Riverfount
Primeiro Plugin Niri: Uma Experiência com DankLinux

O Primeiro Plugin para niri + DankMaterialShell

O blog tem bastante conteúdo sobre software, Python e hardware embarcado. Mas há um lado que nunca apareceu por aqui: o ambiente de trabalho em si. Este é o primeiro relato sobre o setup com o compositor Wayland niri e o DankMaterialShell — e começa pelo primeiro plugin criado do zero para esse ambiente. A motivação foi simples: queria ver no painel a versão do kernel em uso e o tempo de uptime do sistema. Sem abrir terminal, sem script externo. Só um widget discreto na barra mostrando 6.19.6-arch1-1 ⏱ 7h 54m. ...

13 de março de 2026 · 6 min · 1076 words · Riverfount
Controlando Hardware pelo Celular: Uma Experiência com ESP32 e MQTT

Controlando Hardware pelo Celular: Uma Experiência com ESP32 e MQTT

O post anterior mostrou o Blink — o Hello World do hardware embarcado. Um LED piscando sozinho, controlado por um timer, sem nenhuma interação externa. Era o suficiente para validar o ambiente, mas deixava uma pergunta óbvia no ar: e se a gente quiser controlar esse LED de verdade? De outro dispositivo, em tempo real, sem cabos? Essa pergunta levou ao experimento deste post: usar o protocolo MQTT para acionar um LED no ESP32 a partir de um celular, com um broker Mosquitto rodando localmente no PC. O resultado funcionou. O caminho até lá teve algumas surpresas que valem ser documentadas. ...

11 de março de 2026 · 9 min · 1899 words · Riverfount
asyncio na prática: quando concorrência resolve e quando atrapalha

asyncio na prática: quando concorrência resolve e quando atrapalha

Se você chegou até aqui provavelmente já passou pelo profiling e encontrou um gargalo. A tentação imediata é jogar async/await em cima do problema e torcer para que o tempo de execução caia. Na maioria das vezes, não cai. Às vezes, piora. Este artigo começa mostrando exatamente esse cenário — código assíncrono que não resolve nada — e explica por quê. Depois mostra um caso onde asyncio faz diferença real, e só então desce para o mecanismo que explica os dois resultados. ...

10 de março de 2026 · 12 min · 2357 words · Riverfount