Exécuter un script python dans wordpress


19

J'ai une installation WordPress pour un blog personnel et je porte progressivement tous les petits morceaux Web que j'ai écrits au fil des ans sur des pages du blog.

Une de ces pages est http://www.projecttoomanycooks.co.uk/cgi-bin/memory/majorAnalysis.py qui est un simple script python qui renvoie une liste de mots - je voudrais intégrer ce comportement dans une page wordpress - quelqu'un pourrait-il m'orienter dans la bonne direction pour la manière facile de gérer un point de python dans wordpress?

EDIT - suite à la merveilleuse réponse ci-dessous, je suis beaucoup plus loin ... mais malheureusement toujours pas tout à fait là ...

J'ai python qui s'exécute sur le serveur ...

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

et il est dans le même répertoire que le plugin activé ...

Le code python ... qui a le code suivant ...

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

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

1
Si c'est un script très simple, je pense que je le réécrirais simplement en PHP en tant que plugin / modèle WordPress ;-) Mais dans certains cas, les gens utilisent des iframes pour incorporer des pages externes.
birgire

iframe directement? :]
Jesse

Est-ce juste un accident, ou votre code python est-il vraiment mélangé avec PHP?
fuxia

J'ai collé la trace du terminal, avec les fichiers affichés par la commande 'more' ... va ranger un peu ...
Joe

Réponses:


20

Vous pouvez utiliser popen()pour lire ou écrire dans un script Python (cela fonctionne aussi avec n'importe quel autre langage). Si vous avez besoin d'une interaction (passage de variables), utilisez proc_open().

Un exemple simple pour imprimer Hello World! dans un plugin WordPress

Créez le plugin, enregistrez 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;
}

Vous pouvez maintenant utiliser ce shortcode dans l'éditeur de publication avec [python]ou [python file="filename.py"].

Mettez les scripts Python que vous souhaitez utiliser dans le même répertoire que le fichier du plugin. Vous pouvez également les placer dans un répertoire et ajuster le chemin dans le gestionnaire de shortcode.

Créez maintenant un script Python complexe comme celui-ci:

print("Hello World!")

Et c'est tout. Utilisez le shortcode et obtenez cette sortie:

entrez la description de l'image ici


La bonne réponse omet que la première ligne du script python, du moins dans mon cas, doit être #! / Usr / bin / env python
MikeiLL

1
@MikeiLL Cela dépend du système de l'utilisateur, donc je l'ai laissé délibérément.
fuxia

faisant essentiellement une faille de sécurité. Si vous pouvez diriger vers python, vous pouvez également diriger vers tout autre processus et cela peut être utilisé pour intensifier tout exploit plus trivial.
Mark Kaplun

3

J'ai suivi l'exemple de script de la première réponse, mais je n'obtenais aucune sortie ni erreur.

J'ai changé cette ligne:

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

pour ça:

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

puis a reçu un message "permission refusée".

Sur la console, j'ai couru

chmod 777 hello.py

rafraîchi la page, et tout fonctionnait parfaitement.

C'est peut-être le problème que Joe voyait ci-dessus. Je n'ai pas assez de représentant pour faire un commentaire, désolé. J'espère que cela aide quelqu'un.


Ne faites pas l'autorisation 777. Rendez-la simplement exécutable. chmod +x filename.pyva faire
Tessaracter

2

Voici un petit script qui utilise proc_opencomme indiqué ci-dessus, pour envoyer une simple variable de texte à 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] ); //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

Ajout de quelques tests en bas pour voir si le fichier python l'est rwx. Je pense qu'une meilleure façon d'envoyer le argvserait d'utiliser fwrite, mais cela ne fonctionnait pas pour moi après ce tutoriel .

Voici le script python que j'ai utilisé. Comme indiqué dans les commentaires ci-dessus, quelque chose comme #!/usr/bin/env pythonpeut être nécessaire, selon le serveur.

#!/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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.