gdp-if / rest-gateway / gdp-rest.py @ master
History | View | Annotate | Download (3.82 KB)
1 |
#!/usr/bin/env python
|
---|---|
2 |
|
3 |
from twisted.internet import reactor |
4 |
from twisted.web.resource import Resource |
5 |
from twisted.web.server import Site |
6 |
|
7 |
import urlparse |
8 |
import argparse |
9 |
import json |
10 |
import gdp |
11 |
|
12 |
|
13 |
class GDPWriterResource(Resource): |
14 |
|
15 |
isLeaf = True
|
16 |
|
17 |
def __init__(self, logname, keyfile, nolist, allow_nop, convert_num): |
18 |
|
19 |
Resource.__init__(self)
|
20 |
|
21 |
gdp.gdp_init() |
22 |
self.logname = logname
|
23 |
self.nolist = nolist
|
24 |
self.allow_nop = allow_nop
|
25 |
self.convert_num = convert_num
|
26 |
open_info = {} |
27 |
|
28 |
if keyfile is not None: |
29 |
skey = gdp.EP_CRYPTO_KEY(filename=keyfile, |
30 |
keyform=gdp.EP_CRYPTO_KEYFORM_PEM, |
31 |
flags=gdp.EP_CRYPTO_F_SECRET) |
32 |
open_info['skey'] = skey
|
33 |
|
34 |
self.gcl = gdp.GDP_GCL(gdp.GDP_NAME(logname), gdp.GDP_MODE_AO,
|
35 |
open_info=open_info) |
36 |
|
37 |
def __process(self, uri, d): |
38 |
|
39 |
if self.allow_nop == False and len(d.keys())==0: |
40 |
return "" |
41 |
|
42 |
if self.nolist == True: |
43 |
for k in d.keys(): |
44 |
d[k] = d[k][0]
|
45 |
|
46 |
if self.convert_num == True: |
47 |
for k in d.keys(): |
48 |
try:
|
49 |
d[k] = float(d[k])
|
50 |
except (TypeError, ValueError): |
51 |
pass
|
52 |
|
53 |
try:
|
54 |
d["_meta"] = uri
|
55 |
self.gcl.append({"data": json.dumps(d)}) |
56 |
return "Ok" |
57 |
except gdp.MISC.EP_STAT_Exception as e: |
58 |
return str(e) |
59 |
|
60 |
|
61 |
def render_GET(self, request): |
62 |
print "Received GET request:", request.uri, request.args |
63 |
return self.__process(request.uri, request.args) |
64 |
|
65 |
def render_PUT(self, request): |
66 |
print "Received PUT request:", request.uri, request.args |
67 |
return self.__process(request.uri, request.args) |
68 |
|
69 |
|
70 |
if __name__ == "__main__": |
71 |
|
72 |
# Set up argument parsing code
|
73 |
parser = argparse.ArgumentParser() |
74 |
parser.add_argument("-p", "--port", type=int, default=8080, |
75 |
help="TCP port to serve requests on, default=8080")
|
76 |
parser.add_argument("--nolist", action="store_true", default=False, |
77 |
help="Attempt to write a JSON object as a " + \
|
78 |
"key=>value format, as opposed to a " + \
|
79 |
"key=>[value] format. If an applicaiton " + \
|
80 |
"sends multiple values for the same key, " + \
|
81 |
"a random value will be picked. Default: False")
|
82 |
parser.add_argument("--allow-nop", action="store_true", default=False, |
83 |
help="Do not ignore requests that don't look " +\
|
84 |
"like a key-value pair. By default, any " + \
|
85 |
"requests that don't have a key=value pair " + \
|
86 |
"are ignored")
|
87 |
parser.add_argument("--convert-num", action="store_true", default=False, |
88 |
help="Do a best effort attempt to convert " + \
|
89 |
"values to numbers. Everything is a string, " + \
|
90 |
"otherwise. Does not make very much sense " + \
|
91 |
"without --nolist. Default: False")
|
92 |
parser.add_argument("-k", "--keyfile", |
93 |
help="Path to a signature key file for the log")
|
94 |
parser.add_argument("logname", help="Name of log") |
95 |
|
96 |
# Get the actual arguments
|
97 |
args = parser.parse_args() |
98 |
|
99 |
# Create a 'site' object to serve requests on
|
100 |
site = Site(GDPWriterResource(args.logname, args.keyfile, |
101 |
args.nolist, args.allow_nop, args.convert_num)) |
102 |
# Setup the reactor with the port
|
103 |
reactor.listenTCP(args.port, site) |
104 |
print "Starting REST interface on port %d, appending data to log %s" % \ |
105 |
(args.port, args.logname) |
106 |
reactor.run() |