I have a WordPress install for a personal blog and I'm gradually porting all of the little web bits I have written over the years to pages on the blog.

One such page is http://www.projecttoomanycooks.co.uk/cgi-bin/memory/majorAnalysis.py which is a simple python script that returns a list of words - I'd like to embedd that behavior within a wordpress page - could someone point me in the right direction for the easyist way of running a spot of python within wordpress?

EDIT - following the wonderful answer below, I have got a lot futher... but unfortunately still not quite there...

I have python that executes on server...

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

and it's in the same directory as the activated plugin...

The python code... which has the following code...

print("Hello World!")

The 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(
            'file' => 'hello.py'
    $handle = popen( __DIR__ . '/' . $data['file'], 'r');
    $read   = fread($handle, 2096);

    return $read;
  • 1
    If it's a very simple script, I think I would just rewrite it in PHP as a WordPress plugin/template ;-) But in some cases people use iframes to embed external pages. – birgire Oct 27 '13 at 13:29
  • iframe it directly? :] – Jesse Oct 27 '13 at 13:36
  • Is this just an accident, or is your python code really mixed with PHP? – fuxia Nov 5 '13 at 17:01
  • I pasted the terminal trace, with the files being displayed by the 'more' command... will tidy up a little... – Joe Nov 5 '13 at 21:42

You can use popen() to read or write to a Python script (this works with any other language too). If you need interaction (passing variables) use proc_open().

A simple example to print Hello World! in a WordPress plugin

Create the plugin, register a shortcode:

<?php # -*- coding: utf-8 -*-
/* Plugin Name: Python embedded */

add_shortcode( 'python', 'embed_python' );

function embed_python( $attributes )
    $data = shortcode_atts(
            'file' => 'hello.py'

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

    while ( ! feof( $handle ) )
        $read .= fread( $handle, 2096 );

    pclose( $handle );

    return $read;

Now you can use that shortcode in the post editor with [python] or [python file="filename.py"].

Put the Python scripts you want to use into the same directory as the plugin file. You can also put them into a directory and adjust the path in the shortcode handler.

Now create a complex Python script like this:

print("Hello World!")

And that’s all. Use the shortcode, and get this output:

enter image description here

  • Correct answer omits that first line of the the python script, at least in my case, needs to be #!/usr/bin/env python – MikeiLL May 19 '14 at 23:28
  • 1
    @MikeiLL That depends on the user’s system, so I left it out deliberately. – fuxia May 20 '14 at 6:33
  • basically making a security hole. If you can pipe to python, you can pipe to any other process as well and this can be used to escalate any more trivial exploit. – Mark Kaplun Aug 15 '18 at 5:13

I followed the example script from the first answer, but was getting no output or errors.

I changed this line:

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

to this:

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

and then got a "permission denied" message.

On the console, I ran

chmod 777 hello.py

refreshed the page, and everything worked perfectly.

This may be the issue Joe was seeing above. I don't have enough rep to make a comment, sorry. Hope this helps someone.


Here's a little script that uses proc_open as noted above, to sent one simple text variable to a python script:

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

Added a few tests as the bottom to see if the python file is rwx. I think a better way to send the argv would be using fwrite, but it wasn't working for me following this tutorial.

Here is the python script I used. As noted in comments above, something like #!/usr/bin/env python may be necessary, depending on 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

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.