Mercurial > hg > WSGraph
view wsgraph/web.py @ 17:1053290ba067
finish up this throwaway thing
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Mon, 10 Dec 2012 17:36:31 -0800 |
parents | 569a5d93b8e3 |
children | b710a2374c8d |
line wrap: on
line source
#!/usr/bin/env python """ web handler for WSGraph """ import json import sys from webob import Request, Response, exc # rank constants GRAPH = 0 NODE = 1 EDGE = 2 # XXX stubbing hacks class JSONformatter(object): def __init__(self, sort_keys=True): self.sort_keys = sort_keys def format(self, _object): return json.dumps(graph.node(node), sort_keys=self.sort_keys) def node(self, node, graph, request): return Response(body=self.format(graph.node(node))) def edge(self, node1, node2, graph, request): return Response(body=self.format(graph.edge(node))) class Dispatcher(object): def __init__(self, graph, graph_formatters=None, node_formatters=None, edge_formatters=None, require_auth=False): self.graph = graph self.require_auth = require_auth # use JSON formatter by default if graph_formatters is None: graph_formatters = {None: JSONGraphFormatter} if node_formatters is None: node_formatters = {None: JSONFormatter} if edge_formatters is None: edge_formatters = {None: JSONFormatter} # view formatters self.formatters = {GRAPH: graph_formatters, NODE: node_formatters, EDGE: edge_formatters} for key, value in self.formatters.items(): # ensure default formatter assert None in value self.methods = dict([(i, getattr(self, i)) for i in dir(self) if i.isupper()]) def __call__(self, environ, start_response): request = Request(environ) method = self.methods.get(request.method) if method is None: return exc.HTTPMethodNotAllowed()(environ, start_response) response = method(request) return response(environ, start_response) @staticmethod def path_segments(path): """split a path into segments""" segments = path.strip('/').split('/') if segments == ['']: segments = [] return segments # HTTP methods def GET(self, request): """ respond to a GET request Formatters are keyed off of formatters = {0: { } A graph formatter takes the following arguments: def sample_graph_formatter(graph, request): A node formatter takes the following arguments: def sample_node_formatter(node, graph, request): An edge formatter takes the following arguments: def sample_edge_formatter(edge, graph, request): API: ?format=<format> """ # get resource requestor segments = self.path_segments(request.path_info) rank = len(segments) if rank not in (0,1,2): return exc.HTTPNotFound() # is resource in the graph? if (rank == EDGE) or (rank == NODE): if tuple(segments) not in self.graph: return exc.HTTPNotFound() # formatter formatter = self.formatters[len(segments)] return Response(content_type='text/plain', body="WSGraph") def POST(self, request): """ respond to a POST request API: ?update : """ return exc.HTTPSeeOther(location='/') # TODO: /path/to/self def HEAD(self, request): """respond to a HEAD request""" raise NotImplementedError def OPTIONS(self, request): return Response() # TODO: Allow=', '.join(self.methods); Content-Length=0 def main(args=sys.argv[1:]): """example web server""" # imports from wsgiref import simple_server from model import MemoryCache from optparse import OptionParser # parse command line options parser = OptionParser() parser.add_option('-p', '--port', type='int', default=8080, help="port to serve on") options, args = parser.parse_args() # example model graph = MemoryCache() # WSGI app app = Dispatcher(graph=graph) server = simple_server.make_server(host='0.0.0.0', port=options.port, app=app) print 'http://localhost:%s/' % options.port server.serve_forever() if __name__ == '__main__': main()