1. 介绍

上一篇文章分享了 Vue3 如何如何接入 i18n 实现国际化多语言,这里继续和大家分享 Flask 后端如何接入 i18n 实现国际化多语言。

用户请求 API 的多语言化其实有两种解决方案:

  1. 后端返回:"USER_ERROR"  => 前端渲染:"用户错误"
  1. 后端接收请求中 "Accept-Language" 信息为 "zh-CN" => 后端返回:"用户错误" => 前端渲染:"用户错误"



这里我们采用的是第二种方案,也就是后端直接处理 i18n 逻辑。

对于 Flask 我们常用 flask-babel,这个包对于将原本单语言的程序转为国际化多语言非常友好,我们只要用 gettext() 包裹我们原来的文本:

@api.route("/", methods=["GET"])
def info():
return jsonify({"msg": gettext("欢迎访问 Githubstar API 服务器.")}), 200

然后工具就可以自动生成翻译文件,我们只要编辑不同语言的翻译文件就可以了:

#: githubstar_api/api.py:39
msgid "欢迎访问 Githubstar API 服务器."
msgstr "Welcome to the Githubstar API server."

2. 基本实现



本文以 GithubStar.Pro 后端的实现为例进行介绍。

要将 flask-babel 引入项目,这里首先安装 flask-babel:

pip install flask-babel

如果你开发包的话,这个依赖也要加入到项目依赖中。

然后,在 Flask 初始化时安装 Babel 插件:

from flask import Flask
from flask_babel import Babel app = Flask('githubstar_api')
babel = Babel(app)

如果你需要使用工厂模式初始化你的 Flask 实例,可以用:

from flask import Flask
from flask_babel import Babel app = Flask('githubstar_api')
babel = Babel() def init_app():
babel.init_app(app)

然后,将你的所有业务相关的文字都包裹上 gettext():

return (
jsonify(
{"errors": [gettext('用户 "%(username)s" 已被封禁.', username=user.username)]}
),
400,
)

句子中的变量,可以用 %()s 包裹,其中 s 代表字符串。

更多的使用方法详见:文档

然后,在项目根目录新建一个 babel.cfg:

[python: githubstar_api/**.py]

​这里的路径应该指向你的所有需要国际化的代码文件。

然后,运行命令,将这些文件中被 gettext() 包裹的文字都提取到模板文件中:

pybabel extract -F babel.cfg -o messages.pot .

这会在项目根目录生成 messages.pot 文件,可以看到包含了所有需要翻译的文本:

#: githubstar_api/api.py:39
msgid "欢迎访问 Githubstar API 服务器."
msgstr ""

随后,我们需要开始进行一个新语言的翻译,例如英文,运行命令:

pybabel init -i messages.pot -d ./githubstar_api/res/locales -l en

我们就可以在 ./githubstar_api/res/locales 中看到生成了一个 en 文件夹, 里面有 messages.po 文件,这就是一个空的全新的翻译文件了。

这里我们可以将文本内容全部发送给 OpenAI GPT4 或者是 Github Copilot,告诉他:

这是一个 babel 翻译文件,请根据中文翻译为英文并填入msgstr中,以下是文件内容:

...

AI 可以很好地完成翻译任务,只需要检查并稍微调整即可。

完成翻译后,需要将翻译文件编译为二进制文件:

pybabel compile -d ./githubstar_api/res/locales

这样,locale 文件夹中的所有语言都被翻译,生产了 messages.po 文件。

现在,文件目录应该是这样的:

./githubstar
├── githubstar_api
│ ├── __init__.py
│ ├── res
│ │ ├── __init__.py
│ │ └── locales
│ │ └── en
│ │ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
│ ├── api.py
│ ├── app.py
│ └── cli.py
├── messages.pot
└── pyproject.toml

所以,用加载包数据的方式导入:

import importlib.resources as pkg_resources

from . import res

traversable = pkg_resources.files(res)
with pkg_resources.as_file(traversable) as path:
babel.init_app(
app,
default_translation_directories=str(path / "locales"),
)

接下来,我们需要设定,需要检测请求的 Accept-Language,以下就是完整的 app.py 文件:

from flask import Flask, request
from flask_babel import Babel app = Flask("githubstar_api")
babel = Babel() def get_locale():
return request.accept_languages.best_match(["zh_CN", "en"]) def init_app():
traversable = pkg_resources.files(res)
with pkg_resources.as_file(traversable) as path:
babel.init_app(
app,
default_translation_directories=str(path / "locales"),
locale_selector=get_locale,
default_locale="zh_CN",
)

这样,就实现了 Flask API 后端根据请求的 Accept-Language 自动调整返回值的语言了。

注意:如果你要将翻译文件包含在输出的 Python 包中,你需要调整你的 pyproject.toml:

[tool.setuptools]
zip-safe = false
include-package-data = true [tool.setuptools.packages]
find = {namespaces = false} [tool.setuptools.package-data]
"githubstar_api.res" = ["**/*.mo"]

3. 与 Vue3 前端联动

接下来,需要让前端发送的请求以当前语言作为 Accept-Language。

这里,我们以用户操作相关 API 为例,这里我们使用一个 Pinia Store 来管理所有的用户状态和相关请求。API 请求用 axios 发送,详见开源仓库:Github: GithubStarPro

export const useUserStore = defineStore('user', {
state: () => {
const { locale } = useI18n({ inheritLocale: true, useScope: 'local' });
const user = useStorage<User | null>('user', null, undefined, { serializer: StorageSerializers.object });
const api = axios.create({ baseURL: import.meta.env.VITE_API_URL });
api.interceptors.request.use((config) => {
config.headers['Accept-Language'] = locale.value;
if (user.value && user.value.token) {
config.headers.Authorization = `Bearer ${user.value.token.token}`;
}
return config;
});
},
actions: {
login(username: string, password: string) {
const payload = {
username: username,
password: password,
};
this.api.post('/user/login', payload)
.then((response) => {
this.user = response.data;
});
}
},
});

​我们重点关注的是:

api.interceptors.request.use((config) => {
config.headers['Accept-Language'] = locale.value;
if (user.value && user.value.token) {
config.headers.Authorization = `Bearer ${user.value.token.token}`;
}
return config;
});



这一块是在 axios 对象上定义了一个预处理器,也就是在每个发送的请求上加入当前的 locale,如果用户已登录,还需要加入用户的 Token,这里的 locale 参见我的上一篇文章:Vue3 如何如何接入 i18n 实现国际化多语言

这样,就实现了在每次发送请求时候自动发送当前的 locale。

这样我们就实现了前后端的国际化,如果这篇文章对您有帮助的话,欢迎关注我,我会分享更多全栈网页开发的实用经验。

您也可以关注 Github 互赞平台 GithubStar.Pro,快速提升您的项目关注度。

感谢阅读!

Flask API 如何接入 i18n 实现国际化多语言的更多相关文章

  1. Flask 教程 第十三章:国际化和本地化

    本文翻译自The Flask Mega-Tutorial Part XIII: I18n and L10n 这是Flask Mega-Tutorial系列的第十三部分,我将告诉你如何扩展Microbl ...

  2. 阿里云API网关(2)开放 API 并接入 API 网关

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  3. Go Revel - i18n(国际化)

    ##Messages `Messages`信息是对内容提供翻译的外部文本片段.revel提供了组织每一种语言文本片段的message文件.自动区域查找.基于cookie覆盖的消息嵌套和参数. 术语表: ...

  4. php gettext方式实现UTF-8国际化多语言(i18n)

    php gettext方式实现UTF-8国际化多语言(i18n) 一.总结 一句话总结: 二.php gettext方式实现UTF-8国际化多语言(i18n) 近 来随着i18n(国际化)的逐渐标准化 ...

  5. yii2 api接口 实现国际化多语言设置

    1) 在 /config/main.php 下添加如下代码: 'components' => [ 'language' => 'zh-CN', 'i18n' => [ 'transl ...

  6. 实验6、Flask API使用示例和拓展

    实验介绍 1. 实验内容 Flask 提供了多种API拓展,本节我们主要学习基于RESTful的Flask应用程序设计 2. 实验要点 学习和掌握多种RESTful的设计模式 3.实验环境 Cento ...

  7. WPF 实际国际化多语言界面

    前段时候写了一个WPF多语言界面处理,个人感觉还行,分享给大家.使用合并字典,静态绑定,动态绑定.样式等东西 效果图 定义一个实体类LanguageModel,实际INotifyPropertyCha ...

  8. [Spring]Spring Mvc实现国际化/多语言

    1.添加多语言文件*.properties F64_en_EN.properties详情如下: F60_G00_M100=Please select data. F60_G00_M101=Are yo ...

  9. react-intl 实现 React 国际化多语言

    效果预览 React Intl 国际化步骤 创建国际化资源文件 根据语言获取国际化资源 引入 react-intl 的 local data 创建 LocaleProvider 国际化上下文组件 创建 ...

  10. iOS 国际化多语言设置 xcode7

    iOS 国际化多语言设置 方式一: 1. 在storyboard中创建好UI,然后在 project 里面  Localizables 栏目里面,添加你需要的语言:默认是Englist; 比如这里我添 ...

随机推荐

  1. 前端 PM 分享:PM 需要做的事情

    个人经验分享 PM PM( Project Manager ) PM( Product Manager ) 一.什么情况下需要前端担任 PM? 在我之前遇到的项目中,大多数项目的 PM 是由后端/产品 ...

  2. MegaCli64查看磁盘损坏,错误个数统计情况

    如下,两个命令,是磁盘濒临崩坏,比如存在扇区损坏之类的事情发生.咨询的浪潮热线,报sn.他们的临界值是500,我们监控脚本是200告警.Predictive Failure Count 这个的数字比M ...

  3. go高并发之路——go语言如何解决并发问题

    一.选择GO的原因 作为一个后端开发,日常工作中接触最多的两门语言就是PHP和GO了.无可否认,PHP确实是最好的语言(手动狗头哈哈),写起来真的很舒爽,没有任何心智负担,字符串和整型压根就不用区分, ...

  4. rocketMQ 文章

    10 DefaultMQPushConsumer 使用示例与注意事项.md (lianglianglee.com) 手动回滚事务: (29条消息) spring 控制事务回滚重要知识点:Transac ...

  5. 深入理解 Swoole 的底层加载原理

    首发原文链接:深入理解 Swoole 的底层加载原理 PHP 扩展加载 我们从 php-src/sapi/cli/php_cli.c:1159 文件的入口函数 int main(int argc, c ...

  6. Swoole 源码分析之 TCP Server 模块

    首发原文链接:https://mp.weixin.qq.com/s/KxgxseLEz84wxUPjzSUd3w 大家好,我是码农先森. 今天我们来分析 TCP Server 模块 的实现原理,下面这 ...

  7. @synchronized(self) 加锁引起的Crash

    一.最近米家App进入前台的时候上报上来一个Crash {"app_name":"MiHome","timestamp":"201 ...

  8. H264 H265 分析小工具

    1.在调试 H264 H265 编码的流数据的时候,有时候需要打印没有nalu的类型和数量,自己写了一个小工具 使用方式: p.p1 { margin: 0; font: 22px Menlo; co ...

  9. 我有点想用JDK17了

    大家好呀,我是summo,JDK版本升级的非常快,现在已经到JDK20了.JDK版本虽多,但应用最广泛的还得是JDK8,正所谓"他发任他发,我用Java8". 其实我也不太想升级J ...

  10. 使用 Hugging Face 推理终端搭建强大的“语音识别 + 说话人分割 + 投机解码”工作流

    Whisper 是当前最先进的开源语音识别模型之一,毫无疑问,也是应用最广泛的模型.如果你想部署 Whisper 模型,Hugging Face 推理终端 能够让你开箱即用地轻松部署任何 Whispe ...