# How to Internationalize Your Application This guide shows you how to use Metric Engine's Babel integration to create applications that work across different locales and currencies. ## Quick Setup ### 1. Install with Babel Support ```bash pip install "metric-engine[babel]" ``` ### 2. Basic Multi-Locale Example ```python from metricengine.factories import money, percent from metricengine.policy import DisplayPolicy # Your business data revenue = money(1234567.89) growth_rate = percent(12.5, input="percent") profit_margin = percent(0.185, input="ratio") # 18.5% # Define locale-specific policies locales = { "us": DisplayPolicy(locale="en_US", currency="USD"), "uk": DisplayPolicy(locale="en_GB", currency="GBP"), "germany": DisplayPolicy(locale="de_DE", currency="EUR"), "japan": DisplayPolicy(locale="ja_JP", currency="JPY", max_frac=0), } # Format for each locale for region, policy in locales.items(): print(f"\n{region.upper()} Formatting:") print(f" Revenue: {revenue.format(policy)}") print(f" Growth: {growth_rate.format(policy)}") print(f" Margin: {profit_margin.format(policy)}") ``` Output: ``` US Formatting: Revenue: $1,234,567.89 Growth: 12.50% Margin: 18.50% UK Formatting: Revenue: £1,234,567.89 Growth: 12.50% Margin: 18.50% GERMANY Formatting: Revenue: 1.234.567,89 € Growth: 12,50 % Margin: 18,50 % JAPAN Formatting: Revenue: ¥1,234,568 Growth: 13% Margin: 19% ``` ## Building a Multi-Currency Dashboard ### 1. Create a Formatter Service ```python from typing import Dict from metricengine.formatters.base import get_formatter from metricengine.policy import DisplayPolicy class LocalizationService: """Service for handling multi-locale formatting.""" def __init__(self): self.formatter = get_formatter() self.policies = self._create_policies() def _create_policies(self) -> Dict[str, DisplayPolicy]: """Create standard policies for supported locales.""" return { "en_US": DisplayPolicy( locale="en_US", currency="USD", max_frac=2, use_grouping=True ), "en_GB": DisplayPolicy( locale="en_GB", currency="GBP", max_frac=2, use_grouping=True ), "de_DE": DisplayPolicy( locale="de_DE", currency="EUR", max_frac=2, use_grouping=True ), "fr_FR": DisplayPolicy( locale="fr_FR", currency="EUR", max_frac=2, use_grouping=True ), "ja_JP": DisplayPolicy( locale="ja_JP", currency="JPY", max_frac=0, # Yen doesn't use decimal places use_grouping=True ), } def format_for_locale(self, value, locale: str): """Format a value for a specific locale.""" policy = self.policies.get(locale, self.policies["en_US"]) return value.format(policy) def get_accounting_policy(self, locale: str) -> DisplayPolicy: """Get accounting-style policy for financial reports.""" base_policy = self.policies.get(locale, self.policies["en_US"]) return DisplayPolicy( locale=base_policy.locale, currency=base_policy.currency, max_frac=base_policy.max_frac, use_grouping=base_policy.use_grouping, currency_style="accounting", negative_parens=True ) # Usage localization = LocalizationService() ``` ### 2. Create Financial Reports ```python from metricengine.factories import money def generate_financial_report(data: dict, locale: str = "en_US"): """Generate a localized financial report.""" localization = LocalizationService() accounting_policy = localization.get_accounting_policy(locale) # Calculate key metrics revenue = data["revenue"] expenses = data["expenses"] net_income = revenue - expenses # Format with accounting style report = f""" Financial Report ({locale}) {'=' * 30} Revenue: {revenue.format(accounting_policy)} Expenses: {expenses.format(accounting_policy)} Net Income: {net_income.format(accounting_policy)} """ return report # Example usage financial_data = { "revenue": money(500000), "expenses": money(350000) } # Generate reports for different locales for locale in ["en_US", "de_DE", "ja_JP"]: print(generate_financial_report(financial_data, locale)) ``` ## Handling User Preferences ### 1. User Preference System ```python from dataclasses import dataclass from typing import Optional @dataclass class UserPreferences: """User's localization preferences.""" locale: str = "en_US" currency: str = "USD" decimal_places: int = 2 use_accounting_style: bool = False show_currency_symbol: bool = True class UserLocalizer: """Handles user-specific formatting preferences.""" def __init__(self, preferences: UserPreferences): self.preferences = preferences self.formatter = get_formatter() def create_policy(self) -> DisplayPolicy: """Create a display policy from user preferences.""" return DisplayPolicy( locale=self.preferences.locale, currency=self.preferences.currency, max_frac=self.preferences.decimal_places, min_frac=self.preferences.decimal_places, use_grouping=True, currency_style="accounting" if self.preferences.use_accounting_style else "standard", negative_parens=self.preferences.use_accounting_style ) def format_money(self, amount): """Format money according to user preferences.""" policy = self.create_policy() return amount.format(policy) def format_percentage(self, percentage): """Format percentage according to user preferences.""" policy = self.create_policy() return percentage.format(policy) # Example usage user_prefs = UserPreferences( locale="de_DE", currency="EUR", decimal_places=2, use_accounting_style=True ) localizer = UserLocalizer(user_prefs) amount = money(1234.56) print(localizer.format_money(amount)) # 1.234,56 € ``` ### 2. Dynamic Locale Switching ```python class DynamicFormatter: """Formatter that can switch locales dynamically.""" def __init__(self): self.formatter = get_formatter() self.current_locale = "en_US" self.policies_cache = {} def set_locale(self, locale: str, currency: str = None): """Switch to a different locale.""" self.current_locale = locale if currency: # Update cached policy for this locale self.policies_cache[locale] = DisplayPolicy( locale=locale, currency=currency, max_frac=2, use_grouping=True ) def get_policy(self) -> DisplayPolicy: """Get policy for current locale.""" if self.current_locale not in self.policies_cache: # Create default policy for locale currency_map = { "en_US": "USD", "en_GB": "GBP", "de_DE": "EUR", "fr_FR": "EUR", "ja_JP": "JPY", "zh_CN": "CNY" } currency = currency_map.get(self.current_locale, "USD") self.policies_cache[self.current_locale] = DisplayPolicy( locale=self.current_locale, currency=currency, max_frac=2 if currency != "JPY" else 0, use_grouping=True ) return self.policies_cache[self.current_locale] def format_value(self, value): """Format value with current locale.""" policy = self.get_policy() return value.format(policy) # Usage example formatter = DynamicFormatter() amount = money(1234.56) # Switch between locales locales = ["en_US", "de_DE", "ja_JP", "fr_FR"] for locale in locales: formatter.set_locale(locale) print(f"{locale}: {formatter.format_value(amount)}") ``` ## Web Application Integration ### 1. Flask Example ```python from flask import Flask, request, session from metricengine.factories import money, percent from metricengine.policy import DisplayPolicy app = Flask(__name__) app.secret_key = 'your-secret-key' def get_user_locale(): """Get user's preferred locale from session or browser.""" return session.get('locale', request.accept_languages.best_match(['en_US', 'de_DE', 'fr_FR', 'ja_JP'])) def create_display_policy(locale: str) -> DisplayPolicy: """Create display policy for locale.""" currency_map = { 'en_US': 'USD', 'de_DE': 'EUR', 'fr_FR': 'EUR', 'ja_JP': 'JPY' } return DisplayPolicy( locale=locale, currency=currency_map.get(locale, 'USD'), max_frac=2 if locale != 'ja_JP' else 0, use_grouping=True ) @app.route('/dashboard') def dashboard(): """Display localized financial dashboard.""" locale = get_user_locale() policy = create_display_policy(locale) # Sample financial data revenue = money(1500000) expenses = money(1200000) profit = revenue - expenses margin = percent(0.20, input="ratio") return f"""
Locale: {locale}