-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.py
98 lines (72 loc) · 3.11 KB
/
api.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
#!/usr/bin/python
import argparse
import json
from datetime import datetime
from bson import objectid
from common import DbRepo
from flask import Flask, render_template, request, redirect, url_for
'''In a production solution, you will not want to use the development
web server. You may want authentication as well. Check out these links
for more information'''
# Host in Tornado: http://hilpisch.com/rpi/03_web_apps.html
# Basic Auth: http://flask.pocoo.org/snippets/8/
# The Flask class is a WSGI application
app = Flask(__name__)
class CustomEncoder(json.JSONEncoder):
"""A C{json.JSONEncoder} subclass to encode documents that have fields of
type C{bson.objectid.ObjectId}, C{datetime.datetime}"""
def default(self, obj):
if isinstance(obj, objectid.ObjectId):
return str(obj)
elif isinstance(obj, datetime):
return obj.isoformat()
return json.JSONEncoder.default(self, obj)
# app.route() decorator routes requests for a URL to a Python function
@app.route('/')
def index():
repo = DbRepo()
locs = repo.get_locations()
# Quick dev - just string together some anchor tags; most browsers won't complain.
# Don't do this in the real world.
bein_lazy = ['<a href="./dashboard/for/{0}">{0}</a> - {1} measurements, last on {2}'.format(x["_id"], x["num_of_measures"], x['most_recent']) for x in locs]
return '<br />'.join(bein_lazy), 200
# Example of providing default rounds
@app.route('/api/recent/<where>', defaults={'max': 10})
@app.route('/api/recent/<where>/<int:max>')
def recent(where, max):
repo = DbRepo()
results = repo.query_recent_measurements(where, max)
enc = CustomEncoder()
# Return the results as JSON
return enc.encode(results), 200, {'Content-Type': 'text/json; charset=utf-8'}
@app.route('/api/stats/<where>')
def stats(where):
repo = DbRepo()
results = repo.get_stats(where)
enc = CustomEncoder()
return enc.encode(results), 200, {'Content-Type': 'text/json; charset=utf-8'}
@app.route('/dashboard/for/<where>')
def dashboard(where):
"""Flask can actually serve web pages too. It uses Jinja2 templates"""
# http://flask.pocoo.org/docs/0.10/tutorial/templates/
repo = DbRepo()
results = repo.get_stats(where)
return render_template('dashboard.html', ctx={'data': results, 'target_temp_c': repo.get_target_temp()})
@app.route('/dashboard/target-temp/', methods=['POST'])
def set_target_temp():
repo = DbRepo()
try:
temp_c = float(request.form['temp_c'])
except ValueError:
temp_c = None
repo.set_target_temp(temp_c)
return redirect(request.form['redirect_url'])
if __name__ == '__main__':
# Parse command line arguments to get server settings
parser = argparse.ArgumentParser(
description="Starts the Fermonitor API",
prog="api.py")
parser.add_argument('--d', '--debug', help='Launches API web server in debug mode. DEFAULT %(default)s', default=False, action='store_true')
args = parser.parse_args()
# Start the Flask web server; host='0.0.0.0' exposes the endpoints externally.
app.run(host='0.0.0.0', debug=args.d)