-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathget_old_polls.py
106 lines (86 loc) · 3.21 KB
/
get_old_polls.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
import boto3
import time
import json
import decimal
dynamodb = boto3.resource('dynamodb')
responseHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials' : True }
class DecimalEncoder(json.JSONEncoder):
"""Helper class to convert a DynamoDB decimal/item to JSON
"""
def default(self, o):
if isinstance(o, decimal.Decimal):
if o % 1 > 0:
return float(o)
else:
return int(o)
return super(DecimalEncoder, self).default(o)
def batch_get_item_polls(keys, second_attempt = False):
"""Performs batch get items on polls table, if the first attempt failed or has unprocessed keys tries again.
Parameters:
keys: List with keys of polls.
second_attempt: Flag for the second attempt.
Returns:
List with max 4 polls.
"""
result = []
if len(keys) != 0:
try:
response = dynamodb.batch_get_item(
RequestItems={
'fp.polls': {
'Keys': keys
}
}
)
except Exception:
if second_attempt:
raise Exception('Database error!')
# tries again if the first attempt failed
time.sleep(1)
return batch_get_item_polls(keys, True)
# successful response
if ('Responses' in response) and ('fp.polls' in response['Responses']):
result = response['Responses']['fp.polls']
if (not second_attempt) and ('UnprocessedKeys' in response) and ('fp.polls' in response['UnprocessedKeys']) and ('Keys' in response['UnprocessedKeys']['fp.polls']):
# tries again if there are unprocessed keys
try:
time.sleep(1)
second_result = batch_get_item_polls(response['UnprocessedKeys']['fp.polls']['Keys'], True)
except Exception:
raise Exception('Database error!')
result.append(second_result)
return result
def get_old_polls(event, context):
"""Returns at most 5 polls older than the last_poll.
Returns:
List of max 5 polls.
"""
if (event['queryStringParameters'] is None) or ('last_poll' not in event['queryStringParameters']):
return {
'statusCode': 400,
'headers': responseHeaders,
'body': json.dumps({'errorMessage': 'last_poll parameter doesn\'t exist in the API call!'})
}
try:
last_poll = int(event['queryStringParameters']['last_poll'])
except:
return {
'statusCode': 400,
'headers': responseHeaders,
'body': json.dumps({'errorMessage': 'last_poll value is not an integer number!'})
}
first_poll = max(last_poll - 5, 0)
keys = [{'id': id} for id in range(first_poll, last_poll)]
try:
polls = batch_get_item_polls(keys)
except Exception:
return {
'statusCode': 500,
'headers': responseHeaders,
'body': json.dumps({'errorMessage': 'Database error!'})
}
return {
'statusCode': 200,
'headers': responseHeaders,
'body': json.dumps(polls, cls=DecimalEncoder, ensure_ascii=False)
}