mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Add Azure Managed Redis Support with Credential Provider (#2887)
* azure redis support * small fixes * azure managed redis sample * fixes
This commit is contained in:
committed by
GitHub
Unverified
parent
ff9343d7cc
commit
37b4cfd024
@@ -9,6 +9,7 @@ from uuid import uuid4
|
||||
import redis.asyncio as redis
|
||||
from agent_framework import ChatMessage
|
||||
from agent_framework._serialization import SerializationMixin
|
||||
from redis.credentials import CredentialProvider
|
||||
|
||||
|
||||
class RedisStoreState(SerializationMixin):
|
||||
@@ -55,6 +56,11 @@ class RedisChatMessageStore:
|
||||
def __init__(
|
||||
self,
|
||||
redis_url: str | None = None,
|
||||
credential_provider: CredentialProvider | None = None,
|
||||
host: str | None = None,
|
||||
port: int = 6380,
|
||||
ssl: bool = True,
|
||||
username: str | None = None,
|
||||
thread_id: str | None = None,
|
||||
key_prefix: str = "chat_messages",
|
||||
max_messages: int | None = None,
|
||||
@@ -63,12 +69,19 @@ class RedisChatMessageStore:
|
||||
"""Initialize the Redis chat message store.
|
||||
|
||||
Creates a Redis-backed chat message store for a specific conversation thread.
|
||||
The store will automatically create a Redis connection and manage message
|
||||
persistence using Redis List operations.
|
||||
Supports both traditional URL-based authentication and Azure Managed Redis
|
||||
with credential provider.
|
||||
|
||||
Args:
|
||||
redis_url: Redis connection URL (e.g., "redis://localhost:6379").
|
||||
Required for establishing Redis connection.
|
||||
Used for traditional authentication. Mutually exclusive with credential_provider.
|
||||
credential_provider: Redis credential provider (redis.credentials.CredentialProvider) for
|
||||
Azure AD authentication. Requires host parameter. Mutually exclusive with redis_url.
|
||||
host: Redis host name (e.g., "myredis.redis.cache.windows.net").
|
||||
Required when using credential_provider.
|
||||
port: Redis port number. Defaults to 6380 (Azure Redis SSL port).
|
||||
ssl: Enable SSL/TLS connection. Defaults to True.
|
||||
username: Redis username. Defaults to None.
|
||||
thread_id: Unique identifier for this conversation thread.
|
||||
If not provided, a UUID will be auto-generated.
|
||||
This becomes part of the Redis key: {key_prefix}:{thread_id}
|
||||
@@ -82,23 +95,58 @@ class RedisChatMessageStore:
|
||||
Useful for resuming conversations or seeding with context.
|
||||
|
||||
Raises:
|
||||
ValueError: If redis_url is None (Redis connection is required).
|
||||
redis.ConnectionError: If unable to connect to Redis server.
|
||||
ValueError: If neither redis_url nor credential_provider is provided.
|
||||
ValueError: If both redis_url and credential_provider are provided.
|
||||
ValueError: If credential_provider is used without host parameter.
|
||||
|
||||
Examples:
|
||||
Traditional connection:
|
||||
store = RedisChatMessageStore(
|
||||
redis_url="redis://localhost:6379",
|
||||
thread_id="conversation_123"
|
||||
)
|
||||
|
||||
Azure Managed Redis with credential provider:
|
||||
from redis.credentials import CredentialProvider
|
||||
from azure.identity.aio import DefaultAzureCredential
|
||||
|
||||
store = RedisChatMessageStore(
|
||||
credential_provider=CredentialProvider(DefaultAzureCredential()),
|
||||
host="myredis.redis.cache.windows.net",
|
||||
thread_id="conversation_123"
|
||||
)
|
||||
"""
|
||||
# Validate required parameters
|
||||
if redis_url is None:
|
||||
raise ValueError("redis_url is required for Redis connection")
|
||||
# Validate connection parameters
|
||||
if redis_url is None and credential_provider is None:
|
||||
raise ValueError("Either redis_url or credential_provider must be provided")
|
||||
|
||||
if redis_url is not None and credential_provider is not None:
|
||||
raise ValueError("redis_url and credential_provider are mutually exclusive")
|
||||
|
||||
if credential_provider is not None and host is None:
|
||||
raise ValueError("host is required when using credential_provider")
|
||||
|
||||
# Store configuration
|
||||
self.redis_url = redis_url
|
||||
self.thread_id = thread_id or f"thread_{uuid4()}"
|
||||
self.key_prefix = key_prefix
|
||||
self.max_messages = max_messages
|
||||
|
||||
# Initialize Redis client with connection pooling and async support
|
||||
self._redis_client = redis.from_url(redis_url, decode_responses=True) # type: ignore[no-untyped-call]
|
||||
# Initialize Redis client based on authentication method
|
||||
if credential_provider is not None and host is not None:
|
||||
# Azure AD authentication with credential provider
|
||||
self.redis_url = None # Not using URL-based auth
|
||||
self._redis_client = redis.Redis(
|
||||
host=host,
|
||||
port=port,
|
||||
ssl=ssl,
|
||||
username=username,
|
||||
credential_provider=credential_provider,
|
||||
decode_responses=True,
|
||||
)
|
||||
else:
|
||||
# Traditional URL-based authentication
|
||||
self.redis_url = redis_url
|
||||
self._redis_client = redis.from_url(redis_url, decode_responses=True) # type: ignore[no-untyped-call]
|
||||
|
||||
# Handle initial messages (will be moved to Redis on first access)
|
||||
self._initial_messages = list(messages) if messages else []
|
||||
|
||||
Reference in New Issue
Block a user