Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AutoGen cache using Azure Cosmos DB #2327

Merged
merged 170 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
170 commits
Select commit Hold shift + click to select a range
5cf7cba
Create cosmos_db_cache.py
wmwxwa Apr 8, 2024
05bc607
Update cosmos_db_cache.py
wmwxwa Apr 9, 2024
d44123c
Update cosmos_db_cache.py
wmwxwa Apr 9, 2024
e220217
Update cosmos_db_cache.py
wmwxwa Apr 9, 2024
0abe66f
Merge branch 'main' into patch-1
wmwxwa Apr 9, 2024
99514a0
Update cosmos_db_cache.py
wmwxwa Apr 9, 2024
b014425
Merge branch 'main' into patch-1
wmwxwa Apr 10, 2024
f6174c9
Update cosmos_db_cache.py
wmwxwa Apr 11, 2024
ddd7a64
Update cosmos_db_cache.py
wmwxwa Apr 11, 2024
3f06613
Merge branch 'main' into patch-1
wmwxwa Apr 11, 2024
6ea087b
Create test_cosmos_db_cache.py
wmwxwa Apr 11, 2024
332d270
Update cosmos_db_cache.py
wmwxwa Apr 12, 2024
e3aca04
Update test_cosmos_db_cache.py
wmwxwa Apr 12, 2024
bd6ec85
Update cosmos_db_cache.py
wmwxwa Apr 12, 2024
ca2dca2
Update test_cosmos_db_cache.py
wmwxwa Apr 12, 2024
cd145d7
Update cosmos_db_cache.py
wmwxwa Apr 12, 2024
e780f08
Update test_cosmos_db_cache.py
wmwxwa Apr 12, 2024
70489f9
Update cosmos_db_cache.py
wmwxwa Apr 12, 2024
b7ba3dd
Update cosmos_db_cache.py
wmwxwa Apr 12, 2024
e35bdf8
Update test_cosmos_db_cache.py
wmwxwa Apr 12, 2024
c27fb7e
Update cosmos_db_cache.py
wmwxwa Apr 12, 2024
1658fdd
Update cosmos_db_cache.py
wmwxwa Apr 12, 2024
83ee9d7
Update cache.py
wmwxwa Apr 12, 2024
825555a
Update cache_factory.py
wmwxwa Apr 12, 2024
f38d0a8
Update cache.py
wmwxwa Apr 12, 2024
3c2d66a
Update cache_factory.py
wmwxwa Apr 12, 2024
816a672
Update test_cache.py
wmwxwa Apr 12, 2024
10e8c6e
Update test_cache.py
wmwxwa Apr 12, 2024
100a76e
Merge branch 'main' into patch-1
wmwxwa Apr 12, 2024
1de08ae
Merge branch 'main' into patch-1
wmwxwa Apr 15, 2024
f71ee81
Merge branch 'main' into patch-1
wmwxwa Apr 16, 2024
7dd7680
Update cache.py
wmwxwa Apr 16, 2024
79f53f7
Update llm-caching.md
wmwxwa Apr 16, 2024
ae09c71
Update cache.py
wmwxwa Apr 16, 2024
e7c916d
Update cache.py
wmwxwa Apr 16, 2024
06a7486
Update cache.py
wmwxwa Apr 16, 2024
bdb274e
Update cache_factory.py
wmwxwa Apr 16, 2024
64e0afb
Update cosmos_db_cache.py
wmwxwa Apr 16, 2024
88b408f
Update cache.py
wmwxwa Apr 16, 2024
04d1927
Update cosmos_db_cache.py
wmwxwa Apr 16, 2024
2dad10e
Update cosmos_db_cache.py
wmwxwa Apr 16, 2024
18c3caa
Merge branch 'main' into patch-1
wmwxwa Apr 17, 2024
a1865f0
Merge branch 'main' into patch-1
wmwxwa Apr 17, 2024
e115e6f
Update cosmos_db_cache.py
wmwxwa Apr 17, 2024
1e9e6e7
Update cosmos_db_cache.py
wmwxwa Apr 17, 2024
de57ad5
Merge branch 'main' into patch-1
wmwxwa Apr 18, 2024
5a7a2b0
Merge branch 'main' into patch-1
wmwxwa Apr 19, 2024
a2d727e
Update build.yml
wmwxwa Apr 19, 2024
32bdb61
Update build.yml
wmwxwa Apr 19, 2024
3f0779e
Update test_cosmos_db_cache.py
wmwxwa Apr 19, 2024
56a8a96
Update test_cosmos_db_cache.py
wmwxwa Apr 19, 2024
f2c914e
Update test_cosmos_db_cache.py
wmwxwa Apr 19, 2024
ea635cf
Update test_cosmos_db_cache.py
wmwxwa Apr 19, 2024
14805b0
Update test_cosmos_db_cache.py
wmwxwa Apr 19, 2024
c8b963d
Update autogen/cache/cache_factory.py
wmwxwa Apr 19, 2024
e4dd065
Update cache_factory.py
wmwxwa Apr 19, 2024
7653d06
Update cosmos_db_cache.py
wmwxwa Apr 19, 2024
f569999
Update cache.py
wmwxwa Apr 19, 2024
4c1c64b
Update cache_factory.py
wmwxwa Apr 19, 2024
a3bd190
Update cosmos_db_cache.py
wmwxwa Apr 19, 2024
7aeaa47
Update .github/workflows/build.yml
wmwxwa Apr 22, 2024
533833d
Merge branch 'main' into patch-1
wmwxwa Apr 22, 2024
0890c97
Update cache.py
wmwxwa Apr 22, 2024
a18fd0c
Update cache.py
wmwxwa Apr 22, 2024
96d7c6f
Update cache.py
wmwxwa Apr 22, 2024
045c136
Update cache_factory.py
wmwxwa Apr 22, 2024
4084506
Update cosmos_db_cache.py
wmwxwa Apr 22, 2024
0551474
Update cache.py
wmwxwa Apr 22, 2024
c5e5be9
Update cache_factory.py
wmwxwa Apr 22, 2024
ee82458
Update cosmos_db_cache.py
wmwxwa Apr 22, 2024
959e0a0
Update cache.py
wmwxwa Apr 22, 2024
e08d8cd
Update cache_factory.py
wmwxwa Apr 22, 2024
2f9b1b0
Update cache_factory.py
wmwxwa Apr 22, 2024
acbc6e3
Update cache.py
wmwxwa Apr 22, 2024
e7f6fad
Update cosmos_db_cache.py
wmwxwa Apr 22, 2024
1dac41c
Update cache.py
wmwxwa Apr 22, 2024
9316cb0
Update cache.py
wmwxwa Apr 22, 2024
fd60c6b
Update cache_factory.py
wmwxwa Apr 22, 2024
f62c75f
Update cache.py
wmwxwa Apr 22, 2024
399d76f
Update cache_factory.py
wmwxwa Apr 22, 2024
44fbcf4
Update cosmos_db_cache.py
wmwxwa Apr 22, 2024
1408af4
Update cache.py
wmwxwa Apr 22, 2024
42432f7
Update cache_factory.py
wmwxwa Apr 22, 2024
6a6e5c8
Update cosmos_db_cache.py
wmwxwa Apr 22, 2024
6395028
Update cache.py
wmwxwa Apr 22, 2024
1459e75
Update cache_factory.py
wmwxwa Apr 22, 2024
9ff1512
Update cosmos_db_cache.py
wmwxwa Apr 22, 2024
5d79166
Update test_cache.py
wmwxwa Apr 22, 2024
da24523
Update test_cache.py
wmwxwa Apr 22, 2024
1f1d9cf
Update test_cache.py
wmwxwa Apr 22, 2024
44c3a90
Update cache.py
wmwxwa Apr 22, 2024
fa79a98
Update cache.py
wmwxwa Apr 22, 2024
531d4f0
Update cache_factory.py
wmwxwa Apr 22, 2024
64293ce
Update cache.py
wmwxwa Apr 22, 2024
208b14d
Update cache_factory.py
wmwxwa Apr 22, 2024
95bfdb2
Update test_cache.py
wmwxwa Apr 22, 2024
23b3a5d
Update test_cache.py
wmwxwa Apr 22, 2024
55743f5
Update cache.py
wmwxwa Apr 22, 2024
d538847
Update cache.py
wmwxwa Apr 22, 2024
562f46e
Update test_cache.py
wmwxwa Apr 22, 2024
35d3d74
Update cache.py
wmwxwa Apr 22, 2024
f719446
Update cache.py
wmwxwa Apr 22, 2024
e2da161
Update cache_factory.py
wmwxwa Apr 22, 2024
534188f
Update cache_factory.py
wmwxwa Apr 22, 2024
934e025
Update cache_factory.py
wmwxwa Apr 22, 2024
2b4fb18
Update cache_factory.py
wmwxwa Apr 22, 2024
75d8dc7
Update cache_factory.py
wmwxwa Apr 22, 2024
087e540
Merge branch 'main' into patch-1
wmwxwa Apr 23, 2024
33c5538
Merge branch 'main' into patch-1
wmwxwa Apr 23, 2024
6a1c1e6
Update build.yml
wmwxwa Apr 23, 2024
5fddc54
Update test_cache.py
wmwxwa Apr 23, 2024
b5d5fc1
Update test_cosmos_db_cache.py
wmwxwa Apr 23, 2024
da6d4c5
Update test_cache.py
wmwxwa Apr 23, 2024
1b6201b
Merge branch 'main' into patch-1
wmwxwa Apr 23, 2024
383e738
Update cache.py
wmwxwa Apr 23, 2024
b4eea01
Update cache_factory.py
wmwxwa Apr 23, 2024
dd6b1ac
Update cosmos_db_cache.py
wmwxwa Apr 23, 2024
3439b15
Update test_cache.py
wmwxwa Apr 24, 2024
9a7aa68
Update test_cosmos_db_cache.py
wmwxwa Apr 24, 2024
0ee17d8
Update test_cache.py
wmwxwa Apr 24, 2024
228ff73
Update test_cosmos_db_cache.py
wmwxwa Apr 24, 2024
9877222
Update build.yml
wmwxwa Apr 24, 2024
6447fdb
Update build.yml
wmwxwa Apr 24, 2024
f4a0bbc
Update build.yml
wmwxwa Apr 24, 2024
8f38d77
Update build.yml
wmwxwa Apr 24, 2024
2a0654d
Merge branch 'main' into patch-1
wmwxwa Apr 24, 2024
f590ff8
Update cache_factory.py
wmwxwa Apr 24, 2024
f97dccd
Update cache.py
wmwxwa Apr 24, 2024
8d32447
Update cosmos_db_cache.py
wmwxwa Apr 24, 2024
9feb3c9
Update cache.py
wmwxwa Apr 24, 2024
657abf6
Update build.yml
wmwxwa Apr 24, 2024
28d6c6b
Update test_cache.py
wmwxwa Apr 24, 2024
84d54e5
Update test_cache.py
wmwxwa Apr 24, 2024
5c5d661
Update test_cache.py
wmwxwa Apr 24, 2024
4257682
Update test_cache.py
wmwxwa Apr 24, 2024
bf8a2e8
Update cache_factory.py
wmwxwa Apr 24, 2024
ca30023
Update cosmos_db_cache.py
wmwxwa Apr 24, 2024
f0a5d4f
Update test_cache.py
wmwxwa Apr 24, 2024
8defeec
Update test_cache.py
wmwxwa Apr 24, 2024
4e97d9a
Update test_cache.py
wmwxwa Apr 24, 2024
74224dc
Update test_cache.py
wmwxwa Apr 24, 2024
343c3a1
Update test_cosmos_db_cache.py
wmwxwa Apr 24, 2024
173c801
Update cosmos_db_cache.py
wmwxwa Apr 24, 2024
5794d2f
Update test_cosmos_db_cache.py
wmwxwa Apr 24, 2024
1a3c1ce
Update cosmos_db_cache.py
wmwxwa Apr 24, 2024
b74e949
Update cosmos_db_cache.py
wmwxwa Apr 24, 2024
0a39f49
Update test_cache.py
wmwxwa Apr 24, 2024
2123bbf
Merge branch 'main' into patch-1
wmwxwa Apr 25, 2024
f674e88
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
8bdd0da
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
df4dd70
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
8ce3f47
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
6fb4f73
Merge branch 'main' into patch-1
wmwxwa Apr 25, 2024
f2cb949
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
04dcc95
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
27b76a6
Update cosmos_db_cache.py
wmwxwa Apr 25, 2024
c6e20fa
Update test_cache.py
wmwxwa Apr 25, 2024
518d974
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
3c9cbc3
Update cache.py
wmwxwa Apr 25, 2024
00e844f
Update cache.py
wmwxwa Apr 25, 2024
a3b6794
Update cache.py
wmwxwa Apr 25, 2024
0ff53db
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
9ee1e8f
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
01cdc19
Update cache.py
wmwxwa Apr 25, 2024
50e1fdc
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
fd82eff
Merge branch 'main' into patch-1
wmwxwa Apr 25, 2024
65365e5
Update cosmos_db_cache.py
wmwxwa Apr 25, 2024
53a071b
Update cache.py
wmwxwa Apr 25, 2024
c153330
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
37ec58c
Update test_cosmos_db_cache.py
wmwxwa Apr 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion autogen/cache/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ class Cache(AbstractCache):
cache: The cache instance created based on the provided configuration.
"""

ALLOWED_CONFIG_KEYS = ["cache_seed", "redis_url", "cache_path_root"]
ALLOWED_CONFIG_KEYS = [
"cache_seed",
"redis_url",
"cache_path_root",
"connection_string",
"database_id",
"container_id",
wmwxwa marked this conversation as resolved.
Show resolved Hide resolved
]

@staticmethod
def redis(cache_seed: Union[str, int] = 42, redis_url: str = "redis://localhost:6379/0") -> "Cache":
Expand Down Expand Up @@ -56,6 +63,33 @@ def disk(cache_seed: Union[str, int] = 42, cache_path_root: str = ".cache") -> "
"""
return Cache({"cache_seed": cache_seed, "cache_path_root": cache_path_root})

@staticmethod
def cosmos_db(
connection_string: Optional[str] = None,
container_id: Optional[str] = None,
cache_seed: Union[str, int] = 42,
) -> "Cache":
"""
Create a Cosmos DB cache instance with 'autogen_cache' as database ID.

Args:
connection_string (str, optional): Connection string to the Cosmos DB account. Defaults to None.
database_id (str, optional): The database ID for the Cosmos DB account. Defaults to None.
container_id (str, optional): The container ID for the Cosmos DB account. Defaults to None.
cache_seed (Union[str, int], optional): A seed for the cache. Defaults to 42.

Returns:
Cache: A Cache instance configured for Cosmos DB.
"""
return Cache(
{
"cache_seed": cache_seed,
"connection_string": connection_string,
"database_id": "autogen_cache",
"container_id": container_id,
}
)

def __init__(self, config: Dict[str, Any]):
"""
Initialize the Cache with the given configuration.
Expand All @@ -78,6 +112,9 @@ def __init__(self, config: Dict[str, Any]):
self.config.get("cache_seed", "42"),
self.config.get("redis_url", None),
self.config.get("cache_path_root", None),
self.config.get("connection_string", None),
self.config.get("database_id", None),
self.config.get("container_id", None),
)

def __enter__(self) -> "Cache":
Expand Down
46 changes: 35 additions & 11 deletions autogen/cache/cache_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,31 @@
class CacheFactory:
@staticmethod
def cache_factory(
seed: Union[str, int], redis_url: Optional[str] = None, cache_path_root: str = ".cache"
seed: Union[str, int],
redis_url: Optional[str] = None,
cache_path_root: str = ".cache",
connection_string: Optional[str] = None,
database_id: str = "autogen_cache",
container_id: Optional[str] = None,
) -> AbstractCache:
"""
Factory function for creating cache instances.

Based on the provided redis_url, this function decides whether to create a RedisCache
or DiskCache instance. If RedisCache is available and redis_url is provided,
a RedisCache instance is created. Otherwise, a DiskCache instance is used.
This function decides whether to create a RedisCache, DiskCache, or CosmosDBCache instance
based on the provided parameters. If RedisCache is available and a redis_url is provided,
a RedisCache instance is created. If connection_string, database_id, and container_id
are provided, a CosmosDBCache is created. Otherwise, a DiskCache instance is used.

Args:
seed (Union[str, int]): A string or int used as a seed or namespace for the cache.
This could be useful for creating distinct cache instances
or for namespacing keys in the cache.
redis_url (str or None): The URL for the Redis server. If this is None
or if RedisCache is not available, a DiskCache instance is created.
redis_url (Optional[str]): The URL for the Redis server. If this is provided and Redis is available,
a RedisCache instance is created.
cache_path_root (str): The root path for the disk cache. Defaults to ".cache".
connection_string (Optional[str]): The connection string for the Cosmos DB account. Required for creating a CosmosDBCache.
database_id (Optional[str]): The database ID for the Cosmos DB account. Required for creating a CosmosDBCache.
container_id (Optional[str]): The container ID for the Cosmos DB account. Required for creating a CosmosDBCache.
wmwxwa marked this conversation as resolved.
Show resolved Hide resolved

Returns:
An instance of either RedisCache or DiskCache, depending on the availability of RedisCache
Expand All @@ -40,14 +50,28 @@ def cache_factory(
```python
disk_cache = cache_factory("myseed", None)
```

Creating a Cosmos DB cache:
```python
cosmos_cache = cache_factory("myseed", connection_string="your_connection_string", database_id="your_database_id", container_id="your_container_id")
```

"""
if redis_url is not None:
if redis_url:
try:
from .redis_cache import RedisCache

return RedisCache(seed, redis_url)
except ImportError:
logging.warning("RedisCache is not available. Creating a DiskCache instance instead.")
return DiskCache(f"./{cache_path_root}/{seed}")
else:
return DiskCache(f"./{cache_path_root}/{seed}")
logging.warning("RedisCache is not available. Fallback to DiskCache.")
wmwxwa marked this conversation as resolved.
Show resolved Hide resolved

if connection_string and database_id and container_id:
try:
from .cosmos_db_cache import CosmosDBCache

return CosmosDBCache(seed, connection_string, database_id, container_id)
except ImportError:
logging.warning("CosmosDBCache is not available. Fallback to DiskCache.")

# Default to DiskCache if neither Redis nor Cosmos DB configurations are provided
return DiskCache(f"./{cache_path_root}/{seed}")
115 changes: 115 additions & 0 deletions autogen/cache/cosmos_db_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Install Azure Cosmos DB SDK if not already
# pip install azure-cosmos

import pickle
from typing import Any, Optional, Union

from azure.cosmos import CosmosClient, PartitionKey, exceptions
from azure.cosmos.exceptions import CosmosResourceNotFoundError

from autogen.cache.abstract_cache_base import AbstractCache


class CosmosDBCache(AbstractCache):
"""
Synchronous implementation of AbstractCache using Azure Cosmos DB NoSQL API.

This class provides a concrete implementation of the AbstractCache
interface using Azure Cosmos DB for caching data, with synchronous operations.

Attributes:
seed (Union[str, int]): A seed or namespace used as a partition key.
client (CosmosClient): The Cosmos DB client used for caching.
container: The container instance used for caching.
"""

def __init__(
self, seed: Union[str, int], client: CosmosClient, container_id: str, database_id: str = "autogen_cache"
):
"""
Initialize the CosmosDBCache instance.

Args:
seed (Union[str, int]): A seed or namespace for the cache, used as a partition key.
connection_string (str): The connection string for the Cosmos DB account.
container_id (str): The container ID to be used for caching.
client (Optional[CosmosClient]): An existing CosmosClient instance to be used for caching.
"""
self.seed = seed
self.client = client
self.database = self.client.get_database_client(database_id)
self.container = self.database.get_container_client(container_id)
if not self.container.exists():
wmwxwa marked this conversation as resolved.
Show resolved Hide resolved
self.database.create_container(id=container_id, partition_key=PartitionKey(path="/partitionKey"))

@classmethod
def from_connection_string(cls, seed: Union[str, int], connection_string: str, database_id: str, container_id: str):
client = CosmosClient.from_connection_string(connection_string)
return cls(seed, client, database_id, container_id)

@classmethod
def from_existing_client(cls, seed: Union[str, int], client: CosmosClient, database_id: str, container_id: str):
return cls(seed, client, database_id, container_id)

def get(self, key: str, default: Optional[Any] = None) -> Optional[Any]:
"""
Retrieve an item from the Cosmos DB cache.

Args:
key (str): The key identifying the item in the cache.
default (optional): The default value to return if the key is not found.

Returns:
The deserialized value associated with the key if found, else the default value.
"""
try:
response = self.container.read_item(item=key, partition_key=str(self.seed))
return pickle.loads(response["data"])
except CosmosResourceNotFoundError:
return default
except Exception as e:
# Log the exception or rethrow after logging if needed
# Consider logging or handling the error appropriately here
raise e

def set(self, key: str, value: Any) -> None:
"""
Set an item in the Cosmos DB cache.

Args:
key (str): The key under which the item is to be stored.
value: The value to be stored in the cache.

Notes:
The value is serialized using pickle before being stored.
"""
serialized_value = pickle.dumps(value)
item = {"id": key, "partitionKey": str(self.seed), "data": serialized_value}
self.container.upsert_item(item)

def close(self) -> None:
"""
Close the Cosmos DB client.

Perform any necessary cleanup, such as closing network connections.
"""
# CosmosClient doesn't require explicit close in the current SDK
# If you created the client inside this class, you should close it if necessary
wmwxwa marked this conversation as resolved.
Show resolved Hide resolved
pass

async def __enter__(self):
wmwxwa marked this conversation as resolved.
Show resolved Hide resolved
"""
Context management entry.

Returns:
self: The instance itself.
"""
return self

def __exit__(self, exc_type: Optional[type], exc_value: Optional[Exception], traceback: Optional[Any]) -> None:
"""
Context management exit.

Perform cleanup actions such as closing the Cosmos DB client.
"""
self.close()
18 changes: 16 additions & 2 deletions test/cache/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,27 @@

class TestCache(unittest.TestCase):
def setUp(self):
self.config = {"cache_seed": "test_seed", "redis_url": "redis://test", "cache_path_root": ".test_cache"}
self.config = {
"cache_seed": "test_seed",
"redis_url": "redis://test",
"cache_path_root": ".test_cache",
"connection_string": None,
"database_id": None,
"container_id": None,
}

@patch("autogen.cache.cache_factory.CacheFactory.cache_factory", return_value=MagicMock())
def test_init(self, mock_cache_factory):
cache = Cache(self.config)
self.assertIsInstance(cache.cache, MagicMock)
mock_cache_factory.assert_called_with("test_seed", "redis://test", ".test_cache")
mock_cache_factory.assert_called_with(
"test_seed",
"redis://test",
".test_cache",
None, # connection_string
None, # database_id
None, # container_id
)

@patch("autogen.cache.cache_factory.CacheFactory.cache_factory", return_value=MagicMock())
def test_context_manager(self, mock_cache_factory):
Expand Down
66 changes: 66 additions & 0 deletions test/cache/test_cosmos_db_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env python3 -m pytest

import pickle
import unittest
from unittest.mock import MagicMock, patch

import pytest

try:
from autogen.cache.cosmos_db_cache import CosmosDBCache

skip_cosmos_tests = False
except ImportError:
skip_cosmos_tests = True


class TestCosmosDBCache(unittest.TestCase):
wmwxwa marked this conversation as resolved.
Show resolved Hide resolved
def setUp(self):
self.seed = "test_seed"
self.client = MagicMock()
self.database_id = "test_database"
self.container_id = "test_container"

@pytest.mark.skipif(skip_cosmos_tests, reason="Cosmos DB SDK not installed")
@patch("autogen.cache.cosmos_db_cache.CosmosClient.from_connection_string", return_value=MagicMock())
def test_init(self, mock_cosmos_from_connection_string):
cache = CosmosDBCache(self.seed, self.client, self.database_id, self.container_id)
self.assertEqual(cache.seed, self.seed)
self.assertEqual(cache.client, self.client)

@pytest.mark.skipif(skip_cosmos_tests, reason="Cosmos DB SDK not installed")
def test_get(self):
key = "key"
value = "value"
serialized_value = pickle.dumps(value)
self.client.get_database_client().get_container_client().read_item.return_value = {"data": serialized_value}
cache = CosmosDBCache(self.seed, self.client, self.database_id, self.container_id)

self.assertEqual(cache.get(key), value)
self.client.get_database_client().get_container_client().read_item.assert_called_with(
item=key, partition_key=str(self.seed)
)

self.client.get_database_client().get_container_client().read_item.side_effect = Exception("not found")
self.assertIsNone(cache.get(key))

@pytest.mark.skipif(skip_cosmos_tests, reason="Cosmos DB SDK not installed")
def test_set(self):
key = "key"
value = "value"
serialized_value = pickle.dumps(value)
cache = CosmosDBCache(self.seed, self.client, self.database_id, self.container_id)
cache.set(key, value)
self.client.get_database_client().get_container_client().upsert_item.assert_called_with(
{"id": key, "partitionKey": str(self.seed), "data": serialized_value}
)

@pytest.mark.skipif(skip_cosmos_tests, reason="Cosmos DB SDK not installed")
def test_context_manager(self):
with CosmosDBCache(self.seed, self.client, self.database_id, self.container_id) as cache:
self.assertIsInstance(cache, CosmosDBCache)
# Note: Testing of close method if needed when CosmosClient requires explicit closing logic


if __name__ == "__main__":
unittest.main()
8 changes: 6 additions & 2 deletions website/docs/topics/llm-caching.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
AutoGen supports caching API requests so that they can be reused when the same request is issued. This is useful when repeating or continuing experiments for reproducibility and cost saving.

Since version [`0.2.8`](https://github.com/microsoft/autogen/releases/tag/v0.2.8), a configurable context manager allows you to easily
configure LLM cache, using either [`DiskCache`](/docs/reference/cache/disk_cache#diskcache) or [`RedisCache`](/docs/reference/cache/redis_cache#rediscache). All agents inside the
context manager will use the same cache.
configure LLM cache, using either [`DiskCache`](/docs/reference/cache/disk_cache#diskcache), [`RedisCache`](/docs/reference/cache/redis_cache#rediscache), or Cosmos DB Cache. All agents inside the context manager will use the same cache.

```python
from autogen import Cache
Expand All @@ -16,6 +15,11 @@ with Cache.redis(redis_url="redis://localhost:6379/0") as cache:
# Use DiskCache as cache
with Cache.disk() as cache:
user.initiate_chat(assistant, message=coding_task, cache=cache)

# Use Azure Cosmos DB as cache
with Cache.cosmos_db(connection_string="your_connection_string", database_id="your_database_id", container_id="your_container_id") as cache:
user.initiate_chat(assistant, message=coding_task, cache=cache)

```

The cache can also be passed directly to the model client's create call.
Expand Down
Loading