I need to implement a very simple web-server-like app in Python which would perform basic HTTP requests and responses and display very basic output on the web page. I am not too concerned about actually coding it in Python, but I am not sure where to start? How to set this up? One file? Multiple files? I guess I have no idea how to approach the fact that this is a "server" - so I am unfamiliar with how to approach dealing with HTTP requests/sockets/processing requests, etc. Any advice? Resources?
-
Explain further your requirements (and why). Are you wanting to implement the full application-level stack, or can you use e.g. Apache? Explain more what you need *And why.* Finally, when you have the "websocket" tag, do you mean it or was that just an incorrect tag to use? – Chris Morgan Apr 10 '12 at 15:08
-
2Without using *any* libraries? Surely `socket` is going to be required at a minimum? – Wooble Apr 10 '12 at 15:09
-
check [this documentation](http://docs.python.org/library/simplehttpserver.html) page, here I assume that "any libraries" are libraries that are not included in the python installation. – Emil M Apr 10 '12 at 15:10
-
@Wooble: I think it is quite fair to assume "any libraries" to mean "any non-standard libraries". – Chris Morgan Apr 10 '12 at 15:12
4 Answers
You should look at the SimpleHttpServer (py3: http.server) module.
Depending on what you're trying to do, you can either just use it, or check out the module's source (py2, py3) for ideas.
If you want to get more low-level, SimpleHttpServer extends BaseHttpServer (source) to make it just work.
If you want to get even more low-level, take a look at SocketServer (source: py2, py3).
People will often run python like python -m SimpleHttpServer
(or python3 -m http.server
) if they just want to share a directory: it's a fully functional and... simple server.

- 10,606
- 4
- 43
- 67

- 8,185
- 4
- 35
- 48
-
I would probably say you should check the HTTP documentation first. like RFC. – zinking May 15 '12 at 03:06
You can use socket programming for this purpose. The following snippet creates a tcp socket and listens on port 9000 for http requests:
from socket import *
def createServer():
serversocket = socket(AF_INET, SOCK_STREAM)
serversocket.bind(('localhost',9000))
serversocket.listen(5)
while(1):
(clientsocket, address) = serversocket.accept()
clientsocket.send("HTTP/1.1 200 OK\n"
+"Content-Type: text/html\n"
+"\n" # Important!
+"<html><body>Hello World</body></html>\n")
clientsocket.shutdown(SHUT_WR)
clientsocket.close()
serversocket.close()
createServer()
Start the server, $ python server.py
.
Open http://localhost:9000/
in your web-browser (which acts as client). Then in the browser window, you can see the text "Hello World" (http response).
EDIT** The previous code was only tested on chrome, and as you guys suggested about other browsers, the code was modified as:
- To make the response http-alike you can send in plain header with http version 1.1, status code 200 OK and content-type text/html.
- The client socket needs to be closed once response is submitted as it's a TCP socket.
- To properly close the client socket,
shutdown()
needs to be called socket.shutdown vs socket.close
Then the code was tested on chrome, firefox (http://localhost:9000/) and simple curl in terminal (curl http://localhost:9000).
-
4-1. Did you try this? This doesn't work at all; it's a socket server, but doesn't speak HTTP. – Asherah May 18 '12 at 02:57
-
3It doesn't actually speak HTTP, so almost every browser wouldn't work with this. It doesn't work in Chrome. It only works in Firefox if you press the Stop button. This is not a web server. – Asherah May 18 '12 at 03:02
-
I copied your script ran it and I'm getting an error saying `a byte-like object is required not 'str'` how do I fix this? – Xantium Oct 07 '17 at 10:40
-
3@Simon Modified the code a bit. Also it was tested on python 2.7.6. If you are using python 3, where strings are Unicode; but when transmitting on the network, we need to send bytes strings instead. So try sendall() instead of send() with string output encoded as utf-8. #START output = "It works" clientsocket.sendall(output.encode("utf-8")) #END – pritam Oct 10 '17 at 09:59
-
Super! That's just what I needed. I do use Python 3 so the ` sendall()` and `.encode("utf-8")` are absolutely essential and both these have fixed the error I was getting. all my server attempts up to this point have failed so I am very grateful. This is a well deserved up-vote however I do not like the `clientsocket.send("HTTP/1.1 200 OK\n" +"Content-Type: text/html\n" +"\n" # Important! +"Hello World\n")` shouldn't that be all on the same line? I had to modify that part. Thanks again. : ) – Xantium Oct 10 '17 at 17:18
-
@Ashe It works normally in Chrome/Firefox/Edge for me. As I mentioned the byte-like error but apart from that this works great. – Xantium Mar 17 '18 at 12:43
-
@Simon the answer as originally posted (*six years ago*) did not have anything resembling HTTP; see https://stackoverflow.com/revisions/10592712/1. – Asherah Mar 18 '18 at 03:49
I decided to make this work in Python 3 and make it work for Chrome to use as an example for an online course I am developing. Python 3 of course needs encode()
and decode()
in the right places. Chrome - really wants to send its GET request before it gets data. I also added some error checking so it cleans up its socket if you abort the server or it blows up:
def createServer():
serversocket = socket(AF_INET, SOCK_STREAM)
try :
serversocket.bind(('localhost',9000))
serversocket.listen(5)
while(1):
(clientsocket, address) = serversocket.accept()
rd = clientsocket.recv(5000).decode()
pieces = rd.split("\n")
if ( len(pieces) > 0 ) : print(pieces[0])
data = "HTTP/1.1 200 OK\r\n"
data += "Content-Type: text/html; charset=utf-8\r\n"
data += "\r\n"
data += "<html><body>Hello World</body></html>\r\n\r\n"
clientsocket.sendall(data.encode())
clientsocket.shutdown(SHUT_WR)
except KeyboardInterrupt :
print("\nShutting down...\n");
except Exception as exc :
print("Error:\n");
print(exc)
serversocket.close()
print('Access http://localhost:9000')
createServer()
The server also prints out the incoming HTTP request. The code of course only sends text/html regardless of the request - even if the browser is asking for the favicon:
$ python3 server.py
Access http://localhost:9000
GET / HTTP/1.1
GET /favicon.ico HTTP/1.1
^C
Shutting down...
But it is a pretty good example that mostly shows why you want to use a framework like Flask or DJango instead of writing your own. Thanks for the initial code.

- 4,415
- 3
- 27
- 30
There is a very simple solution mentioned above, but the solution above doesn't work. This solution is tested on chrome and it works. This is python 3 although it may work on python 2 since I never tested it.
from socket import *
def createServer():
serversocket = socket(AF_INET, SOCK_STREAM)
serversocket.bind(('localhost',9000))
serversocket.listen(5)
while(1):
(clientsocket, address) = serversocket.accept()
clientsocket.send(bytes("HTTP/1.1 200 OK\n"
+"Content-Type: text/html\n"
+"\n" # Important!
+"<html><body>Hello World</body></html>\n",'utf-8'))
clientsocket.shutdown(SHUT_WR)
clientsocket.close()
serversocket.close()
createServer()
This is improved from the answer that was accepted, but I will post this so future users can use it easily.

- 291
- 2
- 11
-
Welcome to Stack Overflow. This question is a near duplicate of the [answer provided by @drchuck](https://stackoverflow.com/a/53157058/148680). The only thing that differentiates it from the latter is the lack of exception handling. – chb Jan 26 '19 at 20:53