Skip to main content
Glama

mcp-plots

field_validator.py6.23 kB
""" Centralized field validation system for chart generation. This module provides comprehensive validation for chart data fields, ensuring that all required fields are present and valid before chart generation begins. This prevents None errors and provides clear, actionable error messages. """ from typing import Set, List, Dict, Any, Union import pandas as pd from .chart_config import ChartData, ChartType from ..domain.exceptions import ( DataValidationError, EmptyDataError, MissingFieldError, FieldNotFoundError, InvalidDataFormatError ) # Keep old exception for backward compatibility class FieldValidationError(DataValidationError): """Legacy exception - use specific exceptions instead.""" pass class FieldValidator: """ Centralized validator for chart data fields. Provides comprehensive validation of field mappings and data columns before chart generation, preventing None errors and providing clear error messages. """ @staticmethod def validate_chart_fields(chart_type: ChartType, chart_data: ChartData) -> None: """ Validate that all required fields are present and valid for the chart type. Args: chart_type: The type of chart being generated chart_data: The chart data with field mappings Raises: FieldValidationError: If validation fails with detailed error message """ # Get required fields for this chart type required_fields = chart_type.required_fields if not required_fields: return # No validation needed for charts with no required fields # Check that all required fields are mapped missing_fields = [] for field_name in required_fields: field_value = getattr(chart_data, field_name, None) if not field_value: missing_fields.append(field_name) if missing_fields: raise MissingFieldError(missing_fields, chart_type.value) # Validate that mapped fields exist in the data df = FieldValidator._prepare_dataframe(chart_data.data) missing_columns = [] for field_name in required_fields: field_value = getattr(chart_data, field_name) if field_value and field_value not in df.columns: missing_columns.append(f"{field_name}='{field_value}'") if missing_columns: # Parse missing columns back to field mappings dict missing_mappings = {} for col_str in missing_columns: if "=" in col_str: field, mapping = col_str.split("=", 1) missing_mappings[field] = mapping.strip("'\"") raise FieldNotFoundError(missing_mappings, df.columns.tolist()) @staticmethod def validate_optional_fields(chart_data: ChartData, *field_names: str) -> Dict[str, bool]: """ Validate optional fields and return which ones are available. Args: chart_data: The chart data with field mappings *field_names: Names of optional fields to check Returns: Dict mapping field names to availability (True/False) """ df = FieldValidator._prepare_dataframe(chart_data.data) availability = {} for field_name in field_names: field_value = getattr(chart_data, field_name, None) availability[field_name] = ( field_value is not None and field_value in df.columns ) return availability @staticmethod def get_safe_field_value(chart_data: ChartData, field_name: str, default: Any = None) -> Any: """ Safely get a field value, returning default if field is None or missing. Args: chart_data: The chart data with field mappings field_name: Name of the field to get default: Default value if field is None or missing Returns: Field value or default """ field_value = getattr(chart_data, field_name, None) if not field_value: return default df = FieldValidator._prepare_dataframe(chart_data.data) if field_value not in df.columns: return default return field_value @staticmethod def _prepare_dataframe(data: Union[List[Dict[str, Any]], pd.DataFrame]) -> pd.DataFrame: """Convert data to pandas DataFrame for validation.""" if isinstance(data, pd.DataFrame): return data elif isinstance(data, list): return pd.DataFrame(data) else: raise ValueError("Data must be a list of dictionaries or pandas DataFrame") @staticmethod def validate_data_not_empty(data: Union[List[Dict[str, Any]], pd.DataFrame]) -> None: """ Validate that the data is not empty. Args: data: The data to validate Raises: FieldValidationError: If data is empty """ if isinstance(data, list): if not data: raise EmptyDataError("data") elif isinstance(data, pd.DataFrame): if data.empty: raise EmptyDataError("data") else: raise InvalidDataFormatError("a pandas DataFrame or list of dictionaries", type(data).__name__) @staticmethod def get_chart_type_help(chart_type: ChartType) -> str: """ Get helpful information about required fields for a chart type. Args: chart_type: The chart type to get help for Returns: Helpful message about required fields """ required_fields = chart_type.required_fields if not required_fields: return f"{chart_type.value.title()} chart has no required field mappings." field_list = ", ".join(required_fields) return f"{chart_type.value.title()} chart requires: {field_list}"

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MR901/mcp-plots'

If you have feedback or need assistance with the MCP directory API, please join our Discord server