Rularea unui script Python în WordPress

27 oct. 2013, 15:02:08
Vizualizări: 111K
Voturi: 22

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

Dacă este un script foarte simplu, cred că aș rescrie pur și simplu codul în PHP ca un plugin/șablon WordPress ;-) Dar în unele cazuri oamenii folosesc iframe-uri pentru a încorpora pagini externe.

birgire birgire
27 oct. 2013 15:29:19

iframe direct? :]

Jesse Jesse
27 oct. 2013 15:36:22

Este doar o greșeală accidentală, sau codul tău Python este cu adevărat amestecat cu PHP?

fuxia fuxia
5 nov. 2013 19:01:51

Am inserat urma terminalului, cu fișierele afișate prin comanda 'more'... voi aranja puțin...

Joe Joe
5 nov. 2013 23:42:49
Toate răspunsurile la întrebare 3
7
26

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:

Rezultatul afișării scriptului Python

27 oct. 2013 15:45:28
Comentarii

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

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

fuxia fuxia
20 mai 2014 09:33:33

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ă.

Mark Kaplun Mark Kaplun
15 aug. 2018 08:13:28

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

Brian Stinar Brian Stinar
21 ian. 2020 00:15:03

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.

Maarten Derickx Maarten Derickx
26 sept. 2020 14:21:51

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

Mark Kaplun Mark Kaplun
26 sept. 2020 22:40:00

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.

Mark Kaplun Mark Kaplun
26 sept. 2020 22:46:28
Arată celelalte 2 comentarii
2

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.

6 oct. 2016 03:14:38
Comentarii

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

Trect Trect
25 iun. 2019 08:36:00

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

ajinzrathod ajinzrathod
6 mai 2021 18:16:54
0

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