Printing HTML in Python CGI - python

I've been teaching myself python and cgi scripting, and I know that your basic script looks like
#!/usr/local/bin/python
import cgi
print "Content-type: text/html"
print
print "<HTML>"
print "<BODY>"
print "HELLO WORLD!"
print "</BODY>"
print "</HTML>"
My question is, if I have a big HTML file I want to display in python (it had lines and lines of code and sone JS in it) do I have to manually add 'print' in front of each line and turn "s into \" , etc? Or is there a method or script that could convert it for me?
Thanks!

Python supports multiline strings, so you can print out your text in one big blurb.
print '''<html>
<head><title>My first Python CGI app</title></head>
<body>
<p>Hello, 'world'!</p>
</body>
</html>'''
They support all string operations, including methods (.upper(), .translate(), etc.) and formatting (%), as well as raw mode (r prefix) and the u unicode prefix.

If that big html file is called (for example) 'foo.html' and lives in the current directory for your CGI script, then all you need as your script's body is:
print "Content-type: text/html"
print
with open('foo.html') as f:
print f.read()
If you're stuck with Python 2.5, add from __future__ import with_statement as the start of your module's body. If you're stuck with an even older Python, change the last two lines into
print open('foo.html').read()
Note that you don't need to import cgi when you're using none of the functionality of the cgi module, which is the case both in your example and in this answer.

When I was first experimenting with decorators, I wrote this little CGI decorator to handle the HTML head and body tag boilerplate stuff. So that you can just write:
#CGImethod(title="Hello with Decorator")
def say_hello():
print '<h1>Hello from CGI-Land</h1>'
which when called returns:
Content-Type: text/html
<HTML>
<HEAD><TITLE>Hello with Decorator</TITLE></HEAD>
<BODY>
<h1>Hello from CGI-Land</h1>
</BODY></HTML>
Then say_hello could be called from your HTTP server's do_GET or do_POST methods.

Python supports multiline string. So you can just copy your HTML code and paste it into the quotations.
print ("<html>
<head>
<title>
</title>
</head>
</html>")
and so on!

Related

CGI Module - Python

I found this CGI Module, its letting me use HTML tags inside a python script.
ive seen some topics in here that shows how to use it, but when im using it it doesnt works.
import cgi
print ("""
<html>
<body>
Hello
</body>
</html>
""")
and this is the output when im running the script:
<html>
<body>
Hello
</body>
</html>
how can i use this properly?
thanks.
If you have your CGI script already hooked up to a web server, you will need to emit the HTTP headers too, e.g.
print("Content-Type: text/html") # HTML is following
print() # blank line, end of headers
print ("""
<html>
<body>
Hello
</body>
</html>
""")
Note that the cgi module is not being used in any way to achieve this; just simple calls to print(). The module is useful when you want to process form data submitted by a client through a HTML form.

Python CGI URL Redirect

I am currently writing a CGI python script. Once I have time I will rewrite this in web2py, but simply have no time ATM for this.
I have the whole logic built, except for one thing. I need to be able to:
1) Send a variable to start a process (got that it works)
2) Refresh the page until such process ends
3) display information once process is done.
I can't seem to be able to get passed the URL refresh part, and stripping the variable which started the original process.
I tried webbrowser (webbrowser.open('http://example.com?running=1')), however for some reason I am not being redirected at all on Mac.
if print_html.parse_url():
url_variable=print_html.parse_url()
IP=url_variable['IP'].value
Iterations=int(url_variable['quantity'].value)
start=url_variable['start'].value
refresh=url_variable['refresh'].value
if start == "1":
As you can see I read the variables from URL, and assign values. When start == '1' I want to start running the rest of the programs. While the program is running I want to change the URL variable to re-read the page until everything is finished processing
Some more clarification, perhaps this helps:
I need to refresh the page, or perhaps open the same page but with different variables.
For instance
1st instance: http://example.com/test.py?start=1
logic runs and then refresh spawning:
2st instance: http://example.com/test.py?running=1
Does that make sense?
You can refresh the page using the HTML meta http-equiv directive.
#!/usr/bin/python
import datetime
import time
print "Content-Type: text/html"
print ""
print '''
<html>
<head>
<meta http-equiv="refresh" content="15" />
</head>'''
now = datetime.datetime.now()
now = now.isoformat()
print '''
<body>
The time is now %s
</body>''' % now

Javascript with python cgi not giving expected results

In the below Python CGI script, I am using javascript function for changing the picture on click. But apparently it doesn't seems to work. I am following the example from w3 schools js example. So I just want to conform, is it possible to use the javascript inside Python CGI script.
If same example has to be done in Python, what should be the approach.
#!/usr/bin/env python
import cgi
print """print "Content-type: text/html; charset=utf-8
<!DOCTYPE html>
<html>
<body>
<script>
function changeImage()
{
element=document.getElementById('myimage')
if (element.src.match("bulbon"))
{
element.src="../pic_bulboff.gif";
}
else
{
element.src="../pic_bulbon.gif";
}
}
</script>
<img id="myimage" onclick="changeImage()"
src="../pic_bulboff.gif" width="100" height="180">
<p>Click the light bulb to turn on/off the light</p>
</body>
</html>
"""
Yes, you can send javascript inside the HTML via a python CGI scrpit. You have to change the initial part of the string that you are sending to:
print """Content-type: text/html; charset=utf-8\n\n
<!DOCTYPE html>
...
EDIT to add the following comments:
There were two problems in your code:
the 1st, you had to remove the part 'print "', because you were already printing a string;
the 2nd, it is a specification of CGI that it must have "\n\n" separating the header, eg. "content-type: text/html; charset=utf-8\n\n" from the following part eg. "...", (in fact as you had one implicit "\n", it would be enough to add just one more...).

How to loading/show a picture in a Python CGI page

I have written a little survey using Python and CGI. I am trying to show a picture using the normal <img> tag, But even-though the picture is in the same directory as my cgi script, my script cannot show it. I also changed the header to this:
print "Content-type: text/html; image/jpeg"
print
print """<html>
<head>
<title>You are going to be redirected</title>
</head>
<body bgcolor = #14b585>
<br>
<p align=center><font>Helloooo</font></p>
<img src="cat.jpeg" alt="cat" width="304" height="228"/>
<form action="./sample.py" method="post">
<p align=center><input type="submit" value="YES!" /></p>
</form>
</body>
</html>
"""
Why?(it is a very small jpg file)
print "Content-type: text/html; image/jpeg"
Don't change the header to that. You can't have multiple content types for a single document (multipart documents excluded, but browsers don't support them and that isn't the right format).
You are delivering an HTML document with an reference to an image in it. The image will be a separate request and response.
print "Content-type: text/html"
Or, better:
print "Content-type: text/html; charset=utf-8"
(Assuming you are using utf-8, which you should be).
print """<html>
Your Doctype is missing. This will trigger quirks mode, which is undesirable. You also have a great deal of legacy presentational markup that should be replaced by CSS.
<img src="cat.jpeg" alt="cat" width="304" height="228"/>
The context suggests that the image is decorative, so the alternative text should probably be "" (see Alt texts in IMGS), but there is nothing wrong with the actual reference to the image.
But even-though the picture is in the same directory as my cgi script
Since the HTML seems to be OK. You need to check that the image is.
Can you reach the image by typing the URL in directly?
What do the web server logs say when you try?
It is possible that your server is configured to try to treat everything in the directory as an executable, no matter what the file extension, so it might be trying to run the image as if it were a CGI program (which will obviously fail). If so, then you could either move the image or change the configuration of the server.
And I've just noticed this comment:
I did this in my browser: localhost/cgi-bin/cat.jpg and it got an error, I checked the logs, it Exec format error: exec of '/home/hossein/public_html/cgi-bin/cat.jpg' failed
That is what is happening. Moving the image is the simplest solution.
your apache was configured to use the cgi-bin directory as an CGI scripts folder, so any request that trying to get a file from this folder apache try to execute it as an CGI script. to make your image visible move it to the www/html folder.

Is it possible to use Python, AJAX & CGI together

I want to have a web page where you click a button, by using AJAX I get a string from a python script, then display that string in a paragraph HTML element.
I know I can do this by using Python, WSGI & AJAX (theoretically I can do it this way) but its waaaay too difficult. I am experienced with CGI & python.
So can I do the above using CGI?
If I can how do the python script work, exactly the same as when serving a page using CGI?
This doesn't work:
import cgitb; cgitb.enable()
import cgi
import os
print "Content-Type: text/html\n"
input_data = cgi.FieldStorage()
print "hello"
When I click my button in my page, nothing happens & my CGI server (which works fine for cgi page requests) gives me a http 501 error.
My html & javascript:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
<!--
function onTest( dest, params )
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById( "bb" ).innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("POST",dest,true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send( params );
}
-->
</script>
</head>
<body>
<p id="bb"> abcdef </p>
Click it
</body>
</html>
Here are 3 files [my.html, myCGI.py, myPyServer.py]. In windows XP I put them all in the same directory and double-click on myPyServer.py and things work very well.
my.html is the same as your html except:
yours: Click it
mine: Click it
myCGI.py is pretty close to yours
import cgitb; cgitb.enable()
import cgi
import os
input_data = cgi.FieldStorage()
if input_data:
print "Content-Type: text/html\n"
print "hello"
else:
f = open('my.html', 'r'); s = f.read(); f.close()
print "Content-Type: text/html\n"
print s
myPyServer.py
import CGIHTTPServer
import BaseHTTPServer
import sys
class Handler(CGIHTTPServer.CGIHTTPRequestHandler):
cgi_directories = ["/"] #make sure this is where you want it. [was "/cgi"]
PORT = 8000
httpd = BaseHTTPServer.HTTPServer(("", PORT), Handler)
# see effbot http://effbot.org/librarybook/thread.htm
def runserver():
print "serving at port", PORT
httpd.serve_forever()
import thread
thread.start_new_thread(runserver, ())
print "opening browser"
import webbrowser
url = 'http://127.0.0.1:8000/myCGI.py'
webbrowser.open_new(url)
quit = 'n'
while not(quit=='quit'):
quit = raw_input('\n ***Type "quit" and hit return to exit myPyServer.*** \n\n')
print "myPyServer will now exit."
sys.exit(0)
Of course you can use plain old CGI if you want. Your code works fine for me. (The "abcdef" turns into "hello" when the link is clicked.)
You must have some simple error in your setup. I'd check file permissions on your test scripts (a+rx), which might have been overlooked. Also I assume you've got a "#!/usr/bin/env python" (or equivalent) at the top of your cgi script (it is omitted in your example above).
Check out sajax:
http://www.modernmethod.com/sajax/
There's a python library and example in the download. You can have one CGI script that can handle your view and implement any AJAX call.
Here is one simple example using Python CGI and ajax.
http://www.ssiddique.info/writing-your-first-python-cgi-ajax-script.html

Categories