Internationalization for FastAPI, built on standard gettext catalogs.
Documentation: https://fastapi-locale.readthedocs.io
- Picks a locale for every request from a query parameter,
Accept-Languageor a cookie, with RFC 4647 matching and correctContent-LanguageandVaryheaders. - Returns FastAPI's 422 validation errors in the client's language, with correct plural forms.
- Lazy text that works in Pydantic models, response models and
HTTPException.detail. - Dependency injection first:
LocaleDepandTranslatorDep, replaceable in tests. - Lets a dependency switch to the signed-in user's saved language for the rest of the request.
- A command line tool to extract, update, compile and check catalogs in CI.
Status: release candidate. Install it with
pip install --pre fastapi-locale. The engineering documents (requirements, models, architecture, decisions) are in docs/.
from fastapi import FastAPI, HTTPException
from fastapi_locale import LocaleConfig, Localization, TranslatorDep, gettext_lazy
i18n = Localization(
LocaleConfig(default_locale="en", supported_locales=["en", "hi", "de"], catalog_dirs=["locales"])
)
app = FastAPI()
i18n.install(app)
NOT_FOUND = gettext_lazy("Item not found")
@app.get("/items/{item_id}")
def read_item(item_id: int, tr: TranslatorDep) -> dict[str, str]:
if item_id != 1:
raise HTTPException(status_code=404, detail=NOT_FOUND)
return {"name": tr.gettext("Sample item")}A request with Accept-Language: de now gets German text, German validation errors and
Content-Language: de.
fastapi-locale extract # scan the code, write locales/messages.pot
fastapi-locale init --locale hi # start a new language
fastapi-locale update # merge new messages into every .po file
fastapi-locale compile # build .mo files
fastapi-locale check # fail CI when catalogs are stale or brokenSee CONTRIBUTING.md. The engineering documents (requirements, models, architecture, decisions and test plan) are in docs/.
MIT