""" Abstract provider interface for Velocity Comms. """ import os from abc import ABC, abstractmethod from typing import Any, Dict, List, Optional class CommsProvider(ABC): def __init__(self, base_url: str, api_key: str, instance_id: Optional[str] = None): self.base_url = base_url.rstrip("/") self.api_key = api_key self.instance_id = instance_id @abstractmethod async def send_message(self, phone: str, message: str, message_type: str = "text", **kwargs) -> Dict[str, Any]: """Send a message. Return provider response dict.""" ... @abstractmethod async def normalize_webhook(self, payload: Dict[str, Any]) -> Dict[str, Any]: """Convert provider webhook payload to Velocity canonical format.""" ... @abstractmethod async def test_connection(self) -> Dict[str, Any]: """Test provider connectivity. Return {success, message, account_info}.""" ... async def fetch_templates(self) -> List[Dict[str, Any]]: """Optional: fetch message templates.""" return [] async def get_media(self, media_id: str) -> Optional[bytes]: """Optional: download media bytes.""" return None async def send_template(self, phone: str, template_name: str, language: str, components: Optional[List] = None) -> Dict[str, Any]: """Optional: send a template message.""" raise NotImplementedError("Templates not supported by this provider.") class MockProvider(CommsProvider): """Mock provider for local development and UI previews.""" async def send_message(self, phone: str, message: str, message_type: str = "text", **kwargs) -> Dict[str, Any]: return { "success": True, "provider": "mock", "external_message_id": f"mock-{os.urandom(4).hex()}", "status": "sent", } async def normalize_webhook(self, payload: Dict[str, Any]) -> Dict[str, Any]: return payload async def test_connection(self) -> Dict[str, Any]: return { "success": True, "message": "Mock provider is always healthy.", "account_info": {"mode": "mock"}, }