Skip to main content

Decorator de cache para funções e métodos Python, com backends InMemory e SQLite, TTL configurável, hash estável de parâmetros e serialização segura.

Project description

PyCacheable

Decorator de cache para métodos e funções Python com backends em memória e SQLite — serialização automática com estratégia JSON-first + pickle fallback, hash estável de parâmetros, suporte a instância/estado e arquitetura plugável.


Problema

Em muitos aplicativos Python existem métodos que:

  • fazem consultas repetidas ao banco de dados ou a APIs externas;
  • recebem os mesmos parâmetros múltiplas vezes;
  • repetem trabalho caro de CPU ou I/O;
  • ou seja: fazem o mesmo trabalho mais de uma vez, desperdiçando tempo e recursos.

Sem um mecanismo de cache, cada chamada resulta em reexecução completa, levando a latências elevadas, carga extra no banco/serviço, e experiência de usuário piorada.


Solução

A biblioteca fornece:

  • Um decorator @cacheable(...) que envolve funções ou métodos, gera uma chave estável a partir dos parâmetros (serialização canônica + sha256);
  • Suporte a backends:
    • InMemoryCache: cache volátil em memória com LRU + TTL.
    • SQLiteCache: cache persistente em disco (SQLite) com TTL, ideal para entre execuções ou processos;
  • Logs claros de fluxo: HIT / MISS / EXPIRE — permitindo entender se o cache está funcionando;
  • Serialização segura:
    • JSON-first para estruturas simples (seguro, sem risco de RCE)
    • Pickle fallback para objetos complexos (flexível)
  • Métodos auxiliares:
    • .cache_clear(), .cache_info() no wrapper para inspeção/manutenção;

Como usar

from src.pycacheable.backend_sqlite import SQLiteCache
from src.pycacheable.backend_memory import InMemoryCache
from src.pycacheable.cacheable import cacheable

mem = InMemoryCache(max_entries=512)
disk = SQLiteCache(path="./.cache/myapp.sqlite")


class Repo:
    @cacheable(ttl=60, backend=mem)
    def get_user(self, user_id: int) -> dict:
        # consulta cara ao banco
        return {"user_id": user_id, "name": f"user{user_id}"}

    @cacheable(ttl=300, backend=disk)
    def get_orders(self, user_id: int, status: str = "open") -> list:
        return [{"order_id": 101, "user_id": user_id, "status": status}]


repo = Repo()
u1 = repo.get_user(42)  # MISS → executa consulta
u2 = repo.get_user(42)  # HIT → retorna cache, consulta não é executada

Benefícios

  • Menor latência em chamadas repetidas (hit quase instantâneo).
  • Menor carga no banco/serviço, menos I/O repetido.
  • Persistência local (via SQLite) permite cache entre reinícios/processos.
  • Transparente para o usuário da função — apenas aplicar o decorator.
  • Logs e métricas ajudam a monitorar impacto real.
  • Serialização segura com JSON-first (sem risco de arbitrary code execution).

Quando usar

  • Funções/métodos com resultado determinístico (mesmos parâmetros → mesmo resultado)
  • Consultas idempotentes e repetidas
  • Cálculos caros de CPU ou I/O
  • Cenários onde latência importa e repetição deve ser evitada

Considerações e limites

  • O cache evita reexecuções somente se os parâmetros para o método forem os mesmos e serializáveis.
  • Se o método depende de estados mutáveis fora dos parâmetros (ex.: self.some_state), você deve usar include_self=True ou custom key_fn.
  • TTL é usado para expiração — resultados podem ficar "stale" se parâmetros ou contexto mudarem sem mudar a chave.
  • Embora o backend SQLite seja persistente, ele não substitui um cache distribuído (ex.: Redis) em cenários multi-processo/semi-distribuídos.
  • Pickle fallback mantém compatibilidade com objetos complexos, mas use com dados confiáveis.

Benchmarks

Veja resultados reais que medem MISS vs HIT:

Backend MISS (s) HIT (s) Speedup Calls
RAW 0.4410
InMemory 0.4043 0.000043 ~9,494x 1
SQLite 0.4001 0.000763 ~524x 1

O cache reduz o tempo de execução de ~0.4 s para ~0.00004 s — um speedup superior a 9.000×.


Próximos passos

  • Suporte a funções async def (decorator awaitable)
  • Backend Redis / LMDB para cenários distribuídos
  • Métricas e integração com Prometheus

Licença

MIT License — veja o arquivo LICENSE para detalhes.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pycacheable-0.2.0.tar.gz (15.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pycacheable-0.2.0-py3-none-any.whl (12.1 kB view details)

Uploaded Python 3

File details

Details for the file pycacheable-0.2.0.tar.gz.

File metadata

  • Download URL: pycacheable-0.2.0.tar.gz
  • Upload date:
  • Size: 15.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pycacheable-0.2.0.tar.gz
Algorithm Hash digest
SHA256 cbd1191259e21c5393ec9985ab562a932ab35e40267349ac4b5312c565fb0192
MD5 cad69ba9a0a9309a0be455d599f06d96
BLAKE2b-256 6f5f906293d50af1e23b35aaf4ea718c5a1aa20673f45d764edbf6e3fc83c5c7

See more details on using hashes here.

Provenance

The following attestation bundles were made for pycacheable-0.2.0.tar.gz:

Publisher: publish.yml on leonardopinho/pycacheable

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pycacheable-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pycacheable-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 12.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pycacheable-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a71cee736e06eeb49973c699461cd8adc6eac83b840416a27735ab90c7ccf977
MD5 e64df6409c5118bfcbe920328d7812ed
BLAKE2b-256 bc451927f88691da4c615e947a7ccc9a137fcd17f1b79e68992326abacc4cf99

See more details on using hashes here.

Provenance

The following attestation bundles were made for pycacheable-0.2.0-py3-none-any.whl:

Publisher: publish.yml on leonardopinho/pycacheable

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page