Eseguire uno script Python all'interno di WordPress

27 ott 2013, 15:02:08
Visualizzazioni: 111K
Voti: 22

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;
}
4
Commenti

Se è uno script molto semplice, penso che lo riscriverei semplicemente in PHP come un plugin/template di WordPress ;-) Ma in alcuni casi le persone usano iframe per incorporare pagine esterne.

birgire birgire
27 ott 2013 15:29:19

Incorporarlo direttamente con iframe? :]

Jesse Jesse
27 ott 2013 15:36:22

È solo un errore, o il tuo codice python è davvero mescolato con PHP?

fuxia fuxia
5 nov 2013 19:01:51

Ho incollato la traccia del terminale, con i file visualizzati dal comando 'more'... sistemerò un po'...

Joe Joe
5 nov 2013 23:42:49
Tutte le risposte alla domanda 3
7
26

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:

Esempio di output Hello World

27 ott 2013 15:45:28
Commenti

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

MikeiLL MikeiLL
20 mag 2014 02:28:55

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

fuxia fuxia
20 mag 2014 09:33:33

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.

Mark Kaplun Mark Kaplun
15 ago 2018 08:13:28

@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."

Brian Stinar Brian Stinar
21 gen 2020 00:15:03

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.

Maarten Derickx Maarten Derickx
26 set 2020 14:21:51

@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

Mark Kaplun Mark Kaplun
26 set 2020 22:40:00

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.

Mark Kaplun Mark Kaplun
26 set 2020 22:46:28
Mostra i restanti 2 commenti
2

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.

6 ott 2016 03:14:38
Commenti

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

Trect Trect
25 giu 2019 08:36:00

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

ajinzrathod ajinzrathod
6 mag 2021 18:16:54
0

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
20 mag 2014 02:28:55