Mercurial > hg > WSGraph
annotate 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 |
rev | line source |
---|---|
0 | 1 #!/usr/bin/env python |
2 | |
3 """ | |
4 web handler for WSGraph | |
5 """ | |
6 | |
7 import json | |
12
421d5119e324
reluctantly make this a CLI entry point
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
8 import sys |
0 | 9 from webob import Request, Response, exc |
10 | |
5 | 11 # rank constants |
4 | 12 GRAPH = 0 |
13 NODE = 1 | |
14 EDGE = 2 | |
15 | |
5 | 16 # XXX stubbing hacks |
7 | 17 class JSONformatter(object): |
18 def __init__(self, sort_keys=True): | |
19 self.sort_keys = sort_keys | |
20 | |
21 def format(self, _object): | |
22 return json.dumps(graph.node(node), sort_keys=self.sort_keys) | |
23 | |
24 def node(self, node, graph, request): | |
25 return Response(body=self.format(graph.node(node))) | |
26 | |
17
1053290ba067
finish up this throwaway thing
Jeff Hammel <jhammel@mozilla.com>
parents:
16
diff
changeset
|
27 def edge(self, node1, node2, graph, request): |
1053290ba067
finish up this throwaway thing
Jeff Hammel <jhammel@mozilla.com>
parents:
16
diff
changeset
|
28 return Response(body=self.format(graph.edge(node))) |
0 | 29 |
30 class Dispatcher(object): | |
31 | |
32 def __init__(self, graph, | |
5 | 33 graph_formatters=None, |
34 node_formatters=None, | |
35 edge_formatters=None, | |
0 | 36 require_auth=False): |
37 self.graph = graph | |
38 self.require_auth = require_auth | |
5 | 39 |
40 # use JSON formatter by default | |
41 if graph_formatters is None: | |
42 graph_formatters = {None: JSONGraphFormatter} | |
13
7459702bf574
mostly spacing fix + comment
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
43 if node_formatters is None: |
5 | 44 node_formatters = {None: JSONFormatter} |
13
7459702bf574
mostly spacing fix + comment
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
45 if edge_formatters is None: |
5 | 46 edge_formatters = {None: JSONFormatter} |
47 | |
13
7459702bf574
mostly spacing fix + comment
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
48 # view formatters |
5 | 49 self.formatters = {GRAPH: graph_formatters, |
50 NODE: node_formatters, | |
51 EDGE: edge_formatters} | |
16 | 52 for key, value in self.formatters.items(): |
5 | 53 # ensure default formatter |
54 assert None in value | |
0 | 55 |
3 | 56 self.methods = dict([(i, getattr(self, i)) |
57 for i in dir(self) | |
58 if i.isupper()]) | |
59 | |
0 | 60 def __call__(self, environ, start_response): |
61 request = Request(environ) | |
3 | 62 method = self.methods.get(request.method) |
63 if method is None: | |
64 return exc.HTTPMethodNotAllowed()(environ, start_response) | |
65 response = method(request) | |
0 | 66 return response(environ, start_response) |
67 | |
68 @staticmethod | |
5 | 69 def path_segments(path): |
70 """split a path into segments""" | |
71 segments = path.strip('/').split('/') | |
72 if segments == ['']: | |
73 segments = [] | |
74 return segments | |
0 | 75 |
76 # HTTP methods | |
77 | |
78 def GET(self, request): | |
2
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
79 """ |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
80 respond to a GET request |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
81 |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
82 Formatters are keyed off of |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
83 |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
84 formatters = {0: { |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
85 } |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
86 |
4 | 87 A graph formatter takes the following arguments: |
88 | |
6 | 89 def sample_graph_formatter(graph, request): |
90 | |
91 A node formatter takes the following arguments: | |
92 | |
93 def sample_node_formatter(node, graph, request): | |
94 | |
95 An edge formatter takes the following arguments: | |
96 | |
97 def sample_edge_formatter(edge, graph, request): | |
4 | 98 |
2
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
99 API: |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
100 |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
101 ?format=<format> |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
102 |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
103 """ |
0 | 104 |
7 | 105 # get resource requestor |
5 | 106 segments = self.path_segments(request.path_info) |
12
421d5119e324
reluctantly make this a CLI entry point
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
107 rank = len(segments) |
421d5119e324
reluctantly make this a CLI entry point
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
108 if rank not in (0,1,2): |
4 | 109 return exc.HTTPNotFound() |
0 | 110 |
17
1053290ba067
finish up this throwaway thing
Jeff Hammel <jhammel@mozilla.com>
parents:
16
diff
changeset
|
111 # is resource in the graph? |
12
421d5119e324
reluctantly make this a CLI entry point
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
112 if (rank == EDGE) or (rank == NODE): |
421d5119e324
reluctantly make this a CLI entry point
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
113 if tuple(segments) not in self.graph: |
14 | 114 return exc.HTTPNotFound() |
7 | 115 |
0 | 116 # formatter |
117 formatter = self.formatters[len(segments)] | |
118 return Response(content_type='text/plain', | |
119 body="WSGraph") | |
120 | |
121 def POST(self, request): | |
2
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
122 """ |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
123 respond to a POST request |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
124 |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
125 API: |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
126 |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
127 ?update : |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
128 """ |
7a3b21cafc00
start to sketch out REST API
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
129 |
4 | 130 return exc.HTTPSeeOther(location='/') # TODO: /path/to/self |
0 | 131 |
132 def HEAD(self, request): | |
133 """respond to a HEAD request""" | |
134 raise NotImplementedError | |
135 | |
3 | 136 def OPTIONS(self, request): |
4 | 137 return Response() # TODO: Allow=', '.join(self.methods); Content-Length=0 |
3 | 138 |
0 | 139 |
12
421d5119e324
reluctantly make this a CLI entry point
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
140 def main(args=sys.argv[1:]): |
421d5119e324
reluctantly make this a CLI entry point
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
141 """example web server""" |
3 | 142 |
0 | 143 # imports |
144 from wsgiref import simple_server | |
3 | 145 from model import MemoryCache |
146 from optparse import OptionParser | |
0 | 147 |
3 | 148 # parse command line options |
149 parser = OptionParser() | |
150 parser.add_option('-p', '--port', type='int', default=8080, | |
151 help="port to serve on") | |
152 options, args = parser.parse_args() | |
153 | |
154 # example model | |
0 | 155 graph = MemoryCache() |
156 | |
3 | 157 # WSGI app |
0 | 158 app = Dispatcher(graph=graph) |
3 | 159 server = simple_server.make_server(host='0.0.0.0', port=options.port, app=app) |
160 print 'http://localhost:%s/' % options.port | |
0 | 161 server.serve_forever() |
162 | |
12
421d5119e324
reluctantly make this a CLI entry point
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
163 if __name__ == '__main__': |
421d5119e324
reluctantly make this a CLI entry point
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
164 main() |