-
-
Save isuruf/f9fe7788310c251fcbd51e0d19cc5b71 to your computer and use it in GitHub Desktop.
Writing Simple HTTP Server in Python (With REST and JSON)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
There are many already existing powerful http servers that can be used in python e.g. gevent, twisted web server. However, they are a bit complex to use and you cannot start them in a thread other than the main thread. | |
Here is a sample of basic http server using "BaseHTTPRequestHandler". The example exposed two rest interfaces: | |
To ingest records into the web server | |
To retrieve already ingested records from the web server | |
The records are assumed to be JSON based, however, any type of records can be ingested. | |
[sourcecode language="python" wraplines="false" collapse="false"] | |
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer | |
from SocketServer import ThreadingMixIn | |
import threading | |
import argparse | |
import re | |
import cgi | |
class LocalData(object): | |
records = {} | |
class HTTPRequestHandler(BaseHTTPRequestHandler): | |
def do_POST(self): | |
if None != re.search('/api/v1/addrecord/*', self.path): | |
ctype, pdict = cgi.parse_header(self.headers.getheader('content-type')) | |
if ctype == 'application/json': | |
length = int(self.headers.getheader('content-length')) | |
data = cgi.parse_qs(self.rfile.read(length), keep_blank_values=1) | |
recordID = self.path.split('/')[-1] | |
LocalData.records[recordID] = data | |
print "record %s is added successfully" % recordID | |
else: | |
data = {} | |
self.send_response(200) | |
self.end_headers() | |
else: | |
self.send_response(403) | |
self.send_header('Content-Type', 'application/json') | |
self.end_headers() | |
return | |
def do_GET(self): | |
if None != re.search('/api/v1/getrecord/*', self.path): | |
recordID = self.path.split('/')[-1] | |
if LocalData.records.has_key(recordID): | |
self.send_response(200) | |
self.send_header('Content-Type', 'application/json') | |
self.end_headers() | |
self.wfile.write(LocalData.records[recordID]) | |
else: | |
self.send_response(400, 'Bad Request: record does not exist') | |
self.send_header('Content-Type', 'application/json') | |
self.end_headers() | |
else: | |
self.send_response(403) | |
self.send_header('Content-Type', 'application/json') | |
self.end_headers() | |
return | |
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): | |
allow_reuse_address = True | |
def shutdown(self): | |
self.socket.close() | |
HTTPServer.shutdown(self) | |
class SimpleHttpServer(): | |
def __init__(self, ip, port): | |
self.server = ThreadedHTTPServer((ip,port), HTTPRequestHandler) | |
def start(self): | |
self.server_thread = threading.Thread(target=self.server.serve_forever) | |
self.server_thread.daemon = True | |
self.server_thread.start() | |
def waitForThread(self): | |
self.server_thread.join() | |
def addRecord(self, recordID, jsonEncodedRecord): | |
LocalData.records[recordID] = jsonEncodedRecord | |
def stop(self): | |
self.server.shutdown() | |
self.waitForThread() | |
if __name__=='__main__': | |
parser = argparse.ArgumentParser(description='HTTP Server') | |
parser.add_argument('port', type=int, help='Listening port for HTTP Server') | |
parser.add_argument('ip', help='HTTP Server IP') | |
args = parser.parse_args() | |
server = SimpleHttpServer(args.ip, args.port) | |
print 'HTTP Server Running...........' | |
server.start() | |
server.waitForThread() | |
[/sourcecode] | |
Usage: | |
Copy paste the code above and name it simplewebserver.py | |
Starting WebServer: | |
python simplewebserver.py | |
POST addrecord example using curl: | |
curl -X POST http://localhost:8080/api/v1/addrecord/1 -d '{\"asif1\":\"test1\"}' -H "Content-Type: application/json" | |
GET record example using curl: | |
curl -X GET http://localhost:8080/api/v1/getrecord/test -H "Content-Type: application/json" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment