Ejecutar un script de Python dentro de WordPress

19

Tengo una instalación de WordPress para un blog personal y gradualmente estoy transfiriendo todos los pequeños fragmentos web que he escrito a lo largo de los años a las páginas del blog.

Una de esas páginas es http://www.projecttoomanycooks.co.uk/cgi-bin/memory/majorAnalysis.py, que es un simple script de Python que devuelve una lista de palabras; me gustaría incorporar ese comportamiento dentro de una página de WordPress ¿Podría alguien señalarme en la dirección correcta para la forma más fácil de ejecutar un punto de Python dentro de WordPress?

EDITAR: siguiendo la maravillosa respuesta a continuación, he llegado mucho más lejos ... pero desafortunadamente todavía no estoy allí ...

Tengo Python que se ejecuta en el servidor ...

projecttoomanycooks server [~/public_html/joereddington/wp-content/plugins]#./hello.py 
Hello World!

y está en el mismo directorio que el complemento activado ...

El código de Python ... que tiene el siguiente código ...

#!/usr/bin/python
print("Hello World!")

El php:

<?php
/**
 * Plugin Name: Joe's python thing.
 * Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates
 * Description: A brief description of the Plugin.
 * Version: The Plugin's Version Number, e.g.: 1.0
 * Author: Name Of The Plugin Author
 * Author URI: http://URI_Of_The_Plugin_Author
 * License: A "Slug" license name e.g. GPL2
 */
/*from 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;
}
Joe
fuente
1
Si es un script muy simple, creo que lo reescribiría en PHP como un complemento / plantilla de WordPress ;-) Pero en algunos casos la gente usa iframes para incrustar páginas externas.
Birgire
iframe directamente? :]
Jesse
¿Es esto solo un accidente, o su código de Python está realmente mezclado con PHP?
fuxia
Pegué la traza del terminal, con los archivos que se muestran con el comando 'más' ... ordenaré un poco ...
Joe

Respuestas:

20

Puede usar popen()para leer o escribir en un script de Python (esto también funciona con cualquier otro idioma). Si necesita interacción (pasar variables) use proc_open().

Un ejemplo simple para imprimir Hello World! en un complemento de WordPress

Cree el complemento, registre un código corto:

<?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;
}

Ahora puede usar ese shortcode en el editor de publicaciones con [python]o [python file="filename.py"].

Coloque los scripts de Python que desea usar en el mismo directorio que el archivo del complemento. También puede colocarlos en un directorio y ajustar la ruta en el controlador de shortcode.

Ahora cree un script Python complejo como este:

print("Hello World!")

Y eso es todo. Use el shortcode y obtenga esta salida:

ingrese la descripción de la imagen aquí

fuxia
fuente
La respuesta correcta omite que la primera línea del script de Python, al menos en mi caso, debe ser #! / Usr / bin / env python
MikeiLL
1
@MikeiLL Eso depende del sistema del usuario, así que lo dejé fuera deliberadamente.
fuxia
básicamente haciendo un agujero de seguridad. Si puede canalizar a Python, también puede canalizar a cualquier otro proceso y esto se puede usar para escalar más exploits triviales.
Mark Kaplun
3

Seguí el script de ejemplo desde la primera respuesta, pero no obtenía resultados ni errores.

Cambié esta línea:

$handle = popen( __DIR__ . '/' . $data['file'], 'r' );

a esto:

$handle = popen( __DIR__ . '/' . $data['file'] . ' 2>&1', 'r' );

y luego recibí un mensaje de "permiso denegado".

En la consola, corrí

chmod 777 hello.py

refrescó la página y todo funcionó a la perfección.

Este puede ser el problema que Joe estaba viendo arriba. No tengo suficiente representante para hacer un comentario, lo siento. Espero que esto ayude a alguien.

thepotoo
fuente
No otorgue el permiso 777. Simplemente hágalo ejecutable. chmod +x filename.pyhará
Tessaracter
2

Aquí hay una pequeña secuencia de comandos que se utiliza proc_opencomo se indicó anteriormente, para enviar una variable de texto simple a una secuencia de comandos de 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] ); //Reading stdout buffer
    fclose ( $pipes [1] ); //Closing stdout buffer
    fclose ( $pipes [2] ); //Closing stderr buffer

    $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

Se agregaron algunas pruebas en la parte inferior para ver si el archivo Python es rwx. Creo que una mejor manera de enviar argvsería usar fwrite, pero no funcionó para mí siguiendo este tutorial .

Aquí está el script de Python que utilicé. Como se señaló en los comentarios anteriores, algo como #!/usr/bin/env pythonpuede ser necesario, dependiendo del servidor.

#!/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
MikeiLL
fuente