Coverage for src/invariant/store/base.py: 86.36%

1"""Base class for ArtifactStore implementations."""

2

3 from abc import ABC, abstractmethod

4 from dataclasses import dataclass

5 from typing import Any

6

7

8@dataclass

9 class CacheStats:

10 """Cache statistics tracking hits, misses, and puts."""

11

12 hits: int = 0 # exists() returned True

13 misses: int = 0 # exists() returned False

14 puts: int = 0 # put() was called

15

16

17 class ArtifactStore(ABC):

18 """Abstract base class for artifact storage.

19

20 Provides the interface for storing and retrieving immutable artifacts

21 by operation name and digest (SHA-256 hash). The composite key ensures

22 that different operations with the same input manifest cache separately.

23 """

24

25 def __init__(self) -> None:

26 """Initialize the store with cache statistics."""

27 self.stats = CacheStats()

28

29 def reset_stats(self) -> None:

30 """Reset cache statistics to zero."""

31 self.stats = CacheStats()

32

33 @abstractmethod

34 def exists(self, op_name: str, digest: str) -> bool:

35 """Check if an artifact exists for the given operation and digest.

36

37 Args:

38 op_name: The name of the operation that produced the artifact.

39 digest: The SHA-256 hash (64 character hex string) of the manifest.

40

41 Returns:

42 True if artifact exists, False otherwise.

43 """

44 ...

45

46 @abstractmethod

47 def get(self, op_name: str, digest: str) -> Any:

48 """Retrieve an artifact by operation name and digest.

49

50 Args:

51 op_name: The name of the operation that produced the artifact.

52 digest: The SHA-256 hash (64 character hex string) of the manifest.

53

54 Returns:

55 The deserialized artifact (native type or ICacheable domain type).

56

57 Raises:

58 KeyError: If artifact does not exist.

59 """

60 ...

61

62 @abstractmethod

63 def put(self, op_name: str, digest: str, artifact: Any) -> None:

64 """Store an artifact with the given operation name and digest.

65

66 Args:

67 op_name: The name of the operation that produced the artifact.

68 digest: The SHA-256 hash (64 character hex string) of the manifest.

69 artifact: The artifact to store (must be cacheable).

70 """

71 ...