"""Client factories for various services.""" from typing import Any import hvac import redis.asyncio as redis from minio import Minio from neo4j import GraphDatabase from qdrant_client import QdrantClient from .settings import BaseAppSettings class VaultClientFactory: # pylint: disable=too-few-public-methods """Factory for creating Vault clients""" @staticmethod def create_client(settings: BaseAppSettings) -> hvac.Client: """Create authenticated Vault client""" client = hvac.Client(url=settings.vault_addr) if settings.vault_token: # Development mode with token client.token = settings.vault_token elif settings.vault_role_id and settings.vault_secret_id: # Production mode with AppRole try: auth_response = client.auth.approle.login( role_id=settings.vault_role_id, secret_id=settings.vault_secret_id ) client.token = auth_response["auth"]["client_token"] except Exception as e: raise ValueError("Failed to authenticate with Vault") from e else: raise ValueError( "Either vault_token or vault_role_id/vault_secret_id must be provided" ) if not client.is_authenticated(): raise ValueError("Failed to authenticate with Vault") return client class MinIOClientFactory: # pylint: disable=too-few-public-methods """Factory for creating MinIO clients""" @staticmethod def create_client(settings: BaseAppSettings) -> Minio: """Create MinIO client""" return Minio( endpoint=settings.minio_endpoint, access_key=settings.minio_access_key, secret_key=settings.minio_secret_key, secure=settings.minio_secure, ) class QdrantClientFactory: # pylint: disable=too-few-public-methods """Factory for creating Qdrant clients""" @staticmethod def create_client(settings: BaseAppSettings) -> QdrantClient: """Create Qdrant client""" return QdrantClient(url=settings.qdrant_url, api_key=settings.qdrant_api_key) class Neo4jDriverFactory: # pylint: disable=too-few-public-methods """Factory for creating Neo4j drivers""" @staticmethod def create_driver(settings: BaseAppSettings) -> Any: """Create Neo4j driver""" return GraphDatabase.driver( settings.neo4j_uri, auth=(settings.neo4j_user, settings.neo4j_password) ) class RedisClientFactory: # pylint: disable=too-few-public-methods """Factory for creating Redis clients""" @staticmethod async def create_client(settings: BaseAppSettings) -> "redis.Redis[str]": """Create Redis client""" return redis.from_url( settings.redis_url, encoding="utf-8", decode_responses=True )