{"id":25236722,"url":"https://github.com/mwja/py18n","last_synced_at":"2026-01-19T04:32:46.365Z","repository":{"id":62578417,"uuid":"353485580","full_name":"mwja/py18n","owner":"mwja","description":"I18n for discord.py","archived":false,"fork":false,"pushed_at":"2023-07-20T15:14:09.000Z","size":74,"stargazers_count":0,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-29T04:23:19.017Z","etag":null,"topics":["discord","discord-py","fallback","i18n","i18n-python","internationalization","language","py18n","python","python-i18n","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mwja.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-03-31T20:45:32.000Z","updated_at":"2021-09-09T00:38:04.000Z","dependencies_parsed_at":"2023-09-05T05:46:11.175Z","dependency_job_id":null,"html_url":"https://github.com/mwja/py18n","commit_stats":null,"previous_names":["jacobmacweb/py18n","starsflower/py18n","mwja/py18n"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/mwja/py18n","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwja%2Fpy18n","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwja%2Fpy18n/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwja%2Fpy18n/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwja%2Fpy18n/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mwja","download_url":"https://codeload.github.com/mwja/py18n/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwja%2Fpy18n/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28561841,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T03:31:16.861Z","status":"ssl_error","status_checked_at":"2026-01-19T03:31:15.069Z","response_time":67,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["discord","discord-py","fallback","i18n","i18n-python","internationalization","language","py18n","python","python-i18n","python3"],"created_at":"2025-02-11T15:24:42.048Z","updated_at":"2026-01-19T04:32:46.348Z","avatar_url":"https://github.com/mwja.png","language":"Python","readme":"\u003c!--\n Copyright (C) 2021 Avery\n \n This file is part of py18n.\n \n py18n is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n \n py18n is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n GNU General Public License for more details.\n \n You should have received a copy of the GNU General Public License\n along with py18n.  If not, see \u003chttp://www.gnu.org/licenses/\u003e.\n--\u003e\n\n# Py18n\nThis is a open sourced version of the internal internationalization engine used for [Kolumbao](https://kolumbao.com/).\n\n[![](https://img.shields.io/pypi/v/py18n.svg)](https://pypi.org/project/Py18n/)\n[![](https://img.shields.io/pypi/implementation/py18n.svg)](https://pypi.org/project/Py18n/)\n\n\n## Installation\nTo install the package to your Python installation, clone the repository locally then run the following command in the repository's directory\n```bash\npy setup.py install\n```\n\nYou can now use the library!\n\n## Usage\n\n### Setting up languages\nA language can be initialized like this:\n```python\nfrench = Language(\"French\", \"fr\", {\n    \"hello\": \"Bonjour\",\n    \"goodbye\": \"Au revoir\",\n    \"francais\": \"Français\"\n})\n```\n\nBut you may want to store languages seperately and create them as follows:\n```python\nimport json\nfrench = Language(\"French\", \"fr\", json.load(open(\"fr.json\")))\n```\n\n### Base I18n class\nWhen setting up the i18n class, we need to setup our languages and declare a fallback language:\n```python\ni18n = I18n([\n    Language(\"English\", \"en\", {\n        \"hello\": \"Hello\",\n        \"goodbye\": \"Goodbye\",\n        \"english\": \"English\"\n    }),\n    Language(\"French\", \"fr\", {\n        \"hello\": \"Bonjour\",\n        \"goodbye\": \"Au revoir\",\n        \"francais\": \"Français\"\n    }),\n], fallback=\"en\")\n```\n\n`i18n` will now fallback to english if it can't find a translation for other languages.\n```python\n\u003e\u003e\u003e i18n.get_text(\"hello\", \"en\")\n'Hello'\n\u003e\u003e\u003e i18n.get_text(\"hello\", \"fr\")\n'Bonjour'\n\u003e\u003e\u003e # \"english\" is not a listed translation in the French locale, so we revert to english\n\u003e\u003e\u003e i18n.get_text(\"english\", \"fr\")\n'English'\n\u003e\u003e\u003e # However we can make it not fallback, but this will throw an error if the translation isn't found\n\u003e\u003e\u003e i18n.get_text(\"english\", \"fr\", should_fallback=False) \nTraceback (most recent call last):\n  ...      \npy18n.i18n.InvalidTranslationKeyError: 'Translation foo not found for en!'\n```\n\n### Discord\nFor Discord.py, we can use the extension `py18n.extension.I18nExtension`. Setup your bot as you would usually, and then run `i18n.init_bot` as follows.\n\n```python\nfrom discord.ext import commands\nfrom py18n.extension import I18nExtension\n\n# Make our bot\nbot = commands.Bot(\"prefix\")\n\n# Setup similarly to the usual class\ni18n = I18nExtension([\n    Language(\"English\", \"en\", {\n        \"hello\": \"Hello\",\n        \"goodbye\": \"Goodbye\",\n        \"english\": \"English\"\n    }),\n    Language(\"French\", \"fr\", {\n        \"hello\": \"Bonjour\",\n        \"goodbye\": \"Au revoir\",\n        \"francais\": \"Français\"\n    }),\n], fallback=\"en\")\n\n# Setup the bot by giving it a function to get the user's locale.\n# This could potentially refer to a database or other file.\n# Anything you want!\n# Otherwise, it will always be the fallback locale.\ndef get_locale(ctx: commands.Context):\n    preferences = {\n       301736945610915852: \"en\"\n    }\n    return preferences[ctx.author.id]\n\n# Set it up!\ni18n.init_bot(bot, get_locale)\n\n@bot.command(pass_context=True)\nasync def hello(ctx):\n    await ctx.send(i18n.contextual_get_text(\"hello\"))\n```\n\nThis is all good, but because of our line `i18n.init_bot(bot, get_locale)`, we can shorten things.\n\nThis function adds a pre-invoke hook that sets the language based on the result of `get_locale`. The `contextually_get_text` function is also exposed as `py18n.extension._`, and it is a `classmethod`.\n\nWe can change it by adding the following import and change our function:\n```python\nfrom py18n.extension import I18nExtension, _\n\n# ...\n\n@bot.command(pass_context=True)\nasync def hello(ctx):\n    await ctx.send(_(\"hello\"))\n```\n\nThere, much tidier!\n- The `_` function considers the current context and uses the correct locale by default.\n- When initializing any `I18nExtension`, as we did earlier, it becomes the default i18n instance. The default instance is used by `_` and `contextually_get_text`.\n\n## Issues\nIf you encounter any problems, check out [current issues](https://github.com/starsflower/py18n/issues) or [make a new issue](https://github.com/starsflower/py18n/issues/new).\n\n## Notes\n- Feel free to contribute! This is released under the GLP-3 license. (If you suggest another license, make an issue suggesting).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmwja%2Fpy18n","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmwja%2Fpy18n","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmwja%2Fpy18n/lists"}