Source code for mindroot.coreplugins.l8n.middleware

from fastapi import Request

try:
    from .language_detection import (
        _parse_accept_language_header,
        get_fallback_language,
        set_language_for_request
    )
except ImportError:
    # For standalone testing
    from language_detection import (
        _parse_accept_language_header,
        get_fallback_language,
        set_language_for_request
    )
import os

# Global variable to store the current request language
# This will be set by the middleware for each request
_current_request_language = None

[docs] def get_request_language() -> str: """ Get the language that was detected for the current request. This function is called by the monkey patch system to get the language for template translation. Returns: Language code for the current request """ global _current_request_language print(f"L8n: Current request language is '{_current_request_language}'") # If we have a request-specific language, use it if _current_request_language: return _current_request_language # Fallback to environment variable or default print("L8n: No request language set, falling back to environment variable or default") return os.environ.get('MINDROOT_LANGUAGE', 'en')
[docs] def detect_language_from_request(request: Request) -> str: """ Detect the preferred language from a FastAPI request. Checks multiple sources in order of priority: 1. URL parameter (?lang=es) 2. Cookie value (mindroot_language) 3. Accept-Language header 4. Environment variable 5. Default to 'en' Args: request: FastAPI Request object Returns: Detected language code """ # 1. Check URL parameter first (highest priority) print(f"L8n: Checking URL parameters for language: {request.query_params}") url_lang = request.query_params.get('lang') if url_lang: return get_fallback_language(url_lang.lower()) # 2. Check cookie value print(f"L8n: Checking cookies for language: {request.cookies}") cookie_lang = request.cookies.get('mindroot_language') if cookie_lang: print(f"L8n: Found language in cookie: {cookie_lang}") return get_fallback_language(cookie_lang.lower()) # 3. Check Accept-Language header print(f"L8n: Accept-Language header: {request.headers.get('accept-language')}") accept_language = request.headers.get('accept-language') if accept_language: print(f"L8n: Parsing Accept-Language header: {accept_language}") parsed_lang = _parse_accept_language_header(accept_language) if parsed_lang: print(f"L8n: Parsed language from header: {parsed_lang}") return get_fallback_language(parsed_lang) # 4. Check environment variable env_lang = os.environ.get('MINDROOT_LANGUAGE') if env_lang: return get_fallback_language(env_lang.lower()) # 5. Default to English return 'en'
[docs] async def middleware(request: Request, call_next): """ L8n middleware for language detection and setting. This middleware runs early in the request pipeline to: 1. Detect the preferred language for the request 2. Store it globally for use by the template system 3. Set it in the request state for other components Args: request: FastAPI Request object call_next: Next middleware/handler in the chain Returns: Response from the next handler """ global _current_request_language try: print("L8n middleware: Starting language detection") # Detect the language for this request detected_language = detect_language_from_request(request) print(f"L8n: Detected language '{detected_language}' for {request.url.path}") # Store it globally for the template system _current_request_language = detected_language # Also store it in request state for other components request.state.language = detected_language # Set it using the language detection system set_language_for_request(detected_language) # Debug logging (can be removed in production) print(f"L8n: Detected language '{detected_language}' for {request.url.path}") # Process the request response = await call_next(request) # Optionally set a cookie to remember the language preference # Only set if it was explicitly requested via URL parameter if request.query_params.get('lang'): response.set_cookie( key="mindroot_language", value=detected_language, max_age=30 * 24 * 60 * 60, # 30 days httponly=True, samesite="lax" ) return response except Exception as e: print(f"L8n middleware error: {e}") # If there's an error, continue with default language _current_request_language = 'en' request.state.language = 'en' return await call_next(request) finally: # Clean up the global variable after the request _current_request_language = None