add option to compress cassettes

This commit is contained in:
Chester Curme 2025-05-29 10:04:02 -04:00
parent f7efd89e70
commit 86879be2fe
15 changed files with 170 additions and 6565 deletions

View File

@ -0,0 +1 @@
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

View File

@ -1,5 +1,7 @@
import pytest
from langchain_tests.conftest import YamlGzipSerializer
from langchain_tests.conftest import _base_vcr_config as _base_vcr_config
from vcr import VCR # type: ignore[import-untyped]
def remove_response_headers(response: dict) -> dict:
@ -14,5 +16,15 @@ def vcr_config(_base_vcr_config: dict) -> dict: # noqa: F811
"""
config = _base_vcr_config.copy()
config["before_record_response"] = remove_response_headers
config["serializer"] = "yaml.gz"
config["path_transformer"] = VCR.ensure_suffix(".yaml.gz")
return config
@pytest.fixture
def vcr(vcr_config: dict) -> VCR:
"""Override the default vcr fixture to include custom serializers"""
my_vcr = VCR(**vcr_config)
my_vcr.register_serializer("yaml.gz", YamlGzipSerializer)
return my_vcr

View File

@ -1,141 +0,0 @@
interactions:
- request:
body: '{"max_tokens":1024,"messages":[{"role":"user","content":"Write a story
about a cat."}],"model":"claude-3-5-sonnet-latest","stream":true}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
anthropic-version:
- '2023-06-01'
connection:
- keep-alive
content-length:
- '136'
content-type:
- application/json
host:
- api.anthropic.com
user-agent:
- Anthropic/Python 0.51.0
x-api-key:
- PLACEHOLDER
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 0.51.0
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.11
x-stainless-timeout:
- NOT_GIVEN
method: POST
uri: https://api.anthropic.com/v1/messages
response:
body:
string: "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_01Y9uFRYeCcfJPDAZ6Gpo7nF\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet-latest\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":14,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":1}}
\ }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}\n\nevent:
ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Here\"}}\n\nevent:
content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"'s
a story about a cat:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"\\n\\nThe
Curious Adventure of Whiskers\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"\\n\\nWhiskers
was a sle\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"ek
gray tabby cat who\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
lived in a cozy\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
house at the end of\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
Maple Street. Every morning, she\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
would perch on her favorite windowsill,\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
watching the birds flutter about in the garden an\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d
dreaming of adventure.\\n\\nOne particularly\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
sunny morning, Whiskers notice\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d
that the kitchen window had been left slightly\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
open. Her green eyes sparkled with m\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"ischief
as she squeezed through the gap\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
and stepped into the outside world for\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
the first time in her life.\\n\\nThe\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
grass felt cool beneath her paws\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
as she crept through the garden, duc\"}}\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"king
under flowering bushes and staying\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
close to the fence. Everything\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
seemed so much bigger and more exciting than\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
it had looked from her windowsill.\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"\\n\\nAs
she explored, Whiskers encountere\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d
a friendly butterfly that danced just\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
out of reach, leading her deeper\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
into the neighborhood. She chased it aroun\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d
corners and through yards until she suddenly realize\"} }\n\nevent:
content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d
she didn't recognize her surroundings anymore\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\".\\n\\nJust
as panic began to set in,\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
Whiskers caught a familiar scent \u2013\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
the smell of her favorite t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"una
treats! She followed her nose an\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d
found her worried owner walking through\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
the streets, shaking a treat container an\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d
calling her name.\\n\\nReliev\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"ed,
Whiskers ran\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
to her owner, who scooped her up\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
with joy. As they walked home\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
together, Whiskers decide\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d
that while adventures were exciting, nothing\"} }\n\nevent:
content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
beat the comfort of her window\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"sill
and the love of her family.\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"\\n\\nFrom
that day on, Whiskers was\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
content to watch the world from her window\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\",
knowing she had experienced her\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
very own adventure \u2013 even\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
if just for one day.\\n\\nThe\"} }\n\nevent: content_block_delta\ndata:
{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"
End\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0
\ }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"output_tokens\":367}
\ }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n"
headers: {}
status:
code: 200
message: OK
version: 1

View File

@ -0,0 +1 @@
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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,7 @@
import pytest
from langchain_tests.conftest import YamlGzipSerializer
from langchain_tests.conftest import _base_vcr_config as _base_vcr_config
from vcr import VCR # type: ignore[import-untyped]
_EXTRA_HEADERS = [
("openai-organization", "PLACEHOLDER"),
@ -21,5 +23,15 @@ def vcr_config(_base_vcr_config: dict) -> dict: # noqa: F811
config = _base_vcr_config.copy()
config.setdefault("filter_headers", []).extend(_EXTRA_HEADERS)
config["before_record_response"] = remove_response_headers
config["serializer"] = "yaml.gz"
config["path_transformer"] = VCR.ensure_suffix(".yaml.gz")
return config
@pytest.fixture
def vcr(vcr_config: dict) -> VCR:
"""Override the default vcr fixture to include custom serializers"""
my_vcr = VCR(**vcr_config)
my_vcr.register_serializer("yaml.gz", YamlGzipSerializer)
return my_vcr

View File

@ -1,4 +1,24 @@
import base64
import gzip
import pytest
from vcr import VCR # type: ignore[import-untyped]
from vcr.serializers import yamlserializer # type: ignore[import-untyped]
class YamlGzipSerializer:
@staticmethod
def serialize(cassette_dict: dict) -> str:
raw = yamlserializer.serialize(cassette_dict).encode("utf-8")
compressed = gzip.compress(raw)
return base64.b64encode(compressed).decode("ascii")
@staticmethod
def deserialize(data: str) -> dict:
compressed = base64.b64decode(data.encode("ascii"))
text = gzip.decompress(compressed).decode("utf-8")
return yamlserializer.deserialize(text)
_BASE_FILTER_HEADERS = [
("authorization", "PLACEHOLDER"),
@ -18,6 +38,8 @@ def _base_vcr_config() -> dict:
"filter_headers": _BASE_FILTER_HEADERS.copy(),
"match_on": ["method", "scheme", "host", "port", "path", "query"],
"decode_compressed_response": True,
"cassette_library_dir": "tests/cassettes",
"path_transformer": VCR.ensure_suffix(".yaml"),
}

View File

@ -581,6 +581,65 @@ class ChatModelIntegrationTests(ChatModelTests):
return config
.. dropdown:: Compressing cassettes
``langchain-tests`` includes a custom VCR serializer that compresses
cassettes using gzip. To use it, register the ``"yaml.gz"`` serializer
to your VCR fixture and enable this serializer in the config. See
example below:
.. code-block:: python
:caption: tests/conftest.py
import pytest
from langchain_tests.conftest import YamlGzipSerializer
from langchain_tests.conftest import _base_vcr_config as _base_vcr_config
from vcr import VCR
_EXTRA_HEADERS = [
# Specify additional headers to redact
("user-agent", "PLACEHOLDER"),
]
def remove_response_headers(response: dict) -> dict:
# If desired, remove or modify headers in the response.
response["headers"] = {}
return response
@pytest.fixture(scope="session")
def vcr_config(_base_vcr_config: dict) -> dict: # noqa: F811
\"\"\"Extend the default configuration from langchain_tests.\"\"\"
config = _base_vcr_config.copy()
config.setdefault("filter_headers", []).extend(_EXTRA_HEADERS)
config["before_record_response"] = remove_response_headers
# New: enable serializer and set file extension
config["serializer"] = "yaml.gz"
config["path_transformer"] = VCR.ensure_suffix(".yaml.gz")
return config
@pytest.fixture
def vcr(vcr_config: dict) -> VCR:
\"\"\"Override the default vcr fixture to include custom serializers\"\"\"
my_vcr = VCR(**vcr_config)
my_vcr.register_serializer("yaml.gz", YamlGzipSerializer)
return my_vcr
You can inspect the contents of the compressed cassettes (e.g., to
ensure no sensitive information is recorded) using the serializer:
.. code-block:: python
from langchain_tests.conftest import YamlGzipSerializer
with open("/path/to/tests/cassettes/TestClass_test.yaml.gz", "r") as f:
data = f.read()
YamlGzipSerializer.deserialize(data)
3. Run tests to generate VCR cassettes.
Example:
@ -2798,7 +2857,7 @@ class ChatModelIntegrationTests(ChatModelTests):
pytest.skip("VCR not set up.")
def _run() -> None:
cassette_name = f"{self.__class__.__name__}_test_stream_time.yaml"
cassette_name = f"{self.__class__.__name__}_test_stream_time"
with vcr.use_cassette(cassette_name, record_mode="once"):
for _ in model.stream("Write a story about a cat."):
pass

View File

@ -682,6 +682,65 @@ class ChatModelUnitTests(ChatModelTests):
return config
.. dropdown:: Compressing cassettes
``langchain-tests`` includes a custom VCR serializer that compresses
cassettes using gzip. To use it, register the ``"yaml.gz"`` serializer
to your VCR fixture and enable this serializer in the config. See
example below:
.. code-block:: python
:caption: tests/conftest.py
import pytest
from langchain_tests.conftest import YamlGzipSerializer
from langchain_tests.conftest import _base_vcr_config as _base_vcr_config
from vcr import VCR
_EXTRA_HEADERS = [
# Specify additional headers to redact
("user-agent", "PLACEHOLDER"),
]
def remove_response_headers(response: dict) -> dict:
# If desired, remove or modify headers in the response.
response["headers"] = {}
return response
@pytest.fixture(scope="session")
def vcr_config(_base_vcr_config: dict) -> dict: # noqa: F811
\"\"\"Extend the default configuration from langchain_tests.\"\"\"
config = _base_vcr_config.copy()
config.setdefault("filter_headers", []).extend(_EXTRA_HEADERS)
config["before_record_response"] = remove_response_headers
# New: enable serializer and set file extension
config["serializer"] = "yaml.gz"
config["path_transformer"] = VCR.ensure_suffix(".yaml.gz")
return config
@pytest.fixture
def vcr(vcr_config: dict) -> VCR:
\"\"\"Override the default vcr fixture to include custom serializers\"\"\"
my_vcr = VCR(**vcr_config)
my_vcr.register_serializer("yaml.gz", YamlGzipSerializer)
return my_vcr
You can inspect the contents of the compressed cassettes (e.g., to
ensure no sensitive information is recorded) using the serializer:
.. code-block:: python
from langchain_tests.conftest import YamlGzipSerializer
with open("/path/to/tests/cassettes/TestClass_test.yaml.gz", "r") as f:
data = f.read()
YamlGzipSerializer.deserialize(data)
3. Run tests to generate VCR cassettes.
Example: