How to run CGI "hello world" with python http.server
Solution 1
From the http.server
docs:
CGIHTTPRequestHandler
can be enabled in the command line by passing the--cgi
option:
$ python3 -m http.server --bind localhost --cgi 8000
Put your script into cgi_directories
:
This defaults to
['/cgi-bin', '/htbin']
and describes directories to treat as containing CGI scripts.
Open in the browser:
$ python -mwebbrowser http://localhost:8000/cgi-bin/hello.py
where hello.py
:
#!/usr/bin/env python3
print("Content-Type: text/html\n")
print("<!doctype html><title>Hello</title><h2>hello world</h2>")
I had to make it executable on POSIX: chmod +x cgi-bin/hello.py
.
Solution 2
I created a complete example for a friend. It is a complete demo you can run with 8 simple copy-paste ready lines of code. Enjoy.
echo -e "\n\n Usage: after running this script, visit http://localhost:8000/cgi-bin/hello \n\n"
mkdir /tmp/cgi-bin/
cat > /tmp/cgi-bin/hello <<EOF
#!/bin/bash
echo -e "Content-Type: text/plain\n\n"; date; echo; env
EOF
chmod +x /tmp/cgi-bin/hello
(cd /tmp; python3 -m http.server --cgi 8000)
Solution 3
I did this some time ago for Python2.7
from BaseHTTPServer import BaseHTTPRequestHandler
class GetHandler(BaseHTTPRequestHandler):
def do_HEAD(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
def do_GET(self):
x = self.wfile.write
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
# <--- HTML starts here --->
x("<html>")
# <--- HEAD starts here --->
x("<head>")
x("<title>Title goes here!</title>")
x("</head>")
# <--- HEAD ends here --->
# <--- BODY starts here --->
x("<body>")
x("<p>This is a test.</p>")
x("</body>")
# <--- BODY ends here --->
x("</html>")
# <--- HTML ends here --->
if __name__ == '__main__':
from BaseHTTPServer import HTTPServer
server = HTTPServer(('localhost', 777), GetHandler)
print 'Starting server, use <Ctrl + F2> to stop'
server.serve_forever()
So in Python 3 you just need to change imports
from http.server import BaseHTTPRequestHandler
class GetHandler(BaseHTTPRequestHandler):
def do_HEAD(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
def do_GET(self):
x = self.wfile.write
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
# <--- HTML starts here --->
x("<html>")
# <--- HEAD starts here --->
x("<head>")
x("<title>Title goes here!</title>")
x("</head>")
# <--- HEAD ends here --->
# <--- BODY starts here --->
x("<body>")
x("<p>This is a test.</p>")
x("</body>")
# <--- BODY ends here --->
x("</html>")
# <--- HTML ends here --->
if __name__ == '__main__':
from http.server import HTTPServer
server = HTTPServer(('localhost', 777), GetHandler)
print('Starting server, use <Ctrl + F2> to stop')
server.serve_forever()
Related videos on Youtube
Yura
Updated on March 30, 2020Comments
-
Yura about 4 years
I am using Windows 7 and Python 3.4.3. I would like to run this simple helloworld.py file in my browser:
print('Content-Type: text/html') print( '<html>') print( '<head></head>') print( '<body>') print( '<h2>Hello World</h2>') print( '</body></html>')
What I do is:
1) Go to command line
C:\Python
(where python is installed)2) run:
python -m http.server
3) Got to Firefox and type
http://localhost:8000/hello.py
However, instead of "Hello World", the browser just prints the content of the hello.py file.
How can I fix it?
-
TehTris almost 9 yearsyour webserver isnt "running python". your python is running a webserver.
-
kylieCatt almost 9 yearsYou should edit your original question instead of just reposting it.
-
TehTris almost 9 yearsafter re-reading my comment it seemed kinda sarcastic, so let me explain a little more. visit bootstrap.pypa.io/get-pip.py and watch how the file contents are just displayed in your browser. Your webserver is not configured to actually do anything with python commands, its just serving whatever files you have in the directory as the most basic of all no frills webserver.
-
Yura almost 9 years@IanAuld, my other question was regarding configuring WAMP. This question is regarding http.server. No reposting - this is a different question
-
kylieCatt almost 9 years
-
Yura almost 9 years@TehTris, I clicked the link and it has downloaded a .py file. Nothing was displayed in my browser. what should I do with it?
-
Yura almost 9 years@IanAuld, I tried to read it the last time, but it seems Chinese to me, I dont really know where to start and what to do with that. If you want to prompt me to a more precise to read, Id love your help.
-
Tom-Oliver Heidel almost 9 years@IanAuld depending on what you are doing it is enough to use the python built-in functions. tho' of course you are right that flask and other (micro-)frameworks can help a lot,
-
kylieCatt almost 9 yearsIf the OP is a beginner (which I'm assuming they are) dealing with server configs and rendering out different pages, routing and security concerns can quickly become overwhelming. Letting a framework do the heavy lifting while they learn will probably be much easier in the long run.
-
kylieCatt almost 9 years
-
Yura almost 9 years@IanAuld, Thank you. I'll read it now ! :)
-
Tom-Oliver Heidel almost 9 yearsBy the way you do not type in 'localhost:8000/hello.py' do it WITHOUT 'hello.py'
-
Yura almost 9 years@ Tom-Oliver Heidel, in that case, I just get a list of all the files in the directory. In fact, if I dont type the hello.py, how would the server know to execute the :hello.py" and not "some-other-file-I-have.py"...?
-
-
Yura almost 9 yearsThanks @Tom-Oliver Heidel, Im a newbie, please guide me what to do with this code you have posted and where to place it to make my hello-world.py work oin the browser. Thanks
-
Tom-Oliver Heidel almost 9 yearsI cannot guarantuee 100% that the python3 code will work because I just used python docs in short time. But there is a tool called '2to3' which will convert python2 script into python3 script docs.python.org/2/glossary.html#term-to3 Actually you just need to copy the scripty and name it like e.g. 'httpserver.py' then you can use cmd and type in 'python httpserver.py' to start it.
-
Tom-Oliver Heidel almost 9 yearscan you test my python3 script if it really works. I do not want to install python3 right now or use some online python because those work some different.
-
jfs almost 9 years@Tom-OliverHeidel: sure. What commands do you want me to run and what do you expect to happen (define "really works": do you care about multiple concurrent clients, security, buffers, etc)?
-
Tom-Oliver Heidel almost 9 yearsscroll down a bit - the other answer is mine.
-
Yura almost 9 years@J.F. Sebastian, I did it (except "I had to make it executable on POSIX: chmod +x cgi-bin/hello.py." - since I dont understand what this is. is it Linux? I am on Win) and it did not work for me... stil printing the content of the file onto the browser
-
jfs almost 9 yearsI've changed
777
to7777
(permission error on Unix) and replaced allstr
literals bybytes
literals on Python 3.Ctrl + F2
does something unrelated on my Ubuntu machine. After that it shows: "This is a test." if you visit:localhost:7777
. -
Yura almost 9 years@Tom-OliverHeidel How should I run the files? On port 777?
-
jfs almost 9 years@Yura: 1. have you put
hello.py
intocgi-bin
directory? 2. Have you appended--cgi
as shown above? 3. Have you visitedlocalhost:8000/cgi-bin/hello.py
(note: cgi-bin in url)? 4. Have your added additional"\r\n"
after the http header? -
Tom-Oliver Heidel almost 9 yearsThank you @J.F.Sebastian yes I just choose an unused port (win7). Ctrl+F2 was the IDE I am working with - actually in console you abort with ctrl+c. But it seems everything is running fine then :)
-
Tom-Oliver Heidel almost 9 years@Yura when you got the file saved and executed with 'python filename.py' you can go and open your browser. type in 'localhost:777' or to whatever you changed the port in the script.
-
Tom-Oliver Heidel almost 9 years@Yura is using windows so. J.F. Sebastian he will not have a cgi-bin by default. I guess he is just testing some python at all.
-
jfs almost 9 years@Tom-OliverHeidel:
cgi-bin
is just a directory name: it can be anything fromcgi_directories
(click the link in the answer) -
Yura almost 9 years@ J.F. Sebastian. (1)-Yes (2)-Yes (3)-Yes (4)-I guess no, since I have no idea what you are talking about. As for the file, indeed om my screen is printed "hello". BUT, this is just a print of a file and not a result of running it. It I put print("<h2>hello</h2>") instead of the 2nd line , then I would get "<h2>hello</h2>" on my screen. Meaning that this is just a print of the file.... :(
-
jfs almost 9 years@Yura: have you tried to change:
"Content-Type: text/plain\n\nhello\n"
to"Content-Type: text/html\n\n<!doctype html><title>Hello</title><h2>hello world</h2>"
? -
Yura almost 9 years@ Tom-Oliver Heidel, Ok, I did it. saved and run the server file and then typed "localhost:777/hello.py" in the browser. => the browser showed a blank page...
-
Tom-Oliver Heidel almost 9 yearsI never said to type in 'localhost:777/hello.py' when you executing the python file you can read 'Starting server ........' then you type into your browser 'localhost:777' nothing more.
-
Yura almost 9 years@J.F. Sebastian, YOU ARE RIGHT!!!! I have been struggling with it for 3 days. You helped me alot Thank You very much!!! when I put this line as the first one: print ("Content-type:text/html\r\n\r\n") , it does not work. However, when I put this line: print ("Content-Type: text/html\n\n<!doctype html>"), it works. Do you know why?
-
Yura almost 9 years@Tom-Oliver Heidel, I just tried typing only "localhost:777" but got a blank result again. Anyway, seems that J.F. Sebastian solved the problem. Thank you very much Tom-OliverHeide for you support and your time! Thanks!
-
jfs almost 9 years@Yura: If something stops working; start with a known state that works and change one thing at a time until it breaks again.
"\n"
is replaced with"\r\n"
while printing by Python on Windows. The client (browser) expects\r\n\r\n
before the html body. My previous (removed) comment was wrong: you don't need a space before the field value. There are several html versions.<!doctype html>
indicates html5 -
W.M. almost 8 yearsHow to make the server accept SSL connections, what modifications must be made for this line
python3 -m http.server --bind localhost --cgi 8000
? Thanks -
jfs about 6 years@W.M.: you could add
httpd.socket = ssl.wrap_socket( httpd.socket, keyfile=keypath, certfile=certpath, server_side=True)
tohttp.server.test()
function (or use more flexibleSSLContext.wrap_socket
). Here's a code example for apython3 -mhttp.server
analog [text in Russian]. For the cgi case, pass CGIHTTPRequestHandler instead of SimpleHTTPRequestHandler