feat: mark core and api user-facing strings for translation - #602
feat: mark core and api user-facing strings for translation#602hamza-56 wants to merge 1 commit into
Conversation
Wraps request-time literals in _() and converts f-strings to translated str.format templates across auth, permissions, plugins, llm, whitelist, and the verification email, so they render in the request locale negotiated by LocaleMiddleware. UserPluginResponse.for_plugin becomes the rendering boundary for the gettext_noop-marked frontend metadata. Machine-read codes (expired_token), operator-facing configuration errors, audit records, and internal invariants deliberately stay English. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@claude-review |
|
Claude finished @hamza-56's task in 3m 41s —— View job Review — PR #602 · mark core & api strings for translation
Solid, well-scoped mechanical PR. The marking patterns follow the i18n guide precisely, English output is preserved, and the risky bits (f-string → What's done well
Suggestions (non-blocking)Low — untested Low — empty-msgid gotcha in Low — confirm intent in Consideration — localized operator logs. Translating domain-exception messages at raise time means VerdictApprove-worthy from a review standpoint (I can't formally approve). No correctness or security concerns; the notes above are polish. I was unable to execute the test suite in this sandbox (network/DB commands are blocked here), so I relied on static analysis — your reported |
| """ | ||
| display = get_plugin_display_info(plugin_name) | ||
| if display is not None: | ||
| display = DisplayInfo(translate(display.display_name), translate(display.description), display.icon) |
There was a problem hiding this comment.
Minor edge case: translate() is gettext, and GNUTranslations.gettext("") returns the catalog's header metadata rather than "" (the classic empty-msgid gotcha). DisplayInfo.description is a required str with no default, so a plugin registering DisplayInfo("Name", "") would serialize the PO header as its description under a non-English locale. Very low likelihood (no real plugin ships an empty description), but a cheap guard avoids it — only translate when the source string is non-empty.
Non-blocking — flagging for awareness.
abdulrafey1
left a comment
There was a problem hiding this comment.
fix the merge conflicts, rest looks good
Part of: Sparkth UI, emails, API errors, and AI-generated content are English-only
Second layer of the i18n stack (#601 → #602 → #603 → #604 → #606 → #607).
What
Marks the user-facing strings owned by core, the API layer, and the services for translation, so API error details, domain-exception messages, and the verification email render in the request locale negotiated by
LocaleMiddleware.Changes
HTTPExceptiondetails in_()across auth, user, user-plugins, file-parser, and llm routes; f-strings become translatedstr.formattemplatesUserPluginResponse.for_pluginbecomes the rendering boundary for thegettext_noop-marked frontend metadata (DisplayInfo/SidebarEntry)_(), assembled from per-sentence templatesAccept-Language, translated plugin metadata, exception templates, email content)How to Test
uv run pytest tests/api/v1/test_auth.py tests/api/v1/test_list_user_plugins.py tests/permissions/test_exception_messages.py tests/services/test_email_verification.pyuv run pytest(1757 passed on this layer)make mypyandmake lint.backendare cleanNotes
Deliberately not marked: machine-read codes (
expired_token,email_not_verified), auditerror_detailrecords, operator-facing configuration errors, and internal invariants ("is not persisted"). English output is unchanged until catalogs ship in #604.This PR description was written with the assistance of an LLM (Claude).