We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/daekeun-ml/ppt-translator'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""
Configuration constants and settings for PowerPoint Translator
"""
import os
from pathlib import Path
from typing import Dict, List
from dotenv import load_dotenv
# Load environment variables from .env file
env_path = Path(__file__).parent.parent / '.env'
load_dotenv(dotenv_path=env_path)
class Config:
"""Configuration constants"""
# AWS Configuration
AWS_REGION = os.getenv('AWS_REGION', 'us-east-1')
AWS_PROFILE = os.getenv('AWS_PROFILE', 'default')
# Translation settings from environment
DEFAULT_TARGET_LANGUAGE = os.getenv('DEFAULT_TARGET_LANGUAGE', 'ko')
DEFAULT_MODEL_ID = os.getenv('BEDROCK_MODEL_ID', 'us.anthropic.claude-3-7-sonnet-20250219-v1:0')
MAX_TOKENS = int(os.getenv('MAX_TOKENS', '4000'))
TEMPERATURE = float(os.getenv('TEMPERATURE', '0.1'))
ENABLE_POLISHING = os.getenv('ENABLE_POLISHING', 'true').lower() == 'true'
BATCH_SIZE = int(os.getenv('BATCH_SIZE', '20'))
CONTEXT_THRESHOLD = int(os.getenv('CONTEXT_THRESHOLD', '100')) # Effectively disable context translation
# Debug settings
DEBUG = os.getenv('DEBUG', 'false').lower() == 'true'
# Post-processing settings
ENABLE_TEXT_AUTOFIT = os.getenv('ENABLE_TEXT_AUTOFIT', 'true').lower() == 'true'
TEXT_LENGTH_THRESHOLD = int(os.getenv('TEXT_LENGTH_THRESHOLD', '10'))
# Font settings by language
FONT_KOREAN = os.getenv('FONT_KOREAN', '맑은 고딕')
FONT_JAPANESE = os.getenv('FONT_JAPANESE', 'Yu Gothic UI')
FONT_ENGLISH = os.getenv('FONT_ENGLISH', 'Amazon Ember')
FONT_CHINESE = os.getenv('FONT_CHINESE', 'Microsoft YaHei')
FONT_DEFAULT = os.getenv('FONT_DEFAULT', 'Arial')
# Font mapping by language code
FONT_MAP = {
'ko': FONT_KOREAN,
'ja': FONT_JAPANESE,
'en': FONT_ENGLISH,
'en-US': FONT_ENGLISH,
'en-GB': FONT_ENGLISH,
'en-AU': FONT_ENGLISH,
'en-CA': FONT_ENGLISH,
'zh': FONT_CHINESE,
'zh-CN': FONT_CHINESE,
'zh-TW': FONT_CHINESE,
'zh-HK': FONT_CHINESE,
'zh-SG': FONT_CHINESE,
'zh-MY': FONT_CHINESE,
}
# Supported models (text generation only)
SUPPORTED_MODELS = [
# Amazon Nova models (text-only)
"us.amazon.nova-micro-v1:0",
"us.amazon.nova-lite-v1:0",
"us.amazon.nova-pro-v1:0",
"us.amazon.nova-premier-v1:0",
"global.amazon.nova-2-lite-v1:0",
"us.amazon.nova-2-lite-v1:0"
# Anthropic Claude models
"global.anthropic.claude-haiku-4-5-20251001-v1:0",
"global.anthropic.claude-opus-4-5-20251101-v1:0",
"global.anthropic.claude-sonnet-4-20250514-v1:0",
"global.anthropic.claude-sonnet-4-5-20250929-v1:0",
"anthropic.claude-3-5-sonnet-20241022-v2:0",
"us.anthropic.claude-3-5-sonnet-20241022-v2:0",
"us.anthropic.claude-3-7-sonnet-20250219-v1:0",
"us.anthropic.claude-haiku-4-5-20251001-v1:0",
"us.anthropic.claude-opus-4-5-20251101-v1:0",
"us.anthropic.claude-sonnet-4-20250514-v1:0",
"us.anthropic.claude-sonnet-4-5-20250929-v1:0",
# Meta Llama models
"meta.llama4-scout-17b-instruct-v1:0",
"meta.llama4-maverick-17b-instruct-v1:0",
"us.meta.llama4-scout-17b-instruct-v1:0",
"us.meta.llama4-maverick-17b-instruct-v1:0",
# DeepSeek models
"deepseek.r1-v1:0",
"us.deepseek.r1-v1:0",
# Mistral models
"mistral.mistral-7b-instruct-v0:2",
"mistral.mixtral-8x7b-instruct-v0:1",
"mistral.mistral-large-2402-v1:0",
"mistral.mistral-large-3-675b-instruct",
"mistral.mistral-small-2402-v1:0",
"mistral.magistral-small-2509",
"mistral.ministral-3-3b-instruct",
"mistral.ministral-3-8b-instruct",
"mistral.ministral-3-14b-instruct",
# Cohere models
"cohere.command-r-v1:0",
"cohere.command-r-plus-v1:0",
# AI21 models
"ai21.jamba-1-5-large-v1:0",
"ai21.jamba-1-5-mini-v1:0",
# OpenAI models
"openai.gpt-oss-20b-1:0",
"openai.gpt-oss-120b-1:0",
"openai.gpt-oss-safeguard-20b",
"openai.gpt-oss-safeguard-120b",
# Qwen models (text-only)
"qwen.qwen3-32b-v1:0",
"qwen.qwen3-next-80b-a3b",
"qwen.qwen3-coder-30b-a3b-v1:0",
# Google models
"google.gemma-3-4b-it",
"google.gemma-3-12b-it",
"google.gemma-3-27b-it",
# Writer models
"us.writer.palmyra-x4-v1:0",
"us.writer.palmyra-x5-v1:0",
# Upstage models
"upstage-solar-pro"
]
# Language mapping - Comprehensive list of supported languages
LANGUAGE_MAP = {
# Major languages
'en': 'English',
'ko': 'Korean',
'ja': 'Japanese',
'zh': 'Chinese (Simplified)',
'zh-CN': 'Chinese (Simplified)',
'zh-TW': 'Chinese (Traditional)',
'zh-HK': 'Chinese (Hong Kong)',
# European languages
'fr': 'French',
'de': 'German',
'es': 'Spanish',
'it': 'Italian',
'pt': 'Portuguese',
'pt-BR': 'Portuguese (Brazil)',
'ru': 'Russian',
'nl': 'Dutch',
'sv': 'Swedish',
'no': 'Norwegian',
'da': 'Danish',
'fi': 'Finnish',
'pl': 'Polish',
'cs': 'Czech',
'sk': 'Slovak',
'hu': 'Hungarian',
'ro': 'Romanian',
'bg': 'Bulgarian',
'hr': 'Croatian',
'sr': 'Serbian',
'sl': 'Slovenian',
'et': 'Estonian',
'lv': 'Latvian',
'lt': 'Lithuanian',
'el': 'Greek',
'tr': 'Turkish',
'uk': 'Ukrainian',
'be': 'Belarusian',
'mk': 'Macedonian',
'mt': 'Maltese',
'is': 'Icelandic',
'ga': 'Irish',
'cy': 'Welsh',
'eu': 'Basque',
'ca': 'Catalan',
'gl': 'Galician',
# Middle Eastern and African languages
'ar': 'Arabic',
'he': 'Hebrew',
'fa': 'Persian (Farsi)',
'ur': 'Urdu',
'sw': 'Swahili',
'am': 'Amharic',
'ha': 'Hausa',
'yo': 'Yoruba',
'ig': 'Igbo',
'zu': 'Zulu',
'af': 'Afrikaans',
# South Asian languages
'hi': 'Hindi',
'bn': 'Bengali',
'te': 'Telugu',
'mr': 'Marathi',
'ta': 'Tamil',
'gu': 'Gujarati',
'kn': 'Kannada',
'ml': 'Malayalam',
'pa': 'Punjabi',
'or': 'Odia',
'as': 'Assamese',
'ne': 'Nepali',
'si': 'Sinhala',
'my': 'Burmese',
# Southeast Asian languages
'th': 'Thai',
'vi': 'Vietnamese',
'id': 'Indonesian',
'ms': 'Malay',
'tl': 'Filipino (Tagalog)',
'km': 'Khmer',
'lo': 'Lao',
# Other languages
'az': 'Azerbaijani',
'kk': 'Kazakh',
'ky': 'Kyrgyz',
'uz': 'Uzbek',
'tg': 'Tajik',
'mn': 'Mongolian',
'ka': 'Georgian',
'hy': 'Armenian',
'sq': 'Albanian',
'mk': 'Macedonian',
'lv': 'Latvian',
'lt': 'Lithuanian',
'et': 'Estonian',
# Additional variants and regional codes
'en-US': 'English (US)',
'en-GB': 'English (UK)',
'en-AU': 'English (Australia)',
'en-CA': 'English (Canada)',
'fr-CA': 'French (Canada)',
'fr-CH': 'French (Switzerland)',
'de-AT': 'German (Austria)',
'de-CH': 'German (Switzerland)',
'es-MX': 'Spanish (Mexico)',
'es-AR': 'Spanish (Argentina)',
'es-CO': 'Spanish (Colombia)',
'es-CL': 'Spanish (Chile)',
'es-PE': 'Spanish (Peru)',
'es-VE': 'Spanish (Venezuela)',
'pt-PT': 'Portuguese (Portugal)',
'it-CH': 'Italian (Switzerland)',
'nl-BE': 'Dutch (Belgium)',
'sv-FI': 'Swedish (Finland)',
'ar-SA': 'Arabic (Saudi Arabia)',
'ar-EG': 'Arabic (Egypt)',
'ar-AE': 'Arabic (UAE)',
'ar-MA': 'Arabic (Morocco)',
'zh-SG': 'Chinese (Singapore)',
'zh-MY': 'Chinese (Malaysia)',
'ms-SG': 'Malay (Singapore)',
'ta-SG': 'Tamil (Singapore)',
'hi-IN': 'Hindi (India)',
'bn-BD': 'Bengali (Bangladesh)',
'ur-PK': 'Urdu (Pakistan)',
'fa-IR': 'Persian (Iran)',
'fa-AF': 'Persian (Afghanistan)',
'ps': 'Pashto',
'sd': 'Sindhi',
'ckb': 'Kurdish (Sorani)',
'ku': 'Kurdish (Kurmanji)',
'yi': 'Yiddish',
'la': 'Latin',
'eo': 'Esperanto',
'jv': 'Javanese',
'su': 'Sundanese',
'ceb': 'Cebuano',
'haw': 'Hawaiian',
'mi': 'Maori',
'sm': 'Samoan',
'to': 'Tongan',
'fj': 'Fijian',
'mg': 'Malagasy',
'ny': 'Chichewa',
'sn': 'Shona',
'st': 'Sesotho',
'tn': 'Setswana',
'ts': 'Tsonga',
've': 'Venda',
'xh': 'Xhosa',
'co': 'Corsican',
'fy': 'Frisian',
'gd': 'Scottish Gaelic',
'lb': 'Luxembourgish',
'rm': 'Romansh'
}
# Korean-specific terminology rules
KOREAN_TERMINOLOGY = {
"Observability": "Observability",
"AgentCore Observability": "AgentCore Observability",
"Key concepts": "핵심 개념",
"Best Practices": "모범 사례",
"Resources": "리소스",
"Demos": "데모",
"Pricing": "가격 책정"
}
# Text patterns to skip translation
SKIP_PATTERNS = [
r'^\d+$', # Numbers only
r'^https?://', # URLs
r'\S+@\S+\.\S+', # Email addresses
r'^```.*```$', # Code blocks
r'^\s*[{}\[\]();,.:]+\s*$', # Code syntax characters only
r'^\s*import\s+\w+', # Python imports
r'^\s*from\s+\w+\s+import', # Python from imports
r'^\s*def\s+\w+\(', # Python function definitions
r'^\s*class\s+\w+', # Python class definitions
r'^\s*if\s+.*:', # Python if statements
r'^\s*for\s+.*:', # Python for loops
r'^\s*while\s+.*:', # Python while loops
r'^\s*try\s*:', # Python try blocks
r'^\s*except\s*.*:', # Python except blocks
r'^\s*return\s+', # Python return statements
r'^\s*print\s*\(', # Python print statements
r'^\s*console\.log\s*\(', # JavaScript console.log
r'^\s*function\s+\w+\s*\(', # JavaScript functions
r'^\s*var\s+\w+\s*=', # JavaScript var declarations
r'^\s*let\s+\w+\s*=', # JavaScript let declarations
r'^\s*const\s+\w+\s*=', # JavaScript const declarations
r'^\s*\$\s*\(', # jQuery
r'^\s*<\w+.*>.*</\w+>\s*$', # HTML tags
r'^\s*<\w+.*/?>\s*$', # Self-closing HTML tags
]
@classmethod
def get_language_name(cls, language_code: str) -> str:
"""Get the full language name from language code"""
return cls.LANGUAGE_MAP.get(language_code, language_code)
@classmethod
def validate_model_id(cls, model_id: str) -> bool:
"""Validate if the model ID is supported"""
return model_id in cls.SUPPORTED_MODELS
@classmethod
def reload_env(cls):
"""Reload environment variables (useful for testing)"""
load_dotenv(dotenv_path=env_path, override=True)
@classmethod
def get_font_for_language(cls, language_code: str) -> str:
"""Get the appropriate font for a given language code"""
return cls.FONT_MAP.get(language_code, cls.FONT_DEFAULT)
@classmethod
def check_aws_credentials(cls):
"""Check if AWS credentials are properly configured"""
import boto3
from botocore.exceptions import NoCredentialsError, PartialCredentialsError
try:
# Try to create a session with the specified profile
if cls.AWS_PROFILE and cls.AWS_PROFILE != 'default':
session = boto3.Session(profile_name=cls.AWS_PROFILE)
else:
session = boto3.Session()
# Try to get credentials
credentials = session.get_credentials()
if credentials is None:
return False, "No AWS credentials found. Please run 'aws configure' to set up your credentials."
# Try to make a simple AWS call to verify credentials work
sts = session.client('sts', region_name=cls.AWS_REGION)
sts.get_caller_identity()
return True, "AWS credentials are properly configured."
except NoCredentialsError:
return False, "No AWS credentials found. Please run 'aws configure' to set up your credentials."
except PartialCredentialsError:
return False, "Incomplete AWS credentials. Please run 'aws configure' to complete your credential setup."
except Exception as e:
return False, f"AWS credential verification failed: {str(e)}"
def __init__(self):
"""Initialize configuration with environment variables"""
self._env_vars = {}
self._load_env_vars()
def _load_env_vars(self):
"""Load all environment variables"""
for key, value in os.environ.items():
self._env_vars[key] = value
def get(self, key: str, default: str = None) -> str:
"""Get configuration value by key"""
return self._env_vars.get(key, default)
def get_bool(self, key: str, default: bool = False) -> bool:
"""Get boolean configuration value"""
value = self.get(key, str(default).lower())
return value.lower() in ('true', '1', 'yes', 'on')
def get_int(self, key: str, default: int = 0) -> int:
"""Get integer configuration value"""
try:
return int(self.get(key, str(default)))
except (ValueError, TypeError):
return default
def get_float(self, key: str, default: float = 0.0) -> float:
"""Get float configuration value"""
try:
return float(self.get(key, str(default)))
except (ValueError, TypeError):
return default
def set(self, key: str, value: str):
"""Set configuration value"""
self._env_vars[key] = value
os.environ[key] = value