/
main.py
194 lines (143 loc) · 6.01 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/usr/bin/env python
import os
import random
import time as timer
from datetime import datetime, timedelta
import tornado.web
import tornado.wsgi
from google.appengine.ext import db
import models
import utils
import precompute
# initialize users and events
if models.User.all().count() == 0:
models.initialize_db()
MAX_NUMBER_OF_EVENTS = 500
class MainHandler(tornado.web.RequestHandler):
def get(self):
err = {}
user_id = self.get_argument("user_id", None)
if not user_id:
err["message"] = "Please append query parameter /?user_id=<int>"
err["user_id"] = user_id
self.write(utils.json_encode(err))
else:
pipeline = precompute.EventCountPipeline(user_id)
pipeline.start()
self.redirect(pipeline.base_path + "/status?root=" + pipeline.pipeline_id)
class EventApiHandler(tornado.web.RequestHandler):
def get(self, user_id):
"""
Return the number of events of a user.
:Arguments:
user_id : int
User id
time : str
Time represents ``minutes``, ``days``, ``hours``, ``weeks`` in datetime.timedelta() eg. datetime.timedelta(days=7)
delta : int
Delta is any int value for datetime.timedelta() eg. datetime.timedelta(days=7)
If no valid time query argument is provided, it will show the user events count.
"""
start = timer.time()
user = models.User.all().filter("id =",int(user_id)).get()
if not user:
raise tornado.web.HTTPError(404)
time = self.get_argument("time", None)
delta = self.get_argument("delta", 0)
# get last x hours, days, weeks, months
last_x_time = datetime.now() - utils.timedelta_wrapper(time, int(delta))
# get events from the last x time
events_from_last_x_time = filter(lambda x: x.created >= last_x_time, [event for event in user.user_events] )
data = {}
if not time:
# show all events for user
data["description"] = "Number of events for User %s" % (str(user_id))
data["load_time"] = timer.time() - start
data["events"] = user.user_events.count()
else:
data["description"] = "Number of events for User %s for the last %s %s" % (str(user_id), str(delta), str(time))
data["load_time"] = timer.time() - start
data["grouping"] = utils.filter_by(time, events_from_last_x_time, last_x_time)
self.write(utils.json_encode(data))
class EventApiSaveHandler(tornado.web.RequestHandler):
def post(self, user_id, eventname):
"""
Store the event and associate it to a user identified by user_id
:Arguments:
user_id : int
User id
event_name : str
Any string representing an event
"""
existing = models.User.all().filter("id =", int(user_id)).get()
if not existing:
raise tornado.web.HTTPError(400)
else:
event = models.Event(user=existing, name=eventname)
event.put()
self.set_status(201)
class GenerateRandomEventsHandler(tornado.web.RequestHandler):
def get(self):
"""Batch delete."""
start = timer.time()
count = int( models.Event.all().count() );
# check if there is something to delete
if count > 0:
db.delete([item for item in models.Event.all()])
if models.Event.all().count() == 0:
self.write( utils.json_encode({
'message':'All events succesfully deleted.',
'load_time': timer.time() - start
}) )
else:
self.write( utils.json_encode({
'message':'Delete failed. Try again.',
'load_time': timer.time() - start
}) )
def post(self):
"""
Generate randmomized events for a user.
:Arguments:
user_id : int
User id
num_of_events : int
Number of events to generate, max of 100,000 per request
time : str
Time represents ``minutes``, ``days``, ``hours``, ``weeks`` in datetime.timedelta() eg. datetime.timedelta(days=7)
delta : int
Delta is any int value for datetime.timedelta() eg. datetime.timedelta(days=7)
"""
start = timer.time()
time = self.get_argument("time", None)
delta = self.get_argument("delta", 0)
num_of_events = self.get_argument("num_of_events", 0)
user_id = self.get_argument("user_id", 0)
time = str(time) if time in ['minutes','hours','days','weeks'] else None
if not time:
raise tornado.web.HTTPError(404)
user = models.User.all().filter("id =",int(user_id)).get()
if not user:
raise tornado.web.HTTPError(404)
if int(num_of_events) > MAX_NUMBER_OF_EVENTS:
num_of_events = MAX_NUMBER_OF_EVENTS
now = datetime.now()
for i in xrange(1,int(num_of_events)+1):
r = random.randrange(1,int(delta))
e = models.Event(user=user,
name='Event'+str(r),
created=now - utils.timedelta_wrapper(time, int(r)) )
e.put()
d = {}
d["load_time"] = timer.time() - start
d["count"] = models.Event.all().count()
return self.write(utils.json_encode(d))
settings = {
"title": u"Restful Json Api",
"debug": os.environ.get('SERVER_SOFTWARE', '').startswith('Dev'),
}
application = tornado.wsgi.WSGIApplication([
(r"/", MainHandler),
(r"/api/v1/events/randomize", GenerateRandomEventsHandler),
(r"/api/v1/events/([0-9]+)", EventApiHandler),
(r"/api/v1/events/([0-9]+)/([\w]+)", EventApiSaveHandler),
], **settings)