Mercurial > hg > WSGraph
annotate wsgraph/web.py @ 5:9d5a8c90c482
more stubbing
| author | Jeff Hammel <jhammel@mozilla.com> |
|---|---|
| date | Mon, 10 Dec 2012 07:54:10 -0800 |
| parents | c7170cab1184 |
| children | 259210f2e029 |
| rev | line source |
|---|---|
| 0 | 1 #!/usr/bin/env python |
| 2 | |
| 3 """ | |
| 4 web handler for WSGraph | |
| 5 """ | |
| 6 | |
| 7 import json | |
| 8 from webob import Request, Response, exc | |
| 9 | |
| 5 | 10 # rank constants |
| 4 | 11 GRAPH = 0 |
| 12 NODE = 1 | |
| 13 EDGE = 2 | |
| 14 | |
| 5 | 15 # XXX stubbing hacks |
| 0 | 16 def JSONFormatter(**kwargs): |
| 17 return json.dumps(kwargs, sort_keys=True) | |
| 18 def JSONGraphFormatter(graph): | |
| 19 return json.dumps({'nodes': graph.nodes(), | |
| 20 'edges': graph.edges()}, | |
| 21 sort_keys=True) | |
| 22 | |
| 23 class Dispatcher(object): | |
| 24 | |
| 25 def __init__(self, graph, | |
| 5 | 26 graph_formatters=None, |
| 27 node_formatters=None, | |
| 28 edge_formatters=None, | |
| 0 | 29 require_auth=False): |
| 30 self.graph = graph | |
| 31 self.require_auth = require_auth | |
| 5 | 32 |
| 33 # use JSON formatter by default | |
| 34 if graph_formatters is None: | |
| 35 graph_formatters = {None: JSONGraphFormatter} | |
| 36 if node_formatters is None: | |
| 37 node_formatters = {None: JSONFormatter} | |
| 38 if edge_formatters is None: | |
| 39 edge_formatters = {None: JSONFormatter} | |
| 40 | |
| 41 self.formatters = {GRAPH: graph_formatters, | |
| 42 NODE: node_formatters, | |
| 43 EDGE: edge_formatters} | |
| 44 for key, value in formatters.items(): | |
| 45 # ensure default formatter | |
| 46 assert None in value | |
| 0 | 47 |
| 3 | 48 self.methods = dict([(i, getattr(self, i)) |
| 49 for i in dir(self) | |
| 50 if i.isupper()]) | |
| 51 | |
| 0 | 52 def __call__(self, environ, start_response): |
| 53 request = Request(environ) | |
| 3 | 54 method = self.methods.get(request.method) |
| 55 if method is None: | |
| 56 return exc.HTTPMethodNotAllowed()(environ, start_response) | |
| 57 response = method(request) | |
| 0 | 58 return response(environ, start_response) |
| 59 | |
| 60 @staticmethod | |
| 5 | 61 def path_segments(path): |
| 62 """split a path into segments""" | |
| 63 segments = path.strip('/').split('/') | |
| 64 if segments == ['']: | |
| 65 segments = [] | |
| 66 return segments | |
| 0 | 67 |
| 68 # HTTP methods | |
| 69 | |
| 70 def GET(self, request): | |
|
2
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
71 """ |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
72 respond to a GET request |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
73 |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
74 Formatters are keyed off of |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
75 |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
76 formatters = {0: { |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
77 } |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
78 |
| 4 | 79 A graph formatter takes the following arguments: |
| 80 | |
| 81 def sample_graph_formatter(graph, request): | |
| 82 | |
|
2
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
83 API: |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
84 |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
85 ?format=<format> |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
86 |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
87 """ |
| 0 | 88 |
| 5 | 89 segments = self.path_segments(request.path_info) |
| 4 | 90 if len(segments) not in (0,1,2): |
| 91 return exc.HTTPNotFound() | |
| 0 | 92 |
| 93 # formatter | |
| 94 formatter = self.formatters[len(segments)] | |
| 95 return Response(content_type='text/plain', | |
| 96 body="WSGraph") | |
| 97 | |
| 98 def POST(self, request): | |
|
2
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
99 """ |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
100 respond to a POST request |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
101 |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
102 API: |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
103 |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
104 ?update : |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
105 """ |
|
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
106 |
| 4 | 107 return exc.HTTPSeeOther(location='/') # TODO: /path/to/self |
| 0 | 108 |
| 109 def HEAD(self, request): | |
| 110 """respond to a HEAD request""" | |
| 111 raise NotImplementedError | |
| 112 | |
| 3 | 113 def OPTIONS(self, request): |
| 4 | 114 return Response() # TODO: Allow=', '.join(self.methods); Content-Length=0 |
| 3 | 115 |
| 0 | 116 if __name__ == '__main__': |
| 117 | |
| 3 | 118 ### example web server |
| 119 | |
| 0 | 120 # imports |
| 121 from wsgiref import simple_server | |
| 3 | 122 from model import MemoryCache |
| 123 from optparse import OptionParser | |
| 0 | 124 |
| 3 | 125 # parse command line options |
| 126 parser = OptionParser() | |
| 127 parser.add_option('-p', '--port', type='int', default=8080, | |
| 128 help="port to serve on") | |
| 129 options, args = parser.parse_args() | |
| 130 | |
| 131 # example model | |
| 0 | 132 graph = MemoryCache() |
| 133 | |
| 3 | 134 # WSGI app |
| 0 | 135 app = Dispatcher(graph=graph) |
| 3 | 136 server = simple_server.make_server(host='0.0.0.0', port=options.port, app=app) |
| 137 print 'http://localhost:%s/' % options.port | |
| 0 | 138 server.serve_forever() |
| 139 |
