Rularea unui script Python în WordPress
Am o instalare WordPress pentru un blog personal și port treptat toate elementele web mici pe care le-am scris de-a lungul anilor pe paginile blogului.
Una dintre aceste pagini este http://www.projecttoomanycooks.co.uk/cgi-bin/memory/majorAnalysis.py care este un script Python simplu ce returnează o listă de cuvinte - aș dori să încorporez acest comportament într-o pagină WordPress - poate cineva să-mi indice cea mai ușoară modalitate de a rula Python în WordPress?
EDIT - urmând răspunsul excelent de mai jos, am avansat mult... dar din păcate tot nu am ajuns la final...
Am Python care se execută pe server...
projecttoomanycooks server [~/public_html/joereddington/wp-content/plugins]#./hello.py
Hello World!
și este în același director cu plugin-ul activat...
Codul Python... care conține următorul cod...
#!/usr/bin/python
print("Hello World!")
PHP-ul:
<?php
/**
* Plugin Name: Python-ul lui Joe.
* Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates
* Description: O scurtă descriere a Plugin-ului.
* Version: Numărul Versiunii Plugin-ului, ex.: 1.0
* Author: Numele Autorului Plugin-ului
* Author URI: http://URI_Of_The_Plugin_Author
* License: Un nume de licență "Slug" ex. GPL2
*/
/*din http://wordpress.stackexchange.com/questions/120259/running-a-python-scri
pt-within-wordpress/120261?noredirect=1#120261 */
add_shortcode( 'python', 'embed_python' );
function embed_python( $attributes )
{
$data = shortcode_atts(
array(
'file' => 'hello.py'
),
$attributes
);
$handle = popen( __DIR__ . '/' . $data['file'], 'r');
$read = fread($handle, 2096);
pclose($handle);
return $read;
}

Puteți folosi popen()
pentru a citi sau scrie într-un script Python (acest lucru funcționează și cu alte limbaje de programare). Dacă aveți nevoie de interacțiune (transmitere de variabile), folosiți proc_open()
.
Un exemplu simplu pentru a afișa Hello World! într-un plugin WordPress
Creați plugin-ul și înregistrați un shortcode:
<?php # -*- coding: utf-8 -*-
/* Plugin Name: Python embedded */
add_shortcode( 'python', 'embed_python' );
function embed_python( $attributes )
{
$data = shortcode_atts(
[
'file' => 'hello.py'
],
$attributes
);
$handle = popen( __DIR__ . '/' . $data['file'], 'r' );
$read = '';
while ( ! feof( $handle ) )
{
$read .= fread( $handle, 2096 );
}
pclose( $handle );
return $read;
}
Acum puteți utiliza acest shortcode în editorul de postări cu [python]
sau [python file="filename.py"]
.
Puneți scripturile Python pe care doriți să le utilizați în același director cu fișierul plugin-ului. De asemenea, le puteți pune într-un director și ajusta calea în gestionarul shortcode-ului.
Acum creați un script Python complex, precum acesta:
print("Hello World!")
Și asta e tot. Folosiți shortcode-ul și obțineți următorul rezultat:

Răspunsul corect omită faptul că prima linie a scriptului Python, cel puțin în cazul meu, trebuie să fie #!/usr/bin/env python

@MikeiLL Asta depinde de sistemul utilizatorului, așa că am ales să o omit în mod intenționat.

practic creând o breșă de securitate. Dacă poți redirecționa către Python, poți redirecționa către orice alt proces și acest lucru poate fi folosit pentru a escala orice exploatare mai trivială.

@MarkKaplun da, aceasta nu este o idee bună. Pentru a face acest lucru "corect" va trebui să existe mecanisme de evitare a comenzilor la intrare și mecanisme de evitare JavaScript+PHP. Aceasta nu este o modalitate bună de a dezvolta orice în WordPress, decât dacă există un motiv FOARTE specific pentru a face acest lucru. "Oamenii voștri de -știință- programatori erau atât de preocupați dacă pot sau nu, încât nu s-au oprit să se gândească dacă ar trebui."

Salut @MarkKaplun, poate se datorează lipsei mele de înțelegere a PHP și WordPress. Înțeleg că de îndată ce poți trimite comenzi arbitrare către Python, atunci vei putea executa comenzi arbitrare pe gazdă sub utilizatorul sub care rulează procesul Python. Dar în acest exemplu se face doar citire din conductă, așa că nu văd cum acest plugin poate fi folosit pentru a scrie efectiv în conductă. În plus, doar persoanele care pot modifica paginile WordPress pot exploata această vulnerabilitate de securitate, așa că aceasta ar putea fi o soluție acceptabilă pentru un site WordPress personal.

@M.D., mai întâi trebuie să activezi execuția din PHP, iar în funcție de versiunea PHP și serverul web, s-ar putea să poți face acest lucru doar ca setare globală, ceea ce înseamnă că orice script PHP poate executa orice pe sistem. Din partea Python, orice script poate să-l execute și să exploateze orice probleme de securitate pe care le are. Acest lucru poate să nu fie o problemă mare dacă doar tu ai controlul asupra serverului și doar cod verificat este instalat, dar chiar dacă oamenii fac primul lucru, 99,99% dintre site-urile WordPress nu fac al doilea, de aceea este mai bine să fie evitat, deoarece nimeni nu poate avea încredere în sine că va urma permanent al doilea aspect.

modul corect de a comunica între Python și WordPress este să pui un cron pe Python și să-l faci să interogheze WordPress pentru orice informație ar putea avea nevoie. În acest fel menții partea de PHP securizată. Totuși, trebuie să te asiguri că este Python cel care cere informațiile, dar acesta este un lucru mai trivial de făcut. Dar acest tip de comunicare asincronă nu va rezolva întrebarea așa cum a pus-o OP.

Am urmat scriptul exemplu din primul răspuns, dar nu primeam niciun rezultat sau erori.
Am modificat această linie:
$handle = popen( __DIR__ . '/' . $data['file'], 'r' );
în aceasta:
$handle = popen( __DIR__ . '/' . $data['file'] . ' 2>&1', 'r' );
și apoi am primit un mesaj "permission denied".
Pe consolă, am rulat
chmod 777 hello.py
am actualizat pagina și totul a funcționat perfect.
Aceasta poate fi problema pe care o întâmpina Joe mai sus. Nu am suficiente puncte pentru a lăsa un comentariu, îmi pare rău. Sper că acest lucru îi va ajuta pe alții.

Nu seta permisiunea la 777. Doar fă-l executabil. chmod +x filename.py
va fi suficient

A seta totul la 777 este foarte periculos. Sursa: https://superuser.com/questions/1034079/is-it-safe-to-chmod-777-everything

Iată un mic script care folosește proc_open
, așa cum am menționat mai sus, pentru a trimite o singură variabilă text către un script Python:
add_shortcode( 'execute_python', 'execute_python_with_argv' );
function execute_python_with_argv( $attributes ){
$description = array (
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$application_system = "python ";
$application_path .= plugin_dir_path( __FILE__ );
$application_name .= "hello.py";
$separator = " ";
$application = $application_system.$application_path.$application_name.$separator;
$argv1 = '"output to receive back from python script"';
$pipes = array();
$proc = proc_open ( $application.$argv1 , $description , $pipes );
//echo proc_get_status($proc)['pid'];
if (is_resource ( $proc ))
{
echo "Stdout : " . stream_get_contents ( $pipes [1] ); //Citire buffer stdout
fclose ( $pipes [1] ); //Închidere buffer stdout
fclose ( $pipes [2] ); //Închidere buffer stderr
$return_value = proc_close($proc);
echo "<br/>comanda a returnat: $return_value<br/>";
}
$application_test = glitch_player_DIR.$application_name;
echo "<br/>Este ".$application_test." executabil? ".is_executable($application_test)." ";
echo "citibil? ".is_readable($application_test)." ";
echo "scriibil? ".is_writable($application_test)." ";
} //EOF funcția principală/shortcode
Am adăugat câteva teste la final pentru a verifica dacă fișierul Python are permisiunile rwx
. Cred că o metodă mai bună pentru a trimite argv
ar fi folosind fwrite, dar nu a funcționat pentru mine urmărind acest tutorial.
Iată scriptul Python pe care l-am folosit. După cum se menționează în comentariile de mai sus, este posibil să fie necesară o linie precum #!/usr/bin/env python
, în funcție de server.
#!/usr/bin/env python
from sys import argv
script, what_he_said = argv
print "Acesta este ceea ce ai trimis: %s \n \n Nu este uimitor, omule? " % what_he_said
