API Reference¶
This page documents the public API of the interposition library.
Core Module¶
interposition
¶
Protocol-agnostic interaction interposition with lifecycle hooks.
Provides record, replay, and control capabilities.
Broker
¶
Manages interaction replay from cassettes.
Attributes:
| Name | Type | Description |
|---|---|---|
cassette |
Cassette
|
The cassette containing recorded interactions |
mode |
BrokerMode
|
The broker mode (replay, record, or auto) |
live_responder |
LiveResponder | None
|
Callable for upstream forwarding. Required when mode is record or auto; optional in replay mode. |
cassette_store |
CassetteStore | None
|
Optional store for cassette persistence |
Source code in src/interposition/services.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
__init__
¶
__init__(
cassette: Cassette,
mode: BrokerMode = "replay",
live_responder: LiveResponder | None = None,
cassette_store: CassetteStore | None = None,
) -> None
Initialize broker with a cassette.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cassette
|
Cassette
|
The cassette containing recorded interactions |
required |
mode
|
BrokerMode
|
The broker mode (replay, record, or auto) |
'replay'
|
live_responder
|
LiveResponder | None
|
Callable for upstream forwarding. Required when mode is record or auto. |
None
|
cassette_store
|
CassetteStore | None
|
Optional store for automatic cassette persistence |
None
|
Raises:
| Type | Description |
|---|---|
LiveResponderRequiredError
|
When mode is record or auto and live_responder is not configured. |
Source code in src/interposition/services.py
from_store
classmethod
¶
from_store(
cassette_store: CassetteStore,
mode: BrokerMode = "replay",
live_responder: LiveResponder | None = None,
) -> Self
Create a Broker by loading a cassette from a store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cassette_store
|
CassetteStore
|
The store to load the cassette from |
required |
mode
|
BrokerMode
|
The broker mode (replay, record, or auto) |
'replay'
|
live_responder
|
LiveResponder | None
|
Callable for upstream forwarding. Required when mode is record or auto. |
None
|
Returns:
| Type | Description |
|---|---|
Self
|
A new Broker instance with the loaded cassette. |
Raises:
| Type | Description |
|---|---|
CassetteLoadError
|
When the store fails to load the cassette (e.g., missing file, corrupted data). |
LiveResponderRequiredError
|
When mode is record or auto and live_responder is not configured. |
Source code in src/interposition/services.py
replay
¶
replay(
request: InteractionRequest,
) -> Iterator[ResponseChunk]
Replay recorded response for matching request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
InteractionRequest
|
The request to match and replay |
required |
Yields:
| Type | Description |
|---|---|
ResponseChunk
|
ResponseChunks in original recorded order |
Raises:
| Type | Description |
|---|---|
InteractionNotFoundError
|
When no matching interaction exists and mode is replay. |
Source code in src/interposition/services.py
Cassette
¶
Bases: BaseModel
In-memory collection of recorded interactions.
Attributes:
| Name | Type | Description |
|---|---|---|
interactions |
tuple[Interaction, ...]
|
Ordered sequence of interactions |
Source code in src/interposition/models.py
build_index
¶
Build fingerprint index for efficient lookup.
Source code in src/interposition/models.py
find_interaction
¶
find_interaction(
fingerprint: RequestFingerprint,
) -> Interaction | None
Find first interaction matching fingerprint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fingerprint
|
RequestFingerprint
|
Request fingerprint to search for |
required |
Returns:
| Type | Description |
|---|---|
Interaction | None
|
Matching Interaction or None if not found |
Source code in src/interposition/models.py
CassetteStore
¶
Bases: Protocol
Port for cassette persistence operations.
Implementations handle loading and saving cassettes to storage. The Broker calls save() automatically after recording new interactions.
Source code in src/interposition/services.py
Interaction
¶
Bases: BaseModel
Complete request-response pair for replay.
Attributes:
| Name | Type | Description |
|---|---|---|
request |
InteractionRequest
|
The original InteractionRequest |
fingerprint |
RequestFingerprint
|
Precomputed request fingerprint for matching |
response_chunks |
tuple[ResponseChunk, ...]
|
Ordered sequence of response chunks |
metadata |
tuple[tuple[str, str], ...]
|
Optional interaction metadata as (key, value) pairs. Examples: recording timestamp, session ID, test scenario name. Useful for debugging and tracing recorded interactions. Default is empty tuple. |
Source code in src/interposition/models.py
validate_interaction
¶
Validate interaction integrity.
Raises:
| Type | Description |
|---|---|
InteractionValidationError
|
If fingerprint doesn't match request or chunks aren't sequential |
Source code in src/interposition/models.py
InteractionRequest
¶
Bases: BaseModel
Structured representation of a protocol-agnostic request.
Attributes:
| Name | Type | Description |
|---|---|---|
protocol |
str
|
Protocol identifier (e.g., "grpc", "graphql", "mqtt") |
action |
str
|
Action/method name (e.g., "ListUsers", "query", "publish") |
target |
str
|
Target resource (e.g., "users.UserService", "topic/sensors") |
headers |
tuple[tuple[str, str], ...]
|
Request headers as immutable sequence of key-value pairs |
body |
bytes
|
Request body content as bytes |
Source code in src/interposition/models.py
fingerprint
¶
fingerprint() -> RequestFingerprint
Generate stable fingerprint for efficient matching.
Returns:
| Type | Description |
|---|---|
RequestFingerprint
|
RequestFingerprint derived from all request fields. |
JsonFileCassetteStore
¶
File-based cassette store using JSON format.
Attributes:
| Name | Type | Description |
|---|---|---|
path |
Path
|
Path to the JSON file for cassette storage. |
Source code in src/interposition/stores.py
__init__
¶
Initialize store with file path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Path to the JSON file (will be created if doesn't exist). |
required |
create_if_missing
|
bool
|
If True, load() returns an empty Cassette when the file doesn't exist instead of raising CassetteLoadError. |
False
|
Source code in src/interposition/stores.py
load
¶
load() -> Cassette
Load cassette from JSON file.
Returns:
| Type | Description |
|---|---|
Cassette
|
Cassette instance loaded from file. If create_if_missing is True |
Cassette
|
and the file doesn't exist, returns an empty Cassette. |
Raises:
| Type | Description |
|---|---|
CassetteLoadError
|
If file doesn't exist (and create_if_missing is False), file is unreadable, or JSON is invalid. |
Source code in src/interposition/stores.py
save
¶
save(cassette: Cassette) -> None
Save cassette to JSON file.
Creates parent directories if they don't exist.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cassette
|
Cassette
|
The cassette to persist. |
required |
Raises:
| Type | Description |
|---|---|
CassetteSaveError
|
If file write fails. |
Source code in src/interposition/stores.py
ResponseChunk
¶
Bases: BaseModel
Discrete piece of response data.
Attributes:
| Name | Type | Description |
|---|---|---|
data |
bytes
|
Chunk payload as bytes |
sequence |
int
|
Zero-based chunk position in response stream |
metadata |
tuple[tuple[str, str], ...]
|
Optional chunk metadata as (key, value) string pairs. Examples: timing info, encoding, content-type for this chunk. Default is empty tuple. |
Source code in src/interposition/models.py
RequestFingerprint
¶
Bases: BaseModel
Stable unique identifier for request matching.
Attributes:
| Name | Type | Description |
|---|---|---|
value |
str
|
SHA-256 hash of canonicalized request fields |
Source code in src/interposition/models.py
validate_sha256_hex
classmethod
¶
Validate that value is a valid SHA-256 hex string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
v
|
str
|
The fingerprint value to validate |
required |
Returns:
| Type | Description |
|---|---|
str
|
The validated value |
Raises:
| Type | Description |
|---|---|
ValueError
|
If value is not exactly 64 hex characters |
Source code in src/interposition/models.py
from_request
classmethod
¶
from_request(request: InteractionRequest) -> Self
Create fingerprint from InteractionRequest.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
InteractionRequest
|
The request to fingerprint |
required |
Returns:
| Type | Description |
|---|---|
Self
|
RequestFingerprint with SHA-256 hash value |
Source code in src/interposition/models.py
CassetteSaveError
¶
Bases: InterpositionError
Raised when cassette persistence fails.
Source code in src/interposition/errors.py
__init__
¶
Initialize with the path and underlying cause.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
The file path where save failed |
required |
cause
|
Exception
|
The underlying exception that caused the failure |
required |
Source code in src/interposition/errors.py
InteractionNotFoundError
¶
Bases: InterpositionError
Raised when no matching interaction is found in cassette.
Source code in src/interposition/errors.py
__init__
¶
__init__(request: InteractionRequest) -> None
Initialize with request that failed to match.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
InteractionRequest
|
The unmatched request |
required |
Source code in src/interposition/errors.py
InteractionValidationError
¶
Bases: InterpositionError, ValueError
Raised when interaction validation fails.
InterpositionError
¶
LiveResponderRequiredError
¶
Bases: InterpositionError
Raised when live_responder is required but not configured.
Source code in src/interposition/errors.py
__init__
¶
Initialize with the mode that requires live_responder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mode
|
str
|
The broker mode that requires live_responder |
required |
Source code in src/interposition/errors.py
Services¶
interposition.services.Broker
¶
Manages interaction replay from cassettes.
Attributes:
| Name | Type | Description |
|---|---|---|
cassette |
Cassette
|
The cassette containing recorded interactions |
mode |
BrokerMode
|
The broker mode (replay, record, or auto) |
live_responder |
LiveResponder | None
|
Callable for upstream forwarding. Required when mode is record or auto; optional in replay mode. |
cassette_store |
CassetteStore | None
|
Optional store for cassette persistence |
Source code in src/interposition/services.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
__init__
¶
__init__(
cassette: Cassette,
mode: BrokerMode = "replay",
live_responder: LiveResponder | None = None,
cassette_store: CassetteStore | None = None,
) -> None
Initialize broker with a cassette.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cassette
|
Cassette
|
The cassette containing recorded interactions |
required |
mode
|
BrokerMode
|
The broker mode (replay, record, or auto) |
'replay'
|
live_responder
|
LiveResponder | None
|
Callable for upstream forwarding. Required when mode is record or auto. |
None
|
cassette_store
|
CassetteStore | None
|
Optional store for automatic cassette persistence |
None
|
Raises:
| Type | Description |
|---|---|
LiveResponderRequiredError
|
When mode is record or auto and live_responder is not configured. |
Source code in src/interposition/services.py
from_store
classmethod
¶
from_store(
cassette_store: CassetteStore,
mode: BrokerMode = "replay",
live_responder: LiveResponder | None = None,
) -> Self
Create a Broker by loading a cassette from a store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cassette_store
|
CassetteStore
|
The store to load the cassette from |
required |
mode
|
BrokerMode
|
The broker mode (replay, record, or auto) |
'replay'
|
live_responder
|
LiveResponder | None
|
Callable for upstream forwarding. Required when mode is record or auto. |
None
|
Returns:
| Type | Description |
|---|---|
Self
|
A new Broker instance with the loaded cassette. |
Raises:
| Type | Description |
|---|---|
CassetteLoadError
|
When the store fails to load the cassette (e.g., missing file, corrupted data). |
LiveResponderRequiredError
|
When mode is record or auto and live_responder is not configured. |
Source code in src/interposition/services.py
replay
¶
replay(
request: InteractionRequest,
) -> Iterator[ResponseChunk]
Replay recorded response for matching request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
InteractionRequest
|
The request to match and replay |
required |
Yields:
| Type | Description |
|---|---|
ResponseChunk
|
ResponseChunks in original recorded order |
Raises:
| Type | Description |
|---|---|
InteractionNotFoundError
|
When no matching interaction exists and mode is replay. |
Source code in src/interposition/services.py
CassetteStore¶
Bases: Protocol
Port for cassette persistence operations.
Implementations handle loading and saving cassettes to storage. The Broker calls save() automatically after recording new interactions.
Source code in src/interposition/services.py
Stores¶
JsonFileCassetteStore¶
File-based cassette store using JSON format.
Attributes:
| Name | Type | Description |
|---|---|---|
path |
Path
|
Path to the JSON file for cassette storage. |
Source code in src/interposition/stores.py
__init__
¶
Initialize store with file path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Path to the JSON file (will be created if doesn't exist). |
required |
create_if_missing
|
bool
|
If True, load() returns an empty Cassette when the file doesn't exist instead of raising CassetteLoadError. |
False
|
Source code in src/interposition/stores.py
load
¶
load() -> Cassette
Load cassette from JSON file.
Returns:
| Type | Description |
|---|---|
Cassette
|
Cassette instance loaded from file. If create_if_missing is True |
Cassette
|
and the file doesn't exist, returns an empty Cassette. |
Raises:
| Type | Description |
|---|---|
CassetteLoadError
|
If file doesn't exist (and create_if_missing is False), file is unreadable, or JSON is invalid. |
Source code in src/interposition/stores.py
save
¶
save(cassette: Cassette) -> None
Save cassette to JSON file.
Creates parent directories if they don't exist.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cassette
|
Cassette
|
The cassette to persist. |
required |
Raises:
| Type | Description |
|---|---|
CassetteSaveError
|
If file write fails. |
Source code in src/interposition/stores.py
Models¶
Cassette¶
Bases: BaseModel
In-memory collection of recorded interactions.
Attributes:
| Name | Type | Description |
|---|---|---|
interactions |
tuple[Interaction, ...]
|
Ordered sequence of interactions |
Source code in src/interposition/models.py
build_index
¶
Build fingerprint index for efficient lookup.
Source code in src/interposition/models.py
find_interaction
¶
find_interaction(
fingerprint: RequestFingerprint,
) -> Interaction | None
Find first interaction matching fingerprint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fingerprint
|
RequestFingerprint
|
Request fingerprint to search for |
required |
Returns:
| Type | Description |
|---|---|
Interaction | None
|
Matching Interaction or None if not found |
Source code in src/interposition/models.py
Interaction¶
Bases: BaseModel
Complete request-response pair for replay.
Attributes:
| Name | Type | Description |
|---|---|---|
request |
InteractionRequest
|
The original InteractionRequest |
fingerprint |
RequestFingerprint
|
Precomputed request fingerprint for matching |
response_chunks |
tuple[ResponseChunk, ...]
|
Ordered sequence of response chunks |
metadata |
tuple[tuple[str, str], ...]
|
Optional interaction metadata as (key, value) pairs. Examples: recording timestamp, session ID, test scenario name. Useful for debugging and tracing recorded interactions. Default is empty tuple. |
Source code in src/interposition/models.py
validate_interaction
¶
Validate interaction integrity.
Raises:
| Type | Description |
|---|---|
InteractionValidationError
|
If fingerprint doesn't match request or chunks aren't sequential |
Source code in src/interposition/models.py
InteractionRequest¶
Bases: BaseModel
Structured representation of a protocol-agnostic request.
Attributes:
| Name | Type | Description |
|---|---|---|
protocol |
str
|
Protocol identifier (e.g., "grpc", "graphql", "mqtt") |
action |
str
|
Action/method name (e.g., "ListUsers", "query", "publish") |
target |
str
|
Target resource (e.g., "users.UserService", "topic/sensors") |
headers |
tuple[tuple[str, str], ...]
|
Request headers as immutable sequence of key-value pairs |
body |
bytes
|
Request body content as bytes |
Source code in src/interposition/models.py
fingerprint
¶
fingerprint() -> RequestFingerprint
Generate stable fingerprint for efficient matching.
Returns:
| Type | Description |
|---|---|
RequestFingerprint
|
RequestFingerprint derived from all request fields. |
ResponseChunk¶
Bases: BaseModel
Discrete piece of response data.
Attributes:
| Name | Type | Description |
|---|---|---|
data |
bytes
|
Chunk payload as bytes |
sequence |
int
|
Zero-based chunk position in response stream |
metadata |
tuple[tuple[str, str], ...]
|
Optional chunk metadata as (key, value) string pairs. Examples: timing info, encoding, content-type for this chunk. Default is empty tuple. |
Source code in src/interposition/models.py
RequestFingerprint¶
Bases: BaseModel
Stable unique identifier for request matching.
Attributes:
| Name | Type | Description |
|---|---|---|
value |
str
|
SHA-256 hash of canonicalized request fields |
Source code in src/interposition/models.py
validate_sha256_hex
classmethod
¶
Validate that value is a valid SHA-256 hex string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
v
|
str
|
The fingerprint value to validate |
required |
Returns:
| Type | Description |
|---|---|
str
|
The validated value |
Raises:
| Type | Description |
|---|---|
ValueError
|
If value is not exactly 64 hex characters |
Source code in src/interposition/models.py
from_request
classmethod
¶
from_request(request: InteractionRequest) -> Self
Create fingerprint from InteractionRequest.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
InteractionRequest
|
The request to fingerprint |
required |
Returns:
| Type | Description |
|---|---|
Self
|
RequestFingerprint with SHA-256 hash value |
Source code in src/interposition/models.py
Exceptions¶
InterpositionError¶
CassetteSaveError¶
Bases: InterpositionError
Raised when cassette persistence fails.
Source code in src/interposition/errors.py
__init__
¶
Initialize with the path and underlying cause.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
The file path where save failed |
required |
cause
|
Exception
|
The underlying exception that caused the failure |
required |
Source code in src/interposition/errors.py
InteractionNotFoundError¶
Bases: InterpositionError
Raised when no matching interaction is found in cassette.
Source code in src/interposition/errors.py
__init__
¶
__init__(request: InteractionRequest) -> None
Initialize with request that failed to match.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
InteractionRequest
|
The unmatched request |
required |
Source code in src/interposition/errors.py
InteractionValidationError¶
Bases: InterpositionError, ValueError
Raised when interaction validation fails.
LiveResponderRequiredError¶
Bases: InterpositionError
Raised when live_responder is required but not configured.
Source code in src/interposition/errors.py
__init__
¶
Initialize with the mode that requires live_responder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mode
|
str
|
The broker mode that requires live_responder |
required |