У меня есть клиентское приложение 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.
Я создал 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. Итак, мой вопрос: Каков правильный способ сделать модули Pyro4 доступными для пользователя www-data на Ubuntu linux, работающем на apache2?
EDIT – ДОБАВЛЕНИЕ
Я также попытался сделать следующее:
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 не найдено»,
Выглядит немного как этот вопрос https://superuser.com/questions/646062/granting-write-permissions-to-www-data-group
Я хотел предложить использовать переменную среды PYTHONPATH, чтобы указать на место установки библиотеки, которое читается пользователем www-data, где вы скопируете модули python, которые ему нужны для доступа, но я думаю, что это сейчас считается плохой формой.
Наверное, лучше всего создать Python Virtualenv , доступный для пользователя www-data, и установить в него все необходимые модули, используя команду pip из этого virtualenv. Возможно, вам придется использовать какой-нибудь танцевальный танец sudo / chown, чтобы получить это право.
Другим способом, возможно, является не беспокоить вызов подпроцесса python вообще, но использовать HTTP-шлюз Pyro . Таким образом, вы можете просто выполнить HTTP-запрос от PHP к локально запущенному процессу Pyro http gateway, который переведет его в правильный вызов Pyro. Я не знаю PHP, но мне кажется, что было бы легко сделать собственный HTTP-запрос на сервер, работающий на каком-то порту localhost. Это может быть и быстрее, потому что вы не запускаете процессы python для каждого вызова.
(edit) : еще одно успешно работающее решение показалось следующим: где sudo используется для вызова pip под соответствующим пользователем, позволяя ему установить библиотеку в папку .local library www-data
:
/var/www/.local
и /var/www/.cache
папки, предоставляя разрешения только для www-data
(а не /var/www
чтобы избежать проблем с безопасностью) sudo -H -u www-data pip3 install pyro4
Вам все равно нужно добавить --user
в команду pip, если это более старая версия, потому что я думаю, что только последние версии пакетов устанавливаются в папку lib пользователя по умолчанию, а не глобальная папка lib python.