Eseguire uno script Python all'interno di WordPress
Ho un'installazione WordPress per un blog personale e sto gradualmente trasferendo tutti i piccoli elementi web che ho scritto nel corso degli anni in pagine del blog.
Una di queste pagine è http://www.projecttoomanycooks.co.uk/cgi-bin/memory/majorAnalysis.py che è un semplice script Python che restituisce un elenco di parole - vorrei integrare quel comportamento all'interno di una pagina WordPress - qualcuno potrebbe indicarmi il modo più semplice per eseguire un po' di Python all'interno di WordPress?
MODIFICA - seguendo la meravigliosa risposta qui sotto, sono arrivato molto più avanti... ma purtroppo non ancora del tutto...
Ho Python che viene eseguito sul server...
projecttoomanycooks server [~/public_html/joereddington/wp-content/plugins]#./hello.py
Hello World!
ed è nella stessa directory del plugin attivato...
Il codice Python... che ha il seguente codice...
#!/usr/bin/python
print("Hello World!")
Il PHP:
<?php
/**
* Nome Plugin: Lo script Python di Joe.
* URI Plugin: http://URI_Della_Pagina_Che_Descrive_Il_Plugin_e_Aggiornamenti
* Descrizione: Una breve descrizione del Plugin.
* Versione: Numero di Versione del Plugin, es.: 1.0
* Autore: Nome Dell'Autore Del Plugin
* URI Autore: http://URI_Dell_Autore_Del_Plugin
* Licenza: Nome "Slug" della licenza es. GPL2
*/
/*da 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;
}

Puoi utilizzare popen()
per leggere o scrivere in uno script Python (funziona anche con qualsiasi altro linguaggio). Se hai bisogno di interazione (passaggio di variabili) usa proc_open()
.
Un semplice esempio per stampare Hello World! in un plugin WordPress
Crea il plugin, registra uno 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;
}
Ora puoi utilizzare questo shortcode nell'editor degli articoli con [python]
o [python file="nomefile.py"]
.
Inserisci gli script Python che vuoi utilizzare nella stessa directory del file del plugin. Puoi anche metterli in una directory e modificare il percorso nel gestore dello shortcode.
Ora crea uno script Python complesso come questo:
print("Hello World!")
E questo è tutto. Usa lo shortcode e otterrai questo output:

La risposta corretta omette che la prima riga dello script Python, almeno nel mio caso, deve essere #!/usr/bin/env python

@MikeiLL Dipende dal sistema dell'utente, quindi l'ho omesso deliberatamente.

sostanzialmente creando una falla di sicurezza. Se puoi fare il pipe a Python, puoi farlo anche con qualsiasi altro processo e questo può essere usato per ampliare qualsiasi exploit più banale.

@MarkKaplun sì, questa non è una buona idea. Per farlo "correttamente" ci dovrebbe essere l'escape dei comandi in ingresso e l'escape JavaScript+PHP in uscita. Non è un buon modo per sviluppare qualsiasi cosa all'interno di WordPress, a meno che non ci sia un motivo MOLTO specifico per farlo. "I vostri -scienziati- programmatori erano così preoccupati di capire se potevano, che non si sono fermati a pensare se dovessero."

Ciao @MarkKaplun, potrebbe essere la mia mancanza di comprensione di PHP e WordPress. Capisco che non appena è possibile inviare comandi arbitrari a Python, allora sarà possibile eseguire comandi arbitrari sull'host con l'utente sotto cui viene eseguito il processo Python. Ma in questo esempio viene solo effettuata una lettura dalla pipe, quindi non vedo come questo plugin possa essere utilizzato per scrivere effettivamente nella pipe. Inoltre solo le persone che possono effettivamente modificare le pagine WordPress sono in grado di sfruttare questo buco di sicurezza, quindi potrebbe essere una soluzione accettabile per un sito WordPress personale.

@M.D., prima di tutto devi abilitare l'esecuzione fuori da PHP, e a seconda della versione di PHP e del webserver potresti essere in grado di farlo solo come impostazione globale, il che significa che qualsiasi script PHP può eseguire qualsiasi cosa sul sistema. Dal lato Python, qualsiasi script può eseguirlo e sfruttare qualsiasi problema di sicurezza abbia. Potrebbe non essere un grosso problema se solo tu hai il controllo del server e viene installato solo codice verificato, ma anche se le persone fanno il primo, il 99.99% dei siti WordPress non fa il secondo, quindi è meglio evitarlo poiché nessuno può fidarsi di seguire sempre il secondo punto

Il modo corretto per comunicare tra Python e WordPress è impostare un cron su Python e fargli interrogare WordPress per qualsiasi informazione possa aver bisogno. In questo modo mantieni sicuro il lato PHP. È comunque necessario assicurarsi che sia Python a richiedere le informazioni, ma questa è una cosa più banale da fare. Tuttavia, questo tipo di comunicazione asincrona non risolverà la domanda come chiesto dall'OP.

Ho seguito lo script di esempio dalla prima risposta, ma non ottenevo alcun output o errore.
Ho modificato questa riga:
$handle = popen( __DIR__ . '/' . $data['file'], 'r' );
in questa:
$handle = popen( __DIR__ . '/' . $data['file'] . ' 2>&1', 'r' );
e poi ho ricevuto un messaggio "permesso negato".
Sulla console, ho eseguito
chmod 777 hello.py
ho aggiornato la pagina e tutto ha funzionato perfettamente.
Questo potrebbe essere il problema che Joe stava riscontrando sopra. Non ho abbastanza reputazione per lasciare un commento, mi dispiace. Spero che questo possa aiutare qualcuno.

Non impostare il permesso a 777. Rendi semplicemente il file eseguibile. chmod +x filename.py
è sufficiente

Impostare tutto a 777 è molto pericoloso. Fonte: https://superuser.com/questions/1034079/is-it-safe-to-chmod-777-everything

Ecco un piccolo script che utilizza proc_open
come menzionato sopra, per inviare una semplice variabile di testo a uno 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] ); //Lettura del buffer stdout
fclose ( $pipes [1] ); //Chiusura del buffer stdout
fclose ( $pipes [2] ); //Chiusura del buffer stderr
$return_value = proc_close($proc);
echo "<br/>command returned: $return_value<br/>";
}
$application_test = glitch_player_DIR.$application_name;
echo "<br/>Is ".$application_test." executable? ".is_executable($application_test)." ";
echo "readable? ".is_readable($application_test)." ";
echo "writable? ".is_writable($application_test)." ";
} //EOF main/shortcode function
Ho aggiunto alcuni test alla fine per verificare se il file Python ha i permessi rwx
. Penso che un modo migliore per inviare l'argv
sarebbe utilizzare fwrite, ma non funzionava per me seguendo questo tutorial.
Ecco lo script Python che ho utilizzato. Come notato nei commenti sopra, qualcosa come #!/usr/bin/env python
potrebbe essere necessario, dipendendo dal server.
#!/usr/bin/env python
from sys import argv
script, what_he_said = argv
print "This is what you submitted: %s \n \n Isn't that amazing, man? " % what_he_said
