Skip to main content

starlette-i18n

Request-safe gettext localization and locale negotiation for Starlette applications.

Requirements

  • Python 3.11+ (CI validates Python 3.11, 3.12, 3.13, and 3.14)
  • Starlette newer than 1.2.0 and below 2.0

Install

uv add starlette-i18n
pip install starlette-i18n

Quick start

Compile gettext catalogs before starting the application, then load them once:

from starlette.applications import Starlette
from starlette.responses import PlainTextResponse

from starlette_i18n import LocaleMiddleware, TranslationCatalog, gettext

catalog = TranslationCatalog.load("locales", domain="messages", default_locale="en")
app = Starlette()
app.add_middleware(LocaleMiddleware, catalog=catalog)


async def homepage(request):
    return PlainTextResponse(gettext("Success"))


app.add_route("/", homepage)

The selected Locale is also available as request.state.locale. The public translation helpers are gettext, ngettext, gettext_lazy, and get_locale.

Locale selection

LocaleMiddleware selects one catalog for each HTTP request in this order:

  1. A valid configured locale cookie (locale by default).
  2. The request's Accept-Language header.
  3. The catalog's configured default locale.

Header values are parsed as a q-weighted priority list and resolved using RFC 4647 lookup. Exact complex tags work: a zh-CN request selects a zh_CN catalog directory, while pt-BR can fall back to a pt catalog. Invalid values and q=0 entries are ignored. A wildcard falls back to the configured default when no explicit supported locale matches.

Responses include Content-Language. The middleware adds configured selection inputs (Cookie and Accept-Language by default) to Vary so shared caches do not serve the wrong representation.

Configure another cookie name, or disable cookies entirely:

app.add_middleware(LocaleMiddleware, catalog=catalog, cookie_name="language")
app.add_middleware(LocaleMiddleware, catalog=catalog, cookie_name=None)

ASGI and Jinja safety

The active locale is stored in a ContextVar and is reset after every request, including exceptions. Concurrent requests therefore cannot leak translations into one another.

Do not install gettext functions into a shared Jinja environment per request: Jinja's installation mutates global environment state. Pass a request-local callable instead:

html = template.render(request=request, _=request.state.locale.translate)

Then use {{ _("Success") }} in the template. See examples/jinja_app.py.

Examples

uv run --with uvicorn examples/basic_usage.py
uv run --with 'uvicorn[standard]' uvicorn examples.uvicorn_runner:app --reload
uv run --with gunicorn --with uvicorn gunicorn -c examples/gunicorn_conf.py examples.gunicorn_runner:app
curl -H 'Accept-Language: ru' http://127.0.0.1:8000/

Migrating from 2.x

3.0 is a breaking release. It requires Python 3.11+, moves the package to src/, uses pyproject.toml and uv, and replaces LocaleDefaultMiddleware, LocaleFromCookieMiddleware, LocaleFromHeaderMiddleware, and the old ordering-dependent LocaleMiddleware with the single LocaleMiddleware shown above. Load catalogs with TranslationCatalog.load() instead of load_gettext_translations().

Further documentation

Development

uv sync --all-groups
make lint
make test
make build

License

starlette-i18n is distributed under the Apache License 2.0. Report vulnerabilities through the security policy.

Metadata

Release files for starlette-i18n 3.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for starlette-i18n 3.1.0
File Size Uploaded
starlette_i18n-3.1.0.tar.gz 61.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for starlette-i18n 3.1.0
File Interpreter ABI Platform
starlette_i18n-3.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 71.0 kB

Release files / starlette_i18n-3.1.0.tar.gz

Download URL starlette_i18n-3.1.0.tar.gz
Size 61.8 kB
Tags Source
SHA-256 checksum
How to use checksums
647711f03db069b0698c0ef3df35caec4921be39de6c123064e0600859fc7f2e
BLAKE2b-256 checksum
How to use checksums
319d3480729e3cd7babbac2cc7fbc75e4674fa72b99813ae7ba6c4c97769774e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / starlette_i18n-3.1.0-py3-none-any.whl

Download URL starlette_i18n-3.1.0-py3-none-any.whl
Size 9.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b80814e0f4e2b36b70713cd3e8aece9abae8629e6e71e8e0c364484dd28bab99
BLAKE2b-256 checksum
How to use checksums
6b069a1ef1faa38bb4d4670be829d41cde249e0d4908163c5243dfe8bf22b222
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

3.1.0 This release

2 release files

3.0.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.0.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.4.0

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page