Skip to content

Commit fafac9c

Browse files
committed
sqlite persister
1 parent 2da977a commit fafac9c

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

tests/conftest.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ def filter_responses(response: dict) -> dict | None:
4949
}
5050

5151

52+
def pytest_recording_configure(config, vcr):
53+
from tests.sqlite_persister import SQLitePersister
54+
55+
vcr.register_persister(SQLitePersister)
56+
57+
5258
@pytest.fixture(scope="session", params=["llmgw"])
5359
def client_settings(request: pytest.FixtureRequest) -> UiPathBaseSettings:
5460
match request.param:

tests/sqlite_persister.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"""Custom VCR.py persister that stores all cassettes in a single SQLite database file.
2+
3+
Instead of creating one YAML file per test cassette (which can produce 1000+ files),
4+
this persister stores all cassettes as rows in a single SQLite database.
5+
"""
6+
7+
import sqlite3
8+
from pathlib import Path
9+
10+
from vcr.cassette import CassetteNotFoundError
11+
from vcr.serialize import deserialize, serialize
12+
13+
14+
class SQLitePersister:
15+
"""Stores VCR cassettes in a single SQLite database file."""
16+
17+
db_path: str = "tests/cassettes.db"
18+
19+
@classmethod
20+
def _get_connection(cls) -> sqlite3.Connection:
21+
conn = sqlite3.connect(cls.db_path)
22+
conn.execute(
23+
"""
24+
CREATE TABLE IF NOT EXISTS cassettes (
25+
cassette_path TEXT PRIMARY KEY,
26+
data TEXT NOT NULL
27+
)
28+
"""
29+
)
30+
return conn
31+
32+
@classmethod
33+
def load_cassette(cls, cassette_path: str, serializer: str) -> tuple[list, list]:
34+
# Normalize the path to use as a key
35+
key = str(Path(cassette_path))
36+
conn = cls._get_connection()
37+
try:
38+
row = conn.execute(
39+
"SELECT data FROM cassettes WHERE cassette_path = ?", (key,)
40+
).fetchone()
41+
if row is None:
42+
raise CassetteNotFoundError(f"Cassette not found: {key}")
43+
cassette_content = row[0]
44+
return deserialize(cassette_content, serializer)
45+
finally:
46+
conn.close()
47+
48+
@classmethod
49+
def save_cassette(
50+
cls, cassette_path: str, cassette_dict: dict, serializer: str
51+
) -> None:
52+
key = str(Path(cassette_path))
53+
data = serialize(cassette_dict, serializer)
54+
conn = cls._get_connection()
55+
try:
56+
conn.execute(
57+
"INSERT OR REPLACE INTO cassettes (cassette_path, data) VALUES (?, ?)",
58+
(key, data),
59+
)
60+
conn.commit()
61+
finally:
62+
conn.close()

0 commit comments

Comments
 (0)