从Django和单元测试调用时,Python子进程的行为会有所不同

时间:2017-10-05 01:58:18

标签: django python-3.x subprocess mod-wsgi soffice

我的第一次发帖 - 请放轻松我。我无法想出一个总结这个问题的简洁标题。我似乎有一个编解码器问题。

我的基于django的网站调用子进程(soffice)将上传的文档转换为基本文本文件,然后继续对文档中的文本进行一些处理。这一段时间非常漂亮。在我的本地开发机器上,单元测试文件转换仍然完美,完整的django应用程序端到端。在生产服务器上,它曾经工作过,文件转换调用在django应用程序中不再起作用,而在从测试代码运行时它可以正常工作。此行为更改似乎是运行常规服务器更新的结果。

args = ['soffice',
        '--headless',
        '--convert-to',
        'txt:Text',
        '--outdir',
        outDir,
        filePath]

subprocess.call(args)

fo = open(textFilePath, "r")

try:
    docText = fo.read()
except:
    print("Failed to read", textFilePath)
    docText = None

我删除了一些错误检查以简化一点。

当我在生产服务器上运行文件转换代码作为完整django应用程序的一部分时,我可以看到某些特殊字符(例如符号§)变成了垃圾。但是如果我在同一台机器上运行django之外的相同文件转换代码,那些符号就不会被破坏。如上所述,在我的开发机器上,它既可以独立运行,也可以在django内运行。这两台机器的一个区别就是我如何运行django。在本地,它使用django的runserver命令运行。在生产机器上,它使用带有apache的mod_wsgi。我没有看到django或mod_wsgi如何干扰soffice在子进程中所做的事情,但它看起来确实如此。我已经在问题服务器上打开了一个python shell,并运行与上面相同的代码,得到了干净的文本,再加上运行单元测试也能正常工作。

真心感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

如果您使用的是mod_wsgi守护程序模式,请确保设置lang / locale,否则您将从操作系统继承ASCII的默认编码。

这也会传播到子流程。

如果不使用守护进程模式,你真的应该这样做,因为它优于mod_wsgi的嵌入模式。如果使用嵌入模式,则更改lang / locale有点困难,因为必须在Apache启动脚本中完成,如何执行此操作取决于平台和发行版。

答案 1 :(得分:0)

解决方案是使用以下方法升级mod_wsgi:

pip install mod_wsgi --upgrade