Mercurial > hg > WSGraph
annotate wsgraph/web.py @ 6:259210f2e029
more formatter stubbing
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Mon, 10 Dec 2012 13:48:11 -0800 |
parents | 9d5a8c90c482 |
children | 9016b126aa87 |
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 |
6 | 16 def JSONFormatter(node, graph, request): |
17 return json.dumps(graph.node(node), sort_keys=True) | |
18 def JSONGraphFormatter(graph, request): | |
0 | 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 | |
6 | 81 def sample_graph_formatter(graph, request): |
82 | |
83 A node formatter takes the following arguments: | |
84 | |
85 def sample_node_formatter(node, graph, request): | |
86 | |
87 An edge formatter takes the following arguments: | |
88 | |
89 def sample_edge_formatter(edge, graph, request): | |
4 | 90 |
2
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
91 API: |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
92 |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
93 ?format=<format> |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
94 |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
95 """ |
0 | 96 |
5 | 97 segments = self.path_segments(request.path_info) |
4 | 98 if len(segments) not in (0,1,2): |
99 return exc.HTTPNotFound() | |
0 | 100 |
101 # formatter | |
102 formatter = self.formatters[len(segments)] | |
103 return Response(content_type='text/plain', | |
104 body="WSGraph") | |
105 | |
106 def POST(self, request): | |
2
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
107 """ |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
108 respond to a POST request |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
109 |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
110 API: |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
111 |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
112 ?update : |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
113 """ |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
114 |
4 | 115 return exc.HTTPSeeOther(location='/') # TODO: /path/to/self |
0 | 116 |
117 def HEAD(self, request): | |
118 """respond to a HEAD request""" | |
119 raise NotImplementedError | |
120 | |
3 | 121 def OPTIONS(self, request): |
4 | 122 return Response() # TODO: Allow=', '.join(self.methods); Content-Length=0 |
3 | 123 |
0 | 124 if __name__ == '__main__': |
125 | |
3 | 126 ### example web server |
127 | |
0 | 128 # imports |
129 from wsgiref import simple_server | |
3 | 130 from model import MemoryCache |
131 from optparse import OptionParser | |
0 | 132 |
3 | 133 # parse command line options |
134 parser = OptionParser() | |
135 parser.add_option('-p', '--port', type='int', default=8080, | |
136 help="port to serve on") | |
137 options, args = parser.parse_args() | |
138 | |
139 # example model | |
0 | 140 graph = MemoryCache() |
141 | |
3 | 142 # WSGI app |
0 | 143 app = Dispatcher(graph=graph) |
3 | 144 server = simple_server.make_server(host='0.0.0.0', port=options.port, app=app) |
145 print 'http://localhost:%s/' % options.port | |
0 | 146 server.serve_forever() |
147 |