Source code for aidputils.agents.tools.http.response_registry

"""
Response parser and optimizer registries.

Provides dynamic selection of parsers and optimizers based on content-type and response type.
"""

import logging
import re
from typing import Dict, Optional, Type

from aidputils.agents.tools.http.parsers.base_parser import ResponseParser
from aidputils.agents.tools.http.optimizers.base_optimizer import ResponseOptimizer

# Import concrete implementations
from aidputils.agents.tools.http.parsers.json_parser import JsonResponseParser
from aidputils.agents.tools.http.parsers.html_parser import HtmlResponseParser
from aidputils.agents.tools.http.parsers.text_parser import TextResponseParser

from aidputils.agents.tools.http.optimizers.json_optimizer import JsonResponseOptimizer
from aidputils.agents.tools.http.optimizers.html_optimizer import HtmlResponseOptimizer
from aidputils.agents.tools.http.optimizers.text_optimizer import TextResponseOptimizer

logger = logging.getLogger(__name__)


[docs] class ResponseParserRegistry: """Registry for dynamically selecting parsers based on content-type.""" _parsers: Dict[str, Type[ResponseParser]] = {} _fallback_parser: Optional[Type[ResponseParser]] = None
[docs] @classmethod def register(cls, parser_class: Type[ResponseParser]) -> Type[ResponseParser]: """ Decorator to register a parser. Args: parser_class: Parser class to register Returns: The same parser class (for use as decorator) """ content_types = parser_class.content_types() for content_type in content_types: # Use */* as fallback marker if content_type == '*/*': cls._fallback_parser = parser_class else: cls._parsers[content_type.lower()] = parser_class return parser_class
[docs] @classmethod def get_parser(cls, content_type: str) -> ResponseParser: """ Get parser for content-type, with fallback to text parser. Args: content_type: Content-Type header value Returns: Parser instance """ # Normalize content-type (remove charset, parameters) normalized = cls._normalize_content_type(content_type) # Try exact match if normalized in cls._parsers: return cls._parsers[normalized]() # Try wildcard match (e.g., text/* matches text/html) for registered_type, parser_class in cls._parsers.items(): if cls._matches_wildcard(normalized, registered_type): return parser_class() # Use fallback parser if cls._fallback_parser: return cls._fallback_parser() # Default to text parser if no fallback registered return TextResponseParser()
@classmethod def _normalize_content_type(cls, content_type: str) -> str: """Normalize content-type by removing charset and parameters.""" if not content_type: return '' # Split on ; and take first part parts = content_type.split(';') return parts[0].strip().lower() @classmethod def _matches_wildcard(cls, content_type: str, pattern: str) -> bool: """Check if content-type matches a wildcard pattern.""" if '*' not in pattern: return False # Convert glob-style pattern to regex regex_pattern = pattern.replace('*', '.*') return bool(re.match(f'^{regex_pattern}$', content_type))
[docs] class ResponseOptimizerRegistry: """Registry for dynamically selecting optimizers based on response type.""" _optimizers: Dict[str, Type[ResponseOptimizer]] = {}
[docs] @classmethod def register(cls, optimizer_class: Type[ResponseOptimizer]) -> Type[ResponseOptimizer]: """ Decorator to register an optimizer. Args: optimizer_class: Optimizer class to register Returns: The same optimizer class (for use as decorator) """ response_type = optimizer_class.response_type() cls._optimizers[response_type.lower()] = optimizer_class return optimizer_class
[docs] @classmethod def get_optimizer(cls, response_type: str) -> ResponseOptimizer: """ Get optimizer for response type. Args: response_type: Response type identifier (e.g., 'json', 'html', 'text') Returns: Optimizer instance Raises: KeyError: If response type not registered """ normalized = response_type.lower() if normalized not in cls._optimizers: raise KeyError(f"No optimizer registered for response type '{response_type}'") return cls._optimizers[normalized]()
# Auto-register built-in parsers and optimizers ResponseParserRegistry.register(JsonResponseParser) ResponseParserRegistry.register(HtmlResponseParser) ResponseParserRegistry.register(TextResponseParser) ResponseOptimizerRegistry.register(JsonResponseOptimizer) ResponseOptimizerRegistry.register(HtmlResponseOptimizer) ResponseOptimizerRegistry.register(TextResponseOptimizer)