Возможная ошибка импорта для pandas и matplotlib при вызове Python3 через PHPshell_exec.Php

Кемеровские программисты php общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Возможная ошибка импорта для pandas и matplotlib при вызове Python3 через PHPshell_exec.

Сообщение Anonymous »

Я испытываю странное поведение при попытке выполнить два разных скрипта Python 3 с помощью функции PHP Shell_exec(). Первый скрипт Python в PHP вызывается следующим образом:

Код: Выделить всё

$jsondatash = escapeshellarg($jsondata);
// Execute the python script with the JSON data
$resultpy = shell_exec("/usr/bin/python3 /var/www/testsite/py/script1.py 2>&1 $jsondatash");
Я экранирую некоторые данные json ($jsondatash) и запускаю функцию Python (script1.py) для этих данных через shell_exec(). Результат рабочего процесса Python сохраняется в массиве PHP $resultpy. Тестовый скрипт Python выглядит следующим образом:

Код: Выделить всё

from collections import OrderedDict
import sys, json
import scipy
import scipy.cluster.hierarchy as sch
import pandas as pd
import matplotlib

# Load the data that PHP sent
try:
data = json.loads(sys.argv[1], object_pairs_hook=OrderedDict)

except (ValueError, TypeError, IndexError, KeyError) as e:
print (json.dumps({'error': str(e)}))
sys.exit(1)

print (json.dumps(data))
Он просто читает данные и отправляет их обратно в PHP через оболочку. Однако в результате я получаю обратно пустой объект, что указывает на то, что код Python 3 не может быть выполнен. Это журнал ошибок Apache2:

Код: Выделить всё

PHP Fatal error: Uncaught TypeError: array_keys(): Argument #1 ($array) must be of type array, null given
Нет информации об ошибке, специфичной для Python, только ошибка для пустого массива в PHP. Когда я комментирую pandas и matplotlib из тестового скрипта Python

Код: Выделить всё

from collections import OrderedDict
import sys, json
import scipy
import scipy.cluster.hierarchy as sch
#import pandas as pd
#import matplotlib

# Load the data that PHP sent
try:
data = json.loads(sys.argv[1], object_pairs_hook=OrderedDict)

except (ValueError, TypeError, IndexError, KeyError) as e:
print (json.dumps({'error': str(e)}))
sys.exit(1)

print (json.dumps(data))
я могу успешно запустить сценарий через shell_exec(). Таким образом, при выполнении сценария Python через PHP должна возникнуть какая-то ошибка загрузки обеих библиотек Python 3.
То же самое поведение я испытываю при записи данных json в PHP в файл ( inputfile.json), чтение файла на Python, запись данных на Python в другой файл (outputfile.json) и чтение этого файла обратно в PHP. Это PHP-код:

Код: Выделить всё

$jsondata = fopen('/var/www/testsite/files/inputfile.json', 'w');
fwrite($jsondata, $data);
fclose($jsondata);

shell_exec("/usr/bin/python3 /var/www/testsite/py/script2.py 2>&1");
$resultpy = file_get_contents('/var/www/testsite/files/outputfile.json');
Это соответствующий код Python script2.py:

Код: Выделить всё

from collections import OrderedDict
import sys, json
import scipy
import scipy.cluster.hierarchy as sch
import pandas as pd
import matplotlib

# Load the data from json file
try:
with open('/var/www/testsite/files/inputfile.json', 'r') as inputfile:
data = json.load(inputfile, object_pairs_hook=OrderedDict)
except (ValueError, TypeError, IndexError, KeyError) as e:
print (json.dumps({'error': str(e)}))
sys.exit(1)

# write data to json outputfile
with open('/var/www/testsite/files/outputfile.json', 'w') as outputfile:
json.dump(data, outputfile)
При выполнении кода Python непосредственно в оболочке

Код: Выделить всё

/usr/bin/python3 /var/www/testsite/py/script2.py 2>&1
, я получаю ожидаемый результат, но при выполнении кода Python на PHP с использованием оболочки_exec() выходной файл outputfile.json пуст. Опять же, если я удалю панды и matplotlib из сценария Python, он также успешно запустится через PHP Shell_exec().
Эти тесты показывают следующее:
(1) Оба сценария Python могут быть выполнены с помощью PHPshell_exec(), но только если я удалю загрузку pandas и matplotlib из сценариев Python.
(2) Загрузка pandas и matplotlib сама по себе не является проблемой, поскольку я могу выполнить Python script2.py, включая обе библиотеки, непосредственно в оболочке и получить ожидаемый результат.
Почему я могу запустить точно такой же код Python на Apache2 непосредственно в оболочке, но не через Shell_exec() в PHP? Судя по моему тесту, похоже, что это связано с тем, что как pandas, так и matplotlib не могут загрузить и завершить выполнение скриптов Python.
Изменить:
Версия Python3 — 3.8. 10, версия PHP — 8.2.8, и это вывод после установки pandas и matplotlib:

Код: Выделить всё

pip install pandas
> Successfully installed pandas-2.0.3 python-dateutil-2.8.2 pytz-2023.3 tzdata-2023.3
pip install matplotlib
> Successfully installed contourpy-1.1.0 cycler-0.11.0 fonttools-4.40.0 importlib-resources-6.0.0
> kiwisolver-1.4.4 matplotlib-3.7.2 packaging-23.1 pillow-10.0.0 pyparsing-3.0.9 zipp-3.15.0
Edit2: Мне было интересно, расположены ли scipy, который можно загрузить, и pandas, который не загружается, по одному и тому же пути, и это действительно так:

Код: Выделить всё

Name: scipy
Version: 1.10.1
Location: /home/ubuntu/.local/lib/python3.8/site-packages

Name: pandas
Version: 1.5.3
Location: /home/ubuntu/.local/lib/python3.8/site-packages
Я протестировал старую версию pandas (v.1.5.3 – см. выше) и теперь установил текущую версию v.2.0.3. Оба завершают скрипт Python при импорте. Все дополнительные пакеты, необходимые пандам, установлены.

Код: Выделить всё

Name: pandas
Version: 2.0.3
Location: /home/ubuntu/.local/lib/python3.8/site-packages
Системный путь Python 3:

Код: Выделить всё

['', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/home/ubuntu/.local/lib/python3.8/site-packages', '/usr/local/lib/python3.8/dist-packages', '/usr/lib/python3/dist-packages']
Edit3: Я обнаружил, что следующий метод (https://stackoverflow.com/a/44128762/8008652) позволяет мне получить ошибку Python 3 в PHP и распечатайте его в формате html:

Код: Выделить всё

exec('/usr/bin/python3 /var/www/testsite/py/script2.py 2>&1', $output, $return_var);
if ($return_var>0) {
var_dump($output);
}
Это ошибка Python 3:

Код: Выделить всё

 array(14) { [0]=> string(34) "Traceback (most recent call last):" [1]=> string(77) " File "/var/www/testsite/py/script2.py", line 6, in " [2]=> string(23) " import pandas as pd" [3]=> string(80) " File "/usr/lib/python3/dist-packages/pandas/__init__.py", line 55, in " [4]=> string(33) " from pandas.core.api import (" [5]=> string(79) " File "/usr/lib/python3/dist-packages/pandas/core/api.py", line 5, in " [6]=> string(44) " from pandas.core.arrays.integer import (" [7]=> string(92) " File "/usr/lib/python3/dist-packages/pandas/core/arrays/__init__.py", line 10, in " [8]=> string(53) " from .interval import IntervalArray # noqa: F401" [9]=> string(92) " File "/usr/lib/python3/dist-packages/pandas/core/arrays/interval.py", line 38, in " [10]=> string(60) " from pandas.core.indexes.base import Index, ensure_index" [11]=> string(89) " File "/usr/lib/python3/dist-packages/pandas/core/indexes/base.py", line 74, in " [12]=> string(49) " from pandas.core.strings import StringMethods" [13]=> string(139) "ImportError: cannot import name 'StringMethods' from 'pandas.core.strings' (/usr/lib/python3/dist-packages/pandas/core/strings/__init__.py)" }
Как я и подозревал из своих предыдущих тестов, это ошибка импорта, связанная с библиотекой pandas (Ошибка импорта: невозможно импортировать имя «StringMethods» из «pandas.core.strings»).

Подробнее здесь: https://stackoverflow.com/questions/768 ... ia-php-she
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Php»