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
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
Sets em Python: Desvendando O(1) com Operações de Conjunto

Sets em Python: Desvendando O(1) com Operações de Conjunto

Se você já usou um set em Python apenas para remover duplicatas com um .add() aqui e ali, está deixando na mesa uma das estruturas de dados mais poderosas e mal compreendidas da linguagem. Sets não são apenas listas sem duplicatas — são implementações de conjuntos matemáticos otimizadas para operações de associate arrays com tempo constante O(1), suportando operações que vão de interseção até diferença simétrica com performance que impressiona. ...

9 de março de 2026 · 8 min · 1694 words · Riverfount
Argon2 em Python: o jeito certo de guardar senhas

Argon2 em Python: o jeito certo de guardar senhas

MD5, SHA-256 e bcrypt ainda aparecem em bases de código novas. O que está errado nessa escolha, como o Argon2 resolve o problema e por que o pepper é a camada extra que separa uma implementação boa de uma implementação sólida.

5 de março de 2026 · 13 min · 2610 words · Riverfount
Profiling em Python: Encontrando Gargalos com cProfile e memory_profiler

Profiling em Python: Encontrando Gargalos com cProfile e memory_profiler

Existe um padrão que se repete em quase todo projeto Python que cresce. O código funciona, os testes passam, a feature está pronta — aí alguém percebe que uma rota específica demora três segundos quando deveria demorar duzentos milissegundos. Ou que um processo que roda em batch está consumindo 4 GB de RAM sem nenhuma razão óbvia. O instinto natural é abrir o código e começar a suspeitar. Aquele loop ali, essa chamada de banco, aquela list comprehension aninhada. O problema é que intuição é um método caro: você otimiza o que acha que é lento, gasta horas em algo que mal contribui para o tempo total, e o gargalo real continua intacto. ...

2 de março de 2026 · 12 min · 2506 words · Riverfount