Skip to main content
Glama
utils.py3.67 kB
"""Utility functions for PostgreSQL MCP Server.""" from __future__ import annotations from functools import wraps from typing import Any, Callable, Optional def truncate_string(text: Optional[str], max_length: int = 100) -> str: """Truncate a string to specified length with ellipsis. Args: text: Text to truncate (can be None) max_length: Maximum length including ellipsis Returns: Truncated string, or empty string if input is None Examples: >>> truncate_string("Hello World", 5) 'He...' >>> truncate_string(None) '' """ if not text: return "" if len(text) <= max_length: return text return text[:max_length - 3] + "..." def format_bytes(num_bytes: Optional[int]) -> str: """Format bytes as human-readable string. Args: num_bytes: Number of bytes (can be None) Returns: Formatted string like "1.5 MB" Examples: >>> format_bytes(1024) '1.0 KB' >>> format_bytes(1048576) '1.0 MB' """ if num_bytes is None: return "unknown" for unit in ["B", "KB", "MB", "GB", "TB"]: if abs(num_bytes) < 1024.0: return f"{num_bytes:.1f} {unit}" num_bytes /= 1024.0 return f"{num_bytes:.1f} PB" def format_count(count: Optional[int]) -> str: """Format a count with K/M suffix for readability. Args: count: Number to format (can be None) Returns: Formatted string like "1.5M" Examples: >>> format_count(1500) '1.5K' >>> format_count(1500000) '1.5M' """ if count is None: return "unknown" if count < 1000: return str(count) elif count < 1_000_000: return f"{count / 1000:.1f}K" else: return f"{count / 1_000_000:.1f}M" def not_found_response(resource: str, identifier: str) -> dict[str, Any]: """Standard response for not-found resources. Args: resource: Resource type name (e.g., "Table", "Schema") identifier: Resource identifier Returns: Dict with error message Example: >>> not_found_response("Table", "users") {'error': "Table 'users' not found"} """ return {"error": f"{resource} '{identifier}' not found"} def handle_db_error(func: Callable[..., dict[str, Any]]) -> Callable[..., dict[str, Any]]: """Decorator to handle database errors consistently. Wraps a function to catch database exceptions and return a standardized error response instead of raising. Args: func: Function that may raise database errors Returns: Wrapped function that returns {"success": False, "error": str} on error """ import psycopg2 from postgres_mcp.security import SQLValidationError @wraps(func) def wrapper(*args: Any, **kwargs: Any) -> dict[str, Any]: try: return func(*args, **kwargs) except SQLValidationError as e: return {"success": False, "error": f"Validation error: {str(e)}"} except psycopg2.OperationalError as e: return {"success": False, "error": f"Connection error: {str(e)}"} except psycopg2.ProgrammingError as e: return {"success": False, "error": f"SQL error: {str(e)}"} except psycopg2.Error as e: return {"success": False, "error": f"Database error: {str(e)}"} except Exception as e: return {"success": False, "error": f"Unexpected error: {str(e)}"} return wrapper

Latest Blog Posts

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/JaviMaligno/postgres-mcp'

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