-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
131 lines (101 loc) · 3.91 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
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
import os
from os import path
from flask import Flask
from dotenv import load_dotenv
from flask_caching import Cache
import requests
cache = Cache()
app = Flask(__name__, static_folder='build/', static_url_path='/')
app.debug = 'DEBUG' in os.environ
app.config['CACHE_TYPE'] = 'SimpleCache'
cache.init_app(app)
# Load environment variables from .env if exists (during local debug mode)
if os.path.exists('.env'):
load_dotenv('.env')
# API url TODO use flask.Config? https://flask.palletsprojects.com/en/2.0.x/api/#flask.Config
URL_NOAA_API = "https://www.ncdc.noaa.gov/cdo-web/api/v2"
# shared method to send requests using NOAA CDO token
def sendNoaaCdoRequest(url):
return requests.get(
url, headers={"token": os.environ['TOKEN_NOAA_NCDC_CDO']})
def responseContainsJSON(response):
return response.headers.get('content-type') == 'application/json'
@app.errorhandler(404)
def not_found(e):
return app.send_static_file('index.html')
@app.route('/')
def index():
return app.send_static_file('index.html')
@app.route('/api/noaa/data/daily/<data_type>/<location_id>/<start_date>/<end_date>')
@cache.cached(9999999999)
def get_noaa_ghcnd_data(data_type=None, location_id=None, start_date=None, end_date=None):
# Setup the request url
url = URL_NOAA_API
url += "/data?"
url += "datasetid=GHCND"
url += "&datatypeid=" + data_type
# Location code:
url += "&locationid=" + location_id
# Get results in Farenheight
url += "&units=standard"
# Set time range
url += "&startdate=" + start_date
url += "&enddate=" + end_date
url += "&limit=1000"
# send the GET request with auth token header
response = sendNoaaCdoRequest(url)
if responseContainsJSON(response):
return response.json()
else:
return { 'error': response.status_code }
@app.route('/api/locations/get/stations/<location_id>')
@cache.cached(9999999999)
def get_stations_in_location(location_id=None):
# print('getting the stations for location', location_id)
results_list = []
total_count = 1000
while len(results_list) < total_count:
url = url = URL_NOAA_API
url += "/stations?"
url += "locationid=" + location_id
#url += "&sortfield=name"
#url += "&sortorder=asc"
url += "&limit=1000"
url += "&offset=" + str(len(results_list))
response = sendNoaaCdoRequest(url)
if responseContainsJSON(response):
response_json = response.json()
# update the total count of results
total_count = response_json["metadata"]["resultset"]["count"]
# add the results to the list
results_list.extend(response_json["results"])
else:
return { 'error': response.status_code }
return {'stations': results_list}
@app.route('/api/locations/cities')
@cache.cached(99999999)
def get_cities():
# print('getting cities')
results_list = []
total_count = 1000
while len(results_list) < total_count:
url = URL_NOAA_API
url += "/locations?"
url += "locationcategoryid=CITY"
url += "&sortfield=name"
url += "&sortorder=asc"
url += "&limit=1000"
url += "&offset=" + str(len(results_list))
# send the GET request with auth token header
# TODO move NOAA API code to a separate class, add request method
response = sendNoaaCdoRequest(url)
if responseContainsJSON(response):
response_json = response.json()
# TODO handle errors (send error result json through to client)
# update the total count of results
total_count = response_json["metadata"]["resultset"]["count"]
# add the results to the list
results_list.extend(response_json["results"])
else:
return { 'error': response.status_code }
return {'cities': results_list}