Mercurial > personal > weather-server
annotate weather_server/server.py @ 9:f1ea183d28ba
Give a 404 rather than a 500 on missing locations.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sun, 29 Sep 2019 20:34:38 -0400 |
parents | d54155a199d8 |
children | 52ef21607b31 |
rev | line source |
---|---|
4
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
1 import hmac |
5
368f732f13d0
Actually make the server runnable.
Paul Fisher <paul@pfish.zone>
parents:
4
diff
changeset
|
2 import sys |
4
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
3 |
1
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
4 import bson |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
5 import flask |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
6 |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
7 from . import common |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
8 from . import locations |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
9 from . import types |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
10 |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
11 |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
12 def build_app(root_directory: str) -> flask.Flask: |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
13 locs = locations.Locations(root_directory) |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
14 app = flask.Flask(__name__) |
8
d54155a199d8
Improve template; add stylesheet.
Paul Fisher <paul@pfish.zone>
parents:
5
diff
changeset
|
15 app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 |
1
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
16 |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
17 @app.route('/favicon.ico') |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
18 def favicon(): |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
19 return flask.send_file('static/favicon.ico') |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
20 |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
21 @app.route('/') |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
22 def home(): |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
23 return 'Weather server' |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
24 |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
25 @app.route('/_submit', methods=['POST']) |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
26 def submit(): |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
27 req = flask.request |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
28 reader = bson.decode_file_iter( |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
29 req.stream, codec_options=common.BSON_OPTIONS) |
3
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
30 try: |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
31 preamble = next(reader) |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
32 loc_name = preamble['location'] |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
33 password = str(preamble['password']) |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
34 loc, logger = locs.get(loc_name) |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
35 if not hmac.compare_digest(password, loc.password): |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
36 flask.abort(400) |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
37 entries = [ |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
38 types.Reading.from_now( |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
39 sample_time=item['sample_time'], |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
40 temp_c=item['temp_c'], |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
41 rh_pct=item['rh_pct'], |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
42 ) |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
43 for item in reader |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
44 ] |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
45 except (KeyError, bson.InvalidBSON): |
b42c4bfe57c7
server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents:
2
diff
changeset
|
46 flask.abort(400) |
2
cda47993a193
server: fix bugs and improve template.
Paul Fisher <paul@pfish.zone>
parents:
1
diff
changeset
|
47 logger.write_rows(entries) |
cda47993a193
server: fix bugs and improve template.
Paul Fisher <paul@pfish.zone>
parents:
1
diff
changeset
|
48 return flask.jsonify({'status': 'OK'}) |
1
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
49 |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
50 @app.route('/<location>') |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
51 def show(location): |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
52 try: |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
53 loc, logger = locs.get(location) |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
54 except KeyError: |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
55 flask.abort(404) |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
56 data = logger.data |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
57 if data: |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
58 last_reading = data[-1] |
2
cda47993a193
server: fix bugs and improve template.
Paul Fisher <paul@pfish.zone>
parents:
1
diff
changeset
|
59 tz = loc.timezone() |
1
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
60 date = tz.normalize(last_reading.sample_time.astimezone(tz)) |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
61 else: |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
62 last_reading = None |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
63 date = None |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
64 return flask.render_template( |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
65 'location.html', |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
66 location=loc, |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
67 last_reading=last_reading, |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
68 date=date) |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
69 |
f66df122f18d
get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
70 return app |
4
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
71 |
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
72 |
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
73 def main(argv): |
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
74 """Main function for a simple local demo.""" |
5
368f732f13d0
Actually make the server runnable.
Paul Fisher <paul@pfish.zone>
parents:
4
diff
changeset
|
75 app = build_app(argv[0]) |
4
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
76 app.run(host='0.0.0.0') |
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
77 |
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
78 |
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
79 if __name__ == '__main__': |
e7c8dcc5fc15
Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents:
3
diff
changeset
|
80 main(sys.argv[1:]) |