Permalink
Browse files

update

  • Loading branch information...
1 parent e2dbeb5 commit 31c7c19b20b20593d5f24d113e4f126aa3d5d26a agibsonccc committed Mar 13, 2013
View
@@ -0,0 +1,16 @@
+Python HTTP Server example
+==============================
+Leveraging BaseHTTPServer, this is a server that stores data posted to it in memory via POST requests as follows:
+ curl -XPOST http://localhost:8081 -H "Content-Type:application/json" -d '{"data2":"val"}'
+Retrieve the values in either html or csv as follows:
+ curl http://localhost:8081/data.(csv|html)
+
+
+Start the server as follows:
+ python app.py port host
+
+or with default values 8081 and 0.0.0.0:
+ python app.py
+
+Install with the following:
+ python setup.py install
File renamed without changes.
@@ -0,0 +1,28 @@
+import argparse
+import time
+from storagejsonhandler import StorageJSONHandler,MultiThreadedHTTPServer
+parser = argparse.ArgumentParser(description='Start the server.')
+parser.add_argument('--port', type=int,default=8081,nargs='+',
+ help='port to bind to')
+parser.add_argument('--host', type=str,default='0.0.0.0',nargs='+',
+ help='host to bind to')
+"""
+Was going to add support for appending values, turns out it's strange to initialize the replace parameter in there, would have to do it in the server.
+I'll add it later.
+parser.add_argument('replace', type=bool,default=True,
+ help='whether to replace values or not')
+"""
+args = parser.parse_args()
+PORT_NUMBER = args.port
+HOST_NAME = args.host
+
+server_class = MultiThreadedHTTPServer
+handler = StorageJSONHandler
+httpd = server_class((HOST_NAME, PORT_NUMBER), handler)
+print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
+try:
+ httpd.serve_forever()
+except KeyboardInterrupt:
+ pass
+httpd.server_close()
+print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)
@@ -0,0 +1,43 @@
+"""
+BaseStorage is an abstraction for a dictionary
+meant to store values depending if the user wants to append values to a list or
+replace the values
+"""
+class BaseStorage(object):
+
+ def __init__(self,replace=True):
+ self.dict = {}
+ self.replace = replace
+
+
+ def add(self,k,v):
+ if k not in self.dict:
+ self.dict[k] = v
+ print 'keys ' + ''.join(self.dict.keys())
+ elif( self.replace ):
+ self.dict[k] = v
+
+ elif k in self.dict:
+ v_original = self.dict[k]
+ if( isinstance(v,list) ):
+ for item in v:
+ v_original.append(item)
+ else:
+ newlist = []
+ newlist.append(v_original)
+ newlist.append(v)
+ self.dict[k]=newlist
+
+ def delete(self,k):
+ self.dict[k] = None
+
+
+ def get(self,k):
+ if k in self.dict :
+ return self.dict[k]
+ return None
+
+ def keys(self):
+ return self.dict.keys()
+ def entries(self):
+ return self.dict.items()
@@ -0,0 +1,123 @@
+import BaseHTTPServer
+import simplejson as json
+import time
+import sys
+import os
+import logging
+import threading
+from basestorage import BaseStorage
+import socket
+import multiprocessing
+from SocketServer import ThreadingMixIn
+from BaseHTTPServer import HTTPServer
+import getpass
+"""
+Multi threaded http server with a stoppable flag
+"""
+class MultiThreadedHTTPServer(ThreadingMixIn,HTTPServer,object):
+
+ def __init__(self,*args,**kwargs):
+ self.data = BaseStorage()
+ self.please_die = threading.Event()
+ super(MultiThreadedHTTPServer,self).__init__(*args,**kwargs)
+
+ def stop_server(self):
+ print 'stopping'
+ self.stop = True
+ self.shutdown()
+
+ def serve_forever (self):
+ """
+ Handle one request at a time until stopped.
+ """
+ print 'started server'
+ self.stop = False
+
+ while not self.stop:
+ self.handle_request()
+ print 'stopping 2'
+"""
+Request handler that stores values backed by BaseStorage
+This in turn is an abstraction of a dictionary that allows appending of values
+depending on a setting.
+"""
+class StorageJSONHandler(BaseHTTPServer.BaseHTTPRequestHandler,object):
+
+
+ def do_QUIT (self):
+ """
+ Send 200 OK response, and set server.stop to True.
+ """
+ self.send_response(200)
+ self.end_headers()
+ self.server.stop = True
+ self.server.please_die.set()
+
+
+ def do_GET(self):
+ """Respond to a GET request."""
+
+ self.send_response(200)
+ content_type = ''
+ if self.path == '/data.csv':
+ content_type = 'text/csv'
+
+
+ elif self.path == '/data.html':
+ content_type = 'text/html'
+
+ else:
+ content_type = 'text/html'
+ self.send_header("Content-Type", content_type )
+ self.end_headers()
+ output=''
+ print 'content ' + content_type
+
+ if content_type == 'text/html':
+ output= output + ("<!doctype html><html><head><title>Title goes here.</title></head>")
+ output= output + ("<body>")
+ output = output + '<table>'
+ for k,v in self.server.data.entries():
+ output = output + "<tr><td>%s</td>" % (k)
+ if isinstance(v,basestring):
+ print 'basestring'
+ output = output + '<td>' + str(v) + '</td>'
+
+ else:
+ for item in v:
+ output = output + '<td>' + str(item) + '</td>'
+
+ output = output + '</tr>'
+ output = output + "</table></body></html>"
+
+ elif content_type == 'text/csv':
+ for k,v in self.server.data.entries():
+ output= output + k + ', '
+ if isinstance(v,basestring):
+ output = output + str(v) + ','
+ else:
+ for item in v:
+ output = output + str(item) + ','
+ output = output[0:-1]
+ output= output + (unicode('\n'))
+
+ self.wfile.write(unicode(output))
+
+ def do_POST(self):
+ self.send_header("Content-Type","application/json")
+ print 'data so far ' + ','.join(self.server.data.keys())
+
+ self.wfile.write('{"status":"saved"}')
+ varLen = int(self.headers['Content-Length'])
+ postVars = unicode(self.rfile.read(varLen))
+
+ data = json.loads( postVars )
+ print 'adding data ' + postVars
+ for k in data:
+ self.server.data.add(k,data[k])
+
+ self.send_response(200)
+ self.end_headers()
+ self.wfile.write('{"status":"Sent"}')
+
+
View
@@ -0,0 +1,17 @@
+'''
+Created on Mar 13, 2013
+
+@author: agibsonccc
+'''
+#!/usr/bin/env python
+
+from distutils.core import setup
+
+setup(name='stored-server',
+ version='1.0',
+ description=' server that stores values in an in memory dictionary renderable by html or csv',
+ author='agibsonccc',
+ author_email='agibson@clevercloudcomputing.com',
+ url='https://github.com/agibsonccc/storedserver',
+ packages=['storedserver'],
+ )
View
No changes.
View
@@ -0,0 +1,28 @@
+import argparse
+import time
+from storagejsonhandler import StorageJSONHandler,MultiThreadedHTTPServer
+parser = argparse.ArgumentParser(description='Start the server.')
+parser.add_argument('--port', type=int,default=8081,nargs='+',
+ help='port to bind to')
+parser.add_argument('--host', type=str,default='0.0.0.0',nargs='+',
+ help='host to bind to')
+"""
+Was going to add support for appending values, turns out it's strange to initialize the replace parameter in there, would have to do it in the server.
+I'll add it later.
+parser.add_argument('replace', type=bool,default=True,
+ help='whether to replace values or not')
+"""
+args = parser.parse_args()
+PORT_NUMBER = args.port
+HOST_NAME = args.host
+
+server_class = MultiThreadedHTTPServer
+handler = StorageJSONHandler
+httpd = server_class((HOST_NAME, PORT_NUMBER), handler)
+print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
+try:
+ httpd.serve_forever()
+except KeyboardInterrupt:
+ pass
+httpd.server_close()
+print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)
@@ -0,0 +1,43 @@
+"""
+BaseStorage is an abstraction for a dictionary
+meant to store values depending if the user wants to append values to a list or
+replace the values
+"""
+class BaseStorage(object):
+
+ def __init__(self,replace=True):
+ self.dict = {}
+ self.replace = replace
+
+
+ def add(self,k,v):
+ if k not in self.dict:
+ self.dict[k] = v
+ print 'keys ' + ''.join(self.dict.keys())
+ elif( self.replace ):
+ self.dict[k] = v
+
+ elif k in self.dict:
+ v_original = self.dict[k]
+ if( isinstance(v,list) ):
+ for item in v:
+ v_original.append(item)
+ else:
+ newlist = []
+ newlist.append(v_original)
+ newlist.append(v)
+ self.dict[k]=newlist
+
+ def delete(self,k):
+ self.dict[k] = None
+
+
+ def get(self,k):
+ if k in self.dict :
+ return self.dict[k]
+ return None
+
+ def keys(self):
+ return self.dict.keys()
+ def entries(self):
+ return self.dict.items()
Oops, something went wrong.

0 comments on commit 31c7c19

Please sign in to comment.