-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
90 lines (71 loc) · 2.41 KB
/
app.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
from count_me_up import CountMeUp
import json
import atexit
import threading
from flask import Flask, request
# Create new CountMeUp object
counter = CountMeUp()
# Time interval between calling counter.process_vote
pool_time = 0.01
# lock to control access to variable
lock = threading.Lock()
# thread handler
thread = threading.Thread()
def create_app():
"""
Each process_votes method in turn calls the counter.process_vote to process a single vote from the queue.
It then runs itself concurrently within a thread.
The Flask web app exposes API to add new votes and to display the candidate vote statistics.
However, the processing of new user votes operates on the same CountMeUp object as Flask, therefore it needs to be
ran as a background thread executed at every pool_time interval.
:return: Flask web application instance
"""
# Create a flask app
app = Flask(__name__)
def interrupt_thread():
global thread
thread.cancel()
def process_votes():
global counter
global thread
with lock:
# Process a single vote from the queue
counter.process_vote()
# Start next thread to process a vote again in the next time interval
thread = threading.Timer(pool_time, process_votes, ())
thread.start()
def initialise_process():
# Create the thread for the first time and run it
global thread
thread = threading.Timer(pool_time, process_votes, ())
thread.start()
initialise_process()
# After the Flask web app is closed, clear the old thread
atexit.register(interrupt_thread)
return app
app = create_app()
@app.route('/')
def check_candidate_votes():
"""
:return: API call will return the current candidate statistics
"""
return json.dumps(counter.candidate_votes)
@app.route('/clear_votes/')
def clear_votes():
"""
Will reset the candidate vote statistics
"""
counter.candidate_votes = {1:0, 2:0, 3:0, 4:0, 5:0}
return "Votes cleared"
@app.route('/submit', methods=['GET'])
def submit_vote():
"""
API call will add the user and his vote to the current vote queue
"""
user = request.args.get('user', None)
candidate = request.args.get('candidate', None)
counter.add_vote(str(user), int(candidate))
return user + ' ' + candidate
if __name__ == "__main__":
print('Flask starting to run')
app.run()