Skip to main content

Spakky Cache

Spakky Framework를 위한 백엔드 중립 애플리케이션 데이터 캐시 계약과 AOP 어노테이션입니다. 서비스 메서드의 @cacheable/@cache_evict 선언을 등록된 cache backend Pod와 연결합니다.

설치

pip install spakky-cache

주요 기능

  • 타입화된 캐시 결과: CacheHit[T]와 CacheMiss는 백엔드별 예외 없이 hit/miss 결과를 표현합니다.
  • 동기/비동기 계약: ICache[T]는 get, set, delete, clear와 비동기 대응 메서드를 정의합니다.
  • TTL 의미론: 양수 TTL 값은 항목을 결정적으로 만료시키며, 없는 항목과 만료된 항목은 miss입니다.
  • AOP 메서드 캐싱: @cacheable()과 @cache_evict()은 수동 배선 없이 cache hit/miss와 evict 동작을 적용합니다.
  • 운영 backend 분리: Core package는 저장소 backend를 등록하지 않으며, spakky-redis 같은 backend plugin이 ICache[T] 구현체를 제공합니다.
  • 애플리케이션 데이터 범위: 이 패키지는 ApplicationContext 내부 캐시를 노출하거나 변경하지 않습니다.

빠른 시작

from datetime import timedelta

from spakky.cache import cache_evict, cacheable
from spakky.core.application.application import SpakkyApplication
from spakky.core.application.application_context import ApplicationContext
from spakky.core.application.plugin import Plugin
from spakky.core.stereotype.usecase import UseCase


@UseCase()
class ProfileService:
    def __init__(self) -> None:
        self.calls = 0

    @cacheable(key="profile:{0}", ttl=timedelta(minutes=5))
    def load_profile(self, user_id: str) -> str:
        self.calls += 1
        return f"profile:{user_id}"

    @cache_evict(key="profile:{0}")
    def refresh_profile(self, user_id: str) -> None:
        ...


app = (
    SpakkyApplication(ApplicationContext())
    .load_plugins(
        include={
            Plugin(name="spakky-cache"),
            Plugin(name="spakky-redis"),
        }
    )
    .add(ProfileService)
    .start()
)

profiles = app.container.get(type_=ProfileService)
profiles.load_profile("42")

어노테이션 사용

spakky-cache 플러그인을 로드한 뒤 서비스 메서드에 어노테이션을 붙입니다. 이 플러그인은 CacheAspect, AsyncCacheAspect를 등록하며, 실제 저장소 backend는 spakky-redis 같은 plugin이 ICache Pod로 제공합니다.

from datetime import timedelta

from spakky.cache import cache_evict, cacheable
from spakky.core.stereotype.usecase import UseCase


@UseCase()
class ProfileService:
    def __init__(self) -> None:
        self.calls = 0

    @cacheable(key="profile:{0}", ttl=timedelta(minutes=5))
    def load_profile(self, user_id: str) -> str:
        self.calls += 1
        return f"profile:{user_id}"

    @cache_evict(key="profile:{0}")
    def refresh_profile(self, user_id: str) -> None:
        ...

기본 키는 메서드 모듈, 정규화된 이름, 위치 인자, 정렬된 키워드 인자에서 파생됩니다. 명시적 key 값은 메서드 호출 인자에 대해 평가되는 Python format 문자열입니다. 키 포맷이 유효하지 않으면 CacheKeyGenerationError가 발생합니다. 백엔드 실패는 삼키지 않고 캐시 에러로 전파합니다.

@cache_evict()은 어노테이션이 붙은 메서드가 성공한 뒤에만 일치하는 항목을 삭제합니다. 실패한 메서드 호출은 기존 항목을 건드리지 않으므로, refresh 실패가 마지막으로 알려진 캐시 값을 지우지 않습니다.

비동기 사용

from spakky.cache import cacheable
from spakky.core.stereotype.usecase import UseCase


@UseCase()
class AnswerService:
    @cacheable(key="answer:{0}")
    async def load_answer(self, question_id: str) -> int:
        return 42

TTL 규칙

ttl=None은 명시적 삭제 또는 전체 삭제 전까지 항목을 저장합니다. 양수 float, int, datetime.timedelta 값은 해당 시간이 지난 뒤 항목을 만료시킵니다. 0 이하 TTL 값은 InvalidCacheTTLError를 발생시킵니다.

캐시 evict 어노테이션은 어노테이션이 붙은 메서드가 성공한 뒤에만 일치하는 항목 하나를 제거합니다.

범위

spakky-cache는 애플리케이션 데이터 캐시 추상화입니다. ApplicationContext 내부의 타입 캐시, 싱글톤 캐시, 컨텍스트 캐시와는 별개입니다. Tag 기반 무효화, stampede 보호, write-through/write-behind, metrics는 core capability contract로 정의되며, spakky-redis가 Redis backend 구현을 제공합니다.

개발 검증

패키지 단위 검증은 해당 패키지 디렉토리에서 실행합니다.

uv run ruff format .
uv run ruff check .
uv run pyrefly check
uv run pytest

pytest는 각 패키지 pyproject.toml의 coverage 설정을 사용합니다.

라이선스

MIT License

Metadata

Release files for spakky-cache 8.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spakky-cache 8.1.0
File Size Uploaded
spakky_cache-8.1.0.tar.gz 6.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for spakky-cache 8.1.0
File Interpreter ABI Platform
spakky_cache-8.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 16.5 kB

Release files / spakky_cache-8.1.0.tar.gz

Download URL spakky_cache-8.1.0.tar.gz
Size 6.8 kB
Tags Source
SHA-256 checksum
How to use checksums
3c209fb0ce5de437e624dcced730263076881bcab38670ee344c7748c406252c
BLAKE2b-256 checksum
How to use checksums
9c2f17d3092c59eafde820a1050f8b95a84710d54553610883c7b84ebbd34c2b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release files / spakky_cache-8.1.0-py3-none-any.whl

Download URL spakky_cache-8.1.0-py3-none-any.whl
Size 9.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
75d7945187d1f2648f73c021cc5d57ddb77d15a7d307cc1d0d076159f71d17e2
BLAKE2b-256 checksum
How to use checksums
736a379b93fa1099c7de6df3677c8826c8bc95ce29e4bd1d0b12a7f8c2c816dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

8.1.0 This release

2 release files

8.0.0

2 release files

7.2.0

2 release files

7.1.1

2 release files

7.1.0

2 release files

7.0.0

2 release files

6.13.0

2 release files

6.12.0

2 release files

6.11.0

2 release files

6.10.1

2 release files

6.10.0

2 release files

6.9.1

2 release files

6.9.0

2 release files

6.8.0

2 release files

6.7.0

2 release files

6.6.1

2 release files

6.6.0

2 release files

6.5.0

2 release files

6.4.0

2 release files

6.3.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page