CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-disnake

A modern, easy-to-use, feature-rich async-ready API wrapper for Discord written in Python

Pending
Overview
Eval results
Files

localization-i18n.mddocs/

Localization and Internationalization (i18n)

Disnake's internationalization system enables application commands to support multiple languages through Discord's native localization features. The system provides both high-level convenience classes and low-level protocols for custom localization implementations.

Capabilities

Localized Strings

Container class for managing localized strings across different languages/locales.

class Localized(Generic[StringT]):
    def __init__(
        self,
        string: StringT,
        *,
        key: Optional[str] = None,
        **localizations: StringT
    ):
        """
        Create a localized string container.
        
        Parameters:
        - string: Base/default string value
        - key: Localization key for lookups
        - localizations: Locale-specific string values
        """

    def set(self, locale: Union[Locale, str], value: StringT) -> Self:
        """
        Set localized value for a specific locale.
        
        Parameters:
        - locale: Target locale
        - value: Localized string value
        
        Returns:
        Self for method chaining
        """

    @property
    def localizations(self) -> Dict[Locale, StringT]:
        """Dictionary of all localized values."""

    @property 
    def key(self) -> Optional[str]:
        """Localization key for external lookup."""

Localization Value

Represents a localized value with support for fallback languages and placeholder substitution.

class LocalizationValue:
    def __init__(
        self,
        message: str,
        key: Optional[str] = None,
        **kwargs: Any
    ):
        """
        Create a localization value with optional formatting.
        
        Parameters:
        - message: Base message string
        - key: Localization key identifier
        - kwargs: Format arguments for string interpolation
        """

    def format(self, **kwargs: Any) -> LocalizationValue:
        """
        Create new LocalizationValue with additional format arguments.
        
        Parameters:
        - kwargs: Format arguments to merge
        
        Returns:
        New LocalizationValue with combined formatting
        """

Localization Protocol

Abstract protocol defining the interface for localization providers.

class LocalizationProtocol(ABC):
    @abstractmethod
    async def get(
        self,
        key: str,
        locale: Locale,
        *,
        default: Optional[str] = None,
        **kwargs: Any
    ) -> Optional[str]:
        """
        Get localized string for key and locale.
        
        Parameters:
        - key: Localization key
        - locale: Target locale
        - default: Default value if key not found
        - kwargs: Format arguments for string interpolation
        
        Returns:
        Localized string or None if not found
        """

    @abstractmethod  
    async def bulk_get(
        self,
        keys: Sequence[str],
        locale: Locale,
        **kwargs: Any
    ) -> Dict[str, Optional[str]]:
        """
        Get multiple localized strings at once.
        
        Parameters:
        - keys: List of localization keys
        - locale: Target locale
        - kwargs: Format arguments for all strings
        
        Returns:
        Dictionary mapping keys to localized strings
        """

Localization Store

Default file-based localization provider that loads translations from JSON files.

class LocalizationStore(LocalizationProtocol):
    def __init__(
        self,
        files: Union[os.PathLike, Dict[Locale, os.PathLike]],
        *,
        strict: bool = False,
        fallback: Optional[Locale] = None
    ):
        """
        Initialize localization store with translation files.
        
        Parameters:
        - files: Path to directory or mapping of locales to file paths
        - strict: Whether to raise errors for missing keys
        - fallback: Fallback locale when translation missing
        """

    @classmethod
    def from_directory(
        cls,
        directory: os.PathLike,
        *,
        pattern: str = "{locale}.json",
        strict: bool = False,
        fallback: Optional[Locale] = None
    ) -> LocalizationStore:
        """
        Create store from directory of JSON translation files.
        
        Parameters:
        - directory: Directory containing translation files
        - pattern: Filename pattern with {locale} placeholder
        - strict: Whether to raise errors for missing keys
        - fallback: Fallback locale for missing translations
        
        Returns:
        Configured LocalizationStore instance
        """

    async def reload(self) -> None:
        """Reload all translation files from disk."""

    @property
    def locales(self) -> Set[Locale]:
        """All available locales in the store."""

Types

# Type aliases for localized strings
LocalizedRequired = Union[str, "Localized[str]"]
LocalizedOptional = Union[Optional[str], "Localized[Optional[str]]"]
LocalizationsDict = Union[Dict[Locale, str], Dict[str, str]]

# Alias for British English spelling
Localised = Localized

Usage Examples

Basic Localized Strings

import disnake
from disnake.i18n import Localized

# Create localized command name and description
@bot.slash_command(
    name=Localized("hello", es="hola", fr="salut"),
    description=Localized(
        "Say hello to someone",
        es="Saluda a alguien", 
        fr="Dire bonjour à quelqu'un"
    )
)
async def hello(
    inter: disnake.ApplicationCommandInteraction,
    user: disnake.User = disnake.Param(
        description=Localized(
            "The user to greet",
            es="El usuario a saludar",
            fr="L'utilisateur à saluer"
        )
    )
):
    await inter.response.send_message(f"Hello {user.mention}!")

File-based Localization Store

import disnake
from disnake.i18n import LocalizationStore
from disnake.enums import Locale

# Set up localization store
i18n_store = LocalizationStore.from_directory(
    "locales/",
    pattern="{locale}.json",
    fallback=Locale.en_US
)

# Configure client with localization
bot = disnake.Bot(
    command_prefix="!",
    intents=disnake.Intents.default(),
    localization_provider=i18n_store
)

# Use localization keys in commands
@bot.slash_command(
    name="greet",
    description=Localized(key="commands.greet.description")
)
async def greet(
    inter: disnake.ApplicationCommandInteraction,
    target: disnake.User = disnake.Param(
        description=Localized(key="commands.greet.target_param")
    )
):
    # Get localized response message
    greeting = await i18n_store.get(
        key="messages.greeting",
        locale=inter.locale,
        username=target.display_name
    )
    await inter.response.send_message(greeting)

Translation File Structure

Example locales/en-US.json:

{
  "commands": {
    "greet": {
      "description": "Greet another user",
      "target_param": "User to greet"
    }
  },
  "messages": {
    "greeting": "Hello, {username}!"
  }
}

Example locales/es.json:

{
  "commands": {
    "greet": {
      "description": "Saluda a otro usuario", 
      "target_param": "Usuario a saludar"
    }
  },
  "messages": {
    "greeting": "¡Hola, {username}!"
  }
}

Install with Tessl CLI

npx tessl i tessl/pypi-disnake

docs

application-commands.md

automod.md

channels-messaging.md

client-bot.md

command-framework.md

error-handling.md

events-gateway.md

guild-management.md

index.md

interactions-ui.md

localization-i18n.md

permissions-security.md

polls.md

users-members.md

voice-audio.md

tile.json