如何使用PHP和Apache Web服务器正确调用Python Pyro客户端? [英] How do I properly call a Python Pyro client using PHP and Apache web server?
问题描述
我有一个Python3 Pyro4服务器客户端应用程序,从命令行运行时效果很好.
server.py
import Pyro4
@Pyro4.expose
class JokeGen(object):
def __init__(self):
self.jokevar = "Joke"
def joke(self, name):
return "Sorry "+name+", I don't know any jokes."
def main():
Pyro4.Daemon.serveSimple(
{
JokeGen: "example.jokegen"
},
ns = True)
if __name__=="__main__":
main()
client.py
#!/usr/bin/env python3
import Pyro4
import sys
person_to_joke = sys.argv[1]
joke_control = Pyro4.Proxy("PYRONAME:example.jokegen")
print (joke_control.joke(person_to_joke))
问题是我需要使用PHP从Web应用程序运行客户端.
我创建了一个 joke.php
<?php
$command = escapeshellcmd('/full/path/to/client.py SquirrelMaster');
$output = shell_exec($command);
echo $output;
?>
尽管此代码确实有效,但我还是进行了一些非标准的编程以使其正常工作.我复制了我的/home/user/.local (已为用户安装了pyro4模块)的副本,并将其放置在/var/www/中并赋予了所有权到www-data.
sudo chown -R www-data.www-data /var/www/.local
似乎必须有一种更好的方法来完成此操作,而且我很确定,如果我以这种方式离开的话,将来还会有潜在的问题.问题似乎是Pyro4模块需要可供www-data用户使用.所以我的问题是,在运行apache2的Ubuntu linux上,www.data用户可以使用Pyro4模块的正确方法是什么?
编辑-添加
我还尝试了以下操作:
sudo mkdir /var/www/.local
sudo mkdir /var/www/.cache
sudo chown www-data.www-data /var/www/.local
sudo chown www-data.www-data /var/www/.cache
然后运行命令:
sudo -H -u www-data pip3 install pyro4 --user www-data
但这会导致错误找不到符合www-data要求的版本(来自版本:) 找不到与www-data匹配的分布"
看起来像这样的问题 Virtualenv www-data用户可访问,并使用该virtualenv中的pip命令将所有必需的模块安装到该用户中.您可能必须使用一些sudo/chown舞蹈才能正确解决此问题.
另一种方法也许是根本不用打扰python子进程,而是使用 Pyro的HTTP网关.这样,您只需从PHP向本地运行的Pyro http网关进程发出HTTP请求,即可将其转换为正确的Pyro调用.我不了解PHP,但在我看来,向运行在某些本地主机端口上的服务器发出自定义http请求应该很容易.这也可能更快,因为您不必为每个调用都启动python进程.
(edit):似乎是另一个成功的解决方案,其中sudo用于在适当的用户下调用pip,从而将库安装到www-data
的.local库中文件夹:
- 创建
/var/www/.local
和/var/www/.cache
文件夹,仅将www-data
权限授予这些文件夹(而不是/var/www
以避免安全问题) - 调用
sudo -H -u www-data pip3 install pyro4
如果是较旧的版本,您可能仍需要在命令中添加 --user
,因为我认为默认情况下,只有最新的pip版本默认安装到用户的lib文件夹中,而不是全局系统python的lib文件夹中.
I have a Python3 Pyro4 server client app that works great when run from command line.
server.py
import Pyro4
@Pyro4.expose
class JokeGen(object):
def __init__(self):
self.jokevar = "Joke"
def joke(self, name):
return "Sorry "+name+", I don't know any jokes."
def main():
Pyro4.Daemon.serveSimple(
{
JokeGen: "example.jokegen"
},
ns = True)
if __name__=="__main__":
main()
client.py
#!/usr/bin/env python3
import Pyro4
import sys
person_to_joke = sys.argv[1]
joke_control = Pyro4.Proxy("PYRONAME:example.jokegen")
print (joke_control.joke(person_to_joke))
The problem is I need to run the client from a web app using PHP.
I have created a joke.php
<?php
$command = escapeshellcmd('/full/path/to/client.py SquirrelMaster');
$output = shell_exec($command);
echo $output;
?>
While this code does actually work I did some non-standard hacking to make it work. I took a copy of my /home/user/.local (where the pyro4 modules have been installed for user) and placed it in /var/www/ and gave ownership to www-data.
sudo chown -R www-data.www-data /var/www/.local
It seems like there must be a better way to do this and I'm pretty sure there will be potentially issues in the future if I leave things this way. The issues seems to be that the Pyro4 modules need to be available for the www-data user. So my question is, What is the proper way to make Pyro4 modules available to the www-data user on Ubuntu linux running apache2?
EDIT - ADDITION
I also tried doing the following:
sudo mkdir /var/www/.local
sudo mkdir /var/www/.cache
sudo chown www-data.www-data /var/www/.local
sudo chown www-data.www-data /var/www/.cache
Then run the command:
sudo -H -u www-data pip3 install pyro4 --user www-data
But this results the error "Could not find a version that satisfies the requirement www-data (from versions: ) No matching distribution found for www-data"
Looks a bit like this question https://superuser.com/questions/646062/granting-write-permissions-to-www-data-group
I wanted to suggest using the PYTHONPATH environment variable to point to a library install location readable by the www-data user where you'd copy the python modules it needs to acces, but I think this is considered bad form nowadays.
Probably best is to create a Python Virtualenv that is accessible for the www-data user and install all required modules into that, using the pip command from that virtualenv. You may have to use some sudo/chown dance to get this right still.
Another way perhaps is to not bother with calling a python subprocess at all, but use Pyro's HTTP gateway. That way you can simply do a HTTP request from PHP to a locally running Pyro http gateway process, which will translate it into a proper Pyro call. I don't know PHP but it seems to me that it should be easy to make a custom http request to a server running on some localhost port. This may be faster as well because you're not starting up python processes for every call.
(edit): another succesfully working solution seemed to be the following, where sudo is used to invoke pip under the appropriate user, letting it install the library into www-data
's .local library folder:
- create
/var/www/.local
and/var/www/.cache
folders, givingwww-data
permissons to these folders only (and not/var/www
to avoid security issues) - invoke
sudo -H -u www-data pip3 install pyro4
You may still need to add--user
to the pip command if it's an older version, because I think that only recent pip versions install to the user's lib folder by default instead of to the global system python's lib folder.
这篇关于如何使用PHP和Apache Web服务器正确调用Python Pyro客户端?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!