如何将WSGI中的首选编码设置为UTF8

2024-04-16 11:42:01 发布

您现在位置:Python中文网/ 问答频道 /正文

感觉有点疯狂。我已经用mod_wsgi设置了Apache,但是我无法使编码正常工作。我有:

  • 测试mod_wsgi是否在守护程序模式下运行
  • 阅读Graham Dumpleton's blog post关于为WSGIDaemonProcess指令设置langlocale设置的内容
  • 创建了一个最低限度的测试,似乎可以证明这个问题
# I recompiled the mod_wsgi file to get the Python version correct
sys.version = '3.8.6 (default, Sep 24 2020, 21:54:23) \n[GCC 8.3.0]'
sys.prefix = '/usr/local'
sys.path = ['/usr/local/lib/python38.zip', '/usr/local/lib/python3.8', '/usr/local/lib/python3.8/lib-dynload', '/usr/local/lib/python3.8/site-packages', '/usr/local/src/scorched']

# This seems to be a timing thing? Not sure, but possibly problematic
locale.getlocale() = (None, None)
# This was fixed by setting lang or locale (not sure which)
locale.getdefaultlocale() = ('en_US', 'UTF-8')
sys.getdefaultencoding() = 'utf-8'

# These seem like a problem...
sys.getfilesystemencoding() = 'ascii'
locale.getpreferredencoding(False): 'ANSI_X3.4-1968'

# It's daemon mode
mod_wsgi.process_group = 'cl'

我的WSGI配置如下所示:

    WSGIScriptAlias / /opt/courtlistener/docker/apache/wsgi-configs/python_version_test.py
    WSGIDaemonProcess cl \
      threads=10 \
      processes=64 \
      python-path=/usr/local/lib/python3.8/site-packages/ \
      lang='en_US.UTF-8' \
      locale='en_US.UTF-8'
    WSGIProcessGroup cl
    WSGIApplicationGroup %{GLOBAL}
    WSGIPassAuthorization On

当我登录到服务器并在终端中启动python时,这条线路工作正常,但通过mod_wsgi运行时失败:

from reporters_db import REPORTERS

这行所做的就是导入一个json文件,其中包含一些utf-8内容。以下是该导入背后的代码:

db_root = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(db_root, "data", "reporters.json")) as f:
    REPORTERS = json.load(f, object_hook=datetime_parser)

由于上面的json调用没有指定编码,因此它使用ASCII并失败:

 Traceback (most recent call last):
   File "/opt/courtlistener/docker/apache/wsgi-configs/python_version_test.py", line 6, in <module>
     from reporters_db import REPORTERS
   File "/usr/local/lib/python3.8/site-packages/reporters_db/__init__.py", line 22, in <module>
     REPORTERS = json.load(f, object_hook=datetime_parser)
   File "/usr/local/lib/python3.8/json/__init__.py", line 293, in load
     return loads(fp.read(),
   File "/usr/local/lib/python3.8/encodings/ascii.py", line 26, in decode
     return codecs.ascii_decode(input, self.errors)[0]
 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 441720: ordinal not in range(128)

我如何告诉它(以及我代码库的其他部分)像正常成年人一样使用utf-8


编辑1

也许有一点很重要,我使用以下命令运行apache:

exec apache2ctl -D FOREGROUND "$@"

我认为这将是/etc/apache2/envvars文件的源代码,因此我将以下内容附加到该文件中:

export LANG="en_US.UTF-8"

我尝试将启动命令调整为:

LANG="en_US.UTF-8" exec apache2ctl -D FOREGROUND "$@"

我很有希望,但没有。仍然没有进展


Tags: pathinpymodjsonwsgidblib
1条回答
网友
1楼 · 发布于 2024-04-16 11:42:01

好吧,我通过搜索格雷厄姆·邓普尔顿在互联网上每次提到“郎”这个词的时候,终于找到了答案。最终出现了this thread,其中提到不安装区域设置是可能的。我可以通过在我的Ubuntu Docker映像中运行locale -a来检查这一点,它显示:

locale -a
C
C.UTF-8
POSIX

这就是问题所在mod_wsgi在我请求{}时不知道我在请求什么,而且它也不会抛出错误。将我的设置改为设置为C.UTF-8立即修复了这一问题

我运行的是一个细长的docker映像,所以这一定是我缺少区域设置的原因。我在/etc/default/locale上也没有一个文件,这方面的很多其他答案都提到了这个文件

我以a bug的名义提交了这个文件

相关问题 更多 >