Python Scripts I try to run using CGI don't seem to be working

I’m trying to run python scripts using cgi.

When go to the page in a web browser (EG http://yun.local/cgiTest.py) I simply get The CGI process did not produce any response.

I’ve tried all the instructions in this thread, however the result remains the same. I’ve even tried copying and pasting the OttoF’s code from the thread, to no avail.

Next, I tried creating an html document, like so:

<html><body>It is <!--#exec cgi="python ./cgi-bin/temp.py" --> Degrees F</body></html>

This too fails, but differently. It simply displays the oh-so-informative “It is Degrees F”

temp.py works. Take a look.

root@yun:/www/cgi-bin# python temp.py
76.2765867989

I’ve checked all the other threads I could find, and spent the last 6 hours trying to make this work.
It hasn’t.
Please help.

jamesbiederbeck: I'm trying to run python scripts using cgi.

::::SNIP::::

I've checked all the other threads I could find, and spent the last 6 hours trying to make this work. It hasn't. Please help.

jamesbiederbeck,

the webserver on the Yun is NOT an Apache server. It is a custom minimal server. Today you should buy a lottery ticket. I just happen to be documenting the information you need.

This is the executing as registered by ps

/usr/sbin/uhttpd -f -h /www -r Arduino -x /cgi-bin -t 60 -T 30 -A 1 -n 2

The command line options are not well documented. I have not found them yet. Here are the reference/man page for the configuration files. http://wiki.openwrt.org/doc/uci/uhttpd http://wiki.openwrt.org/doc/howto/http.uhttpd

Your two (2) configuration files are below. The first is /etc/config/uhttpd. The other is /etc/httpd.conf

It appears you need to put your cgi in /cgi-bin, which as you would expect is actually in /www/cgi-bin/

These are related, but NOT needed to resolve your issue. http://wiki.openwrt.org/doc/howto/http.overview http://wiki.openwrt.org/doc/howto/http.mini-httpd http://wiki.openwrt.org/doc/howto/start

If this is still not clear, please write back.

Jesse

# Server configuration
config uhttpd main

    # HTTP listen addresses, multiple allowed
    list listen_http    0.0.0.0:80
#   list listen_http    [::]:80

    # HTTPS listen addresses, multiple allowed
    list listen_https   0.0.0.0:443
#   list listen_https   [::]:443

    # Server document root
    option home     /www

    # Reject requests from RFC1918 IP addresses
    # directed to the servers public IP(s).
    # This is a DNS rebinding countermeasure.
    option rfc1918_filter 0

    # Maximum number of concurrent requests.
    # If this number is exceeded, further requests are
    # queued until the number of running requests drops
    # below the limit again.
    option max_requests 2

    # Certificate and private key for HTTPS.
    # If no listen_https addresses are given,
    # the key options are ignored.
    option cert     /etc/uhttpd.crt
    option key      /etc/uhttpd.key

    # CGI url prefix, will be searched in docroot.
    # Default is /cgi-bin
    option cgi_prefix   /cgi-bin

    # List of extension->interpreter mappings.
    # Files with an associated interpreter can
    # be called outside of the CGI prefix and do
    # not need to be executable.
#   list interpreter    ".php=/usr/bin/php-cgi"
#   list interpreter    ".cgi=/usr/bin/perl"

    # Lua url prefix and handler script.
    # Lua support is disabled if no prefix given.
#   option lua_prefix   /luci
#   option lua_handler  /usr/lib/lua/luci/sgi/uhttpd.lua

    # CGI/Lua timeout, if the called script does not
    # write data within the given amount of seconds,
    # the server will terminate the request with
    # 504 Gateway Timeout response.
    option script_timeout   60

    # Network timeout, if the current connection is
    # blocked for the specified amount of seconds,
    # the server will terminate the associated
    # request process.
    option network_timeout  30

    # TCP Keep-Alive, send periodic keep-alive probes
    # over established connections to detect dead peers.
    # The value is given in seconds to specify the
    # interval between subsequent probes.
    # Setting this to 0 will disable TCP keep-alive.
    option tcp_keepalive    1

    # Basic auth realm, defaults to local hostname
#   option realm    OpenWrt

    # Configuration file in busybox httpd format
#   option config   /etc/httpd.conf


# Certificate defaults for px5g key generator
config cert px5g

    # Validity time
    option days     36500

    # RSA key size
    option bits     1024

    # Location
    option country      IT
    option state        Turin
    option location     Turin

    # Common name
    option commonname   'Arduino LLC'
A:/arduino:/cgi-bin/luci/arduino%s
A:/data:/cgi-bin/luci/data%s
A:/mailbox:/cgi-bin/luci/mailbox%s

Thanks Jesse,

I have checked, and my config files appear to match yours, except of course for the addition of

list interpreter ".py=/usr/bin/python"

so it knows to use python for .py files.

My understanding is that I need to put cgi scripts run from an html doc inside cgi-bin, but I can leave python scripts that generate whole pages inside www.

EG:

/www/cgi-bin/calledfromCGIinhtmldoc.py

and

/www/entirepage.py (where I would go to yun.local/entirepage.py)

Neither of these methods seem to be working.

I suppose I should try php or lua with cgi and see if that reproduces the problem. Can anybody give me a simple hello world script for one of these languages that I can use for testing?

jamesbiederbeck:
Thanks Jesse,

::::SNIP::::

Neither of these methods seem to be working.

I suppose I should try php or lua with cgi and see if that reproduces the problem.
Can anybody give me a simple hello world script for one of these languages that I can use for testing?

Okay jamesbiederbeck,
you are thinking like PHP or RUBY or dJango.

  1. NO python code is embedded in the webpage. If you want to do that, you should use php, or some framework.
<html>
<body>
<!-- NOT THIS -->
<! python_code >
  1. The /cgi-bin is the old -style CGI:
<html>
<body>
<!-- LIKE THIS -->
<form action=/cgi-bin/python.py>

So, if you want some “hello world” examples. Please state your goal, then I can find the best fit for you.

Jesse

The goal is really just to run a python script which does some math on the input from a thermistor to figure out the temperature. The script just prints the temperature in Fahrenheit.

I just need something like this to work

import temperature
print temperature.main()

Such that loading up the webpage should ONLY yield a temperature like xx.x eg 72.5

Thanks

jamesbiederbeck: The goal is really just to run a python script which does some math on the input from a thermistor to figure out the temperature. The script just prints the temperature in Fahrenheit.

I just need something like this to work

import temperature
print temperature.main()

Such that loading up the webpage should ONLY yield a temperature like xx.x eg 72.5

Thanks

Okay, got that.

  • Do you want to press a button and redraw the whole pages? this is the easiest solution
  • Do you want to press a button and just update the value on the page? A bit more work

If you want #1 then:

  • create a template webpage for output
  • make that template a giant string in your python code
  • insert your value (where you want it) into that template
  • before you output (respond) with your new webpage, output:
print "Content-Type: text/html"     # HTML is following
print                               # blank line, end of headers

5. Then output your webpge

You can use the python CGI library to make things easier. https://docs.python.org/2/library/cgi.html

Is this enough?

Jesse