我在使用CentOS 6的Apache服务器上运行WSGI下的Python。python脚本使用名为PyNGL的NCAR库包装器。这个库的目的是从提供的数据生成图形。
我试图使用我的python脚本作为一个web服务连接到web.py,但它有一个直接执行的入口点。
奇怪的是:
当我直接运行脚本时,它按预期工作,并在脚本的目录中生成一个输出图像。然而,当我试图通过web.py控制器(使用完全相同的参数)调用它时,它失败了。
我的apache错误日志包含这个:
warning:GKS:GCLRWK: -- cairo driver error: error opening output file
我猜这可能是权限问题,但我一点也不知道它要输出到哪里。
编辑:我想我已经确认这确实是一个权限错误。我尝试使用相对路径创建文件,得到了类似的错误:
<type 'exceptions.IOError'> at /plot
[Errno 13] Permission denied: 'Output.txt'
这个错误指的是这一行:
with open("Output.txt", "w") as text_file:
text_file.write(str(self.__dict__))
当然,现在我可以为该文本文件指定绝对路径,但不能为PyNGL的图形输出指定绝对路径。是否有一种方法可以确定它试图输出的位置,或者更改默认输出目录?
通常您的应用程序将运行当前工作目录为'/'。Apache用户将无法写入该目录。
在任何web应用程序中,你通常都不应该依赖于它在特定目录下运行,因为不同的web服务器对当前工作目录的行为不同。如果您假设它总是在特定目录中运行,那么您的应用程序本质上是不可移植的。通过更改应用程序的工作目录来解决这个问题通常也是不好的做法,因为在允许多个应用程序在同一进程中运行的托管机制中,如果每个应用程序都试图设置自己的工作目录,它们就会相互干扰。
在读写文件时应该始终使用绝对路径,而不是使用相对路径。为什么说不能使用绝对路径?
也要注意,你的应用程序将作为一个特殊的用户运行,这个用户不能访问目录来创建文件。因此,您需要开放对Apache用户的访问。最佳实践是限制Apache用户可以写入的内容。
既然你正在使用mod_wsgi,一个可行的选择是确保你正在使用mod_wsgi守护模式,当使用WSGIDaemonProcess指令时,设置'home'选项来覆盖委托给该进程的单个WSGI应用程序的当前工作目录。您还可以设置'user'和'group'选项,以使进程作为具有访问目录权限的不同用户运行。