Skip to content
Snippets Groups Projects
Unverified Commit 2ff1b528 authored by David Hoese's avatar David Hoese
Browse files

Fix handling of data queries for multiple instruments and data API documentation

parent e3779914
Branches
No related tags found
No related merge requests found
......@@ -83,12 +83,19 @@ def handle_symbols(symbols):
def handle_influxdb_result(result, symbols, interval):
frames = []
for si, (req_syms, influx_symbs) in symbols.items():
for idx, (si, (req_syms, influx_symbs)) in enumerate(symbols.items()):
if isinstance(result, list):
# multiple query select statements results in a list
res = result[idx]
else:
# single query statement results in a single ResultSet
res = result
columns = ['time'] + influx_symbs
if not result:
if not res:
frame = pd.DataFrame(columns=columns)
else:
data_points = result.get_points('metobs_' + interval, tags={'site': si[0], 'inst': si[1]})
data_points = res.get_points('metobs_' + interval, tags={'site': si[0], 'inst': si[1]})
frame = pd.DataFrame(data_points, columns=['time'] + influx_symbs)
frame.set_index('time', inplace=True)
frame.fillna(value=np.nan, inplace=True)
......@@ -232,6 +239,7 @@ def handle_xml(frame, epoch, sep=',',
row_elem.setAttribute('id', str(idx))
row_elem.appendChild(doc.createTextNode(str(t)))
for point in row:
row_elem.appendChild(doc.createTextNode(" "))
row_elem.appendChild(doc.createTextNode(str(point)))
data_elem.appendChild(row_elem)
head.appendChild(data_elem)
......
......@@ -165,10 +165,10 @@
<b>begin:</b>
</td>
<td style='padding: 6px;'>
Start of the query interval in UTC as YYYY-MM-DDTHH:MM:SSZ or -HH:MM:SS.
Start of the query interval in UTC as YYYY-MM-DDTHH:MM:SS or -HH:MM:SS.
If the format -HH:MM:SS is used, begin is interpreted as a relative time
starting from the current time. If begin is not specified, it provides the
single latest record based upon the end parameter.
starting from the current time. If begin is not specified, it defaults to
the equivalent of -00:02:00 (the last two minutes).
</td>
</tr>
<tr>
......@@ -176,8 +176,10 @@
<b>end:</b>
</td>
<td style='padding: 6px;'>
End of the query interval in UTC as YYYY-MM-DDTHH:MM:SSZ. If not provided, it
defaults to the current time.
End of the query interval in UTC as YYYY-MM-DDTHH:MM:SS or -HH:MM:SS.
If the format -HH:MM:SS is used, end is interpreted as a relative time
starting from the current time. If end is not specified, it defaults to
the current time.
</td>
</tr>
<tr>
......@@ -223,11 +225,11 @@
</tr>
<tr>
<td style='padding: 6px;'>
<b>jsonFormat:</b>
<b>order:</b>
</td>
<td style='padding: 6px;'>
The format of the json and jsonp return values. If specified as 'row', the results will be organized as a 2-d array. If specified
as column the results are organized as &#60varname&#62:&#60list of value&#62. The jsonFormat is set as row by default. Only 'row'
as column the results are organized as &#60varname&#62:&#60list of value&#62. The 'order' is set as row by default. Only 'row'
and 'column' json formats are supported.
</td>
</tr>
......@@ -541,7 +543,7 @@
</h2>
<ul>
<li style='font-size: 15px'>
Latest temperature, dewpoint, pressure for AOSS Tower:
Last 2 minutes of temperature, dewpoint, pressure for AOSS Tower:
<ul>
<a href="{{ url_for('get_data', fmt='csv', site='aoss', inst='tower', symbols='air_temp:dewpoint:pressure') }}" }}>
{{ url_for('get_data', fmt='csv', site='aoss', inst='tower', symbols='air_temp:dewpoint:pressure') | replace('%3A', ':') }}
......@@ -549,7 +551,7 @@
</ul>
</li>
<li style='font-size: 15px'>
Latest temperature, dewpoint, pressure for AOSS Tower with Unix epoch millisecond timestamps:
Last 2 minutes of temperature, dewpoint, pressure for AOSS Tower with Unix epoch millisecond timestamps:
<ul>
<a href="{{ url_for('get_data', fmt='csv', site='aoss', inst='tower', symbols='air_temp:dewpoint:pressure', epoch='ms') }}">
{{ url_for('get_data', fmt='csv', site='aoss', inst='tower', symbols='air_temp:dewpoint:pressure', epoch='ms') | replace('%3A', ':') }}
......@@ -567,32 +569,32 @@
<li style='font-size: 15px'>
Last 5 minutes of all AOSS Tower data in a json row format:
<ul>
<a href="{{ url_for('get_data', fmt='json', site='aoss', inst='tower', symbols='air_temp:rel_hum:dewpoint:wind_speed:wind_direction:accum_precip:pressure:altimeter:solar_flux', begin='-00:05:00', jsonFormat='row') }}">
{{ url_for('get_data', fmt='json', site='aoss', inst='tower', symbols='air_temp:rel_hum:dewpoint:wind_speed:wind_direction:accum_precip:pressure:altimeter:solar_flux', begin='-00:05:00', jsonFormat='row') | replace('%3A', ':') }}
<a href="{{ url_for('get_data', fmt='json', site='aoss', inst='tower', symbols='air_temp:rel_hum:dewpoint:wind_speed:wind_direction:accum_precip:pressure:altimeter:solar_flux', begin='-00:05:00', order='row') }}">
{{ url_for('get_data', fmt='json', site='aoss', inst='tower', symbols='air_temp:rel_hum:dewpoint:wind_speed:wind_direction:accum_precip:pressure:altimeter:solar_flux', begin='-00:05:00', order='row') | replace('%3A', ':') }}
</a>
</ul>
</li>
<li style='font-size: 15px'>
Last 5 minutes of all AOSS Tower data in a json column format:
<ul>
<a href="{{ url_for('get_data', fmt='json', site='aoss', inst='tower', symbols='air_temp:rel_hum:dewpoint:wind_speed:wind_direction:accum_precip:pressure:altimeter:solar_flux', begin='-00:05:00', jsonFormat='column') }}">
{{ url_for('get_data', fmt='json', site='aoss', inst='tower', symbols='air_temp:rel_hum:dewpoint:wind_speed:wind_direction:accum_precip:pressure:altimeter:solar_flux', begin='-00:05:00', jsonFormat='column') | replace('%3A', ':') }}
<a href="{{ url_for('get_data', fmt='json', site='aoss', inst='tower', symbols='air_temp:rel_hum:dewpoint:wind_speed:wind_direction:accum_precip:pressure:altimeter:solar_flux', begin='-00:05:00', order='column') }}">
{{ url_for('get_data', fmt='json', site='aoss', inst='tower', symbols='air_temp:rel_hum:dewpoint:wind_speed:wind_direction:accum_precip:pressure:altimeter:solar_flux', begin='-00:05:00', order='column') | replace('%3A', ':') }}
</a>
</ul>
</li>
<li style='font-size: 15px'>
Tower temperature, wind_speed, and wind_direction data for 2016-07-11
<ul>
<a href="{{ url_for('get_data', fmt='csv', site='aoss', inst='tower', symbols='air_temp:wind_speed:wind_direction', begin='2016-07-11T00:00:00Z', end='2016-07-11T23:59:00Z') }}">
{{ url_for('get_data', fmt='csv', site='aoss', inst='tower', symbols='air_temp:wind_speed:wind_direction', begin='2016-07-11T00:00:00Z', end='2016-07-11T23:59:00Z') | replace('%3A', ':') }}
<a href="{{ url_for('get_data', fmt='csv', site='aoss', inst='tower', symbols='air_temp:wind_speed:wind_direction', begin='2016-07-11T00:00:00', end='2016-07-11T23:59:00') }}">
{{ url_for('get_data', fmt='csv', site='aoss', inst='tower', symbols='air_temp:wind_speed:wind_direction', begin='2016-07-11T00:00:00', end='2016-07-11T23:59:00') | replace('%3A', ':') }}
</a>
</ul>
</li>
<li style='font-size: 15px'>
Tower and buoy temperature data for 2016-07-11
<ul>
<a href="{{ url_for('get_data', fmt='csv', symbols='aoss.tower.air_temp:mendota.buoy.air_temp', begin='2016-07-11T00:00:00Z', end='2016-07-11T23:59:00Z') }}">
{{ url_for('get_data', fmt='csv', symbols='aoss.tower.air_temp:mendota.buoy.air_temp', begin='2016-07-11T00:00:00Z', end='2016-07-11T23:59:00Z') | replace('%3A', ':') }}
<a href="{{ url_for('get_data', fmt='csv', symbols='aoss.tower.air_temp:mendota.buoy.air_temp', begin='2016-07-11T00:00:00', end='2016-07-11T23:59:00') }}">
{{ url_for('get_data', fmt='csv', symbols='aoss.tower.air_temp:mendota.buoy.air_temp', begin='2016-07-11T00:00:00', end='2016-07-11T23:59:00') | replace('%3A', ':') }}
</a>
</ul>
</li>
......@@ -613,10 +615,10 @@
# status: success
# code: 200
# message:
# num_results: 4
# fields: Site,Inst,YYYY-MM-DDTHH:MM:SSZ,air_temp,rel_hum,dewpoint,wind_speed,wind_direction,accum_precip,pressure,altimeter,solar_flux
aoss,tower,2016-07-13T18:25:00Z,28.5,66.0,21.8,4.4,4.0,0.0,971.0,29.8,462.7
aoss,tower,2016-07-13T18:26:00Z,28.6,66.0,21.8,3.3,23.0,0.0,971.0,29.8,615.7
# num_results: 2
# fields: YYYY-MM-DDTHH:MM:SSZ,aoss.tower.air_temp,aoss.tower.rel_hum
2016-07-13T18:25:00Z,28.5,66.0
2016-07-13T18:26:00Z,28.6,66.0
</pre>
</li>
</ul>
......@@ -643,7 +645,7 @@ aoss,tower,2016-07-13T18:26:00Z,28.6,66.0,21.8,3.3,23.0,0.0,971.0,29.8,615.7
[28.5,65.0,21.5,8.3,8.0,0.0,970.7,29.8,239.6],
[28.5,65.0,21.5,5.3,8.0,0.0,970.8,29.8,268.2],
[28.5,65.0,21.5,6.6,20.0,0.0,970.7,29.8,237.1]],
"symbols":["air_temp","rel_hum","dewpoint","wind_speed","wind_direction","accum_precip","pressure","altimeter","solar_flux"],
"symbols":["aoss.tower.air_temp","aoss.tower.rel_hum","aoss.tower.dewpoint","aoss.tower.wind_speed","aoss.tower.wind_direction","aoss.tower.accum_precip","aoss.tower.pressure","aoss.tower.altimeter","aoss.tower.solar_flux"],
"timestamps":["2016-07-13T18:32:00Z","2016-07-13T18:33:00Z","2016-07-13T18:34:00Z","2016-07-13T18:35:00Z"]
},
"status":"success"
......@@ -660,15 +662,15 @@ aoss,tower,2016-07-13T18:26:00Z,28.6,66.0,21.8,3.3,23.0,0.0,971.0,29.8,615.7
"results":
{
"data": {
"accum_precip":[0.0,0.0,0.0,0.0],
"air_temp":[28.5,28.5,28.5,28.6],
"altimeter":[29.8,29.8,29.8,29.8],
"dewpoint":[21.5,21.4,21.3,21.5],
"pressure":[970.7,970.7,970.8,970.8],
"rel_hum":[65.0,65.0,65.0,65.0],
"solar_flux":[237.1,387.5,711.4,725.0],
"wind_direction":[20.0,12.0,348.0,357.0],
"wind_speed":[6.6,7.9,5.9,4.2]
"aoss.tower.accum_precip":[0.0,0.0,0.0,0.0],
"aoss.tower.air_temp":[28.5,28.5,28.5,28.6],
"aoss.tower.altimeter":[29.8,29.8,29.8,29.8],
"aoss.tower.dewpoint":[21.5,21.4,21.3,21.5],
"aoss.tower.pressure":[970.7,970.7,970.8,970.8],
"aoss.tower.rel_hum":[65.0,65.0,65.0,65.0],
"aoss.tower.solar_flux":[237.1,387.5,711.4,725.0],
"aoss.tower.wind_direction":[20.0,12.0,348.0,357.0],
"aoss.tower.wind_speed":[6.6,7.9,5.9,4.2]
},
"timestamps": ["2016-07-13T18:35:00Z","2016-07-13T18:36:00Z","2016-07-13T18:37:00Z","2016-07-13T18:38:00Z"]
},
......@@ -688,15 +690,15 @@ mycallback({
"results":
{
"data": {
"accum_precip":[0.0,0.0,0.0,0.0],
"air_temp":[28.5,28.5,28.5,28.6],
"altimeter":[29.8,29.8,29.8,29.8],
"dewpoint":[21.5,21.4,21.3,21.5],
"pressure":[970.7,970.7,970.8,970.8],
"rel_hum":[65.0,65.0,65.0,65.0],
"solar_flux":[237.1,387.5,711.4,725.0],
"wind_direction":[20.0,12.0,348.0,357.0],
"wind_speed":[6.6,7.9,5.9,4.2]
"aoss.tower.accum_precip":[0.0,0.0,0.0,0.0],
"aoss.tower.air_temp":[28.5,28.5,28.5,28.6],
"aoss.tower.altimeter":[29.8,29.8,29.8,29.8],
"aoss.tower.dewpoint":[21.5,21.4,21.3,21.5],
"aoss.tower.pressure":[970.7,970.7,970.8,970.8],
"aoss.tower.rel_hum":[65.0,65.0,65.0,65.0],
"aoss.tower.solar_flux":[237.1,387.5,711.4,725.0],
"aoss.tower.wind_direction":[20.0,12.0,348.0,357.0],
"aoss.tower.wind_speed":[6.6,7.9,5.9,4.2]
},
"timestamps": ["2016-07-13T18:35:00Z","2016-07-13T18:36:00Z","2016-07-13T18:37:00Z","2016-07-13T18:38:00Z"]
},
......@@ -712,20 +714,16 @@ mycallback({
A <i>timestamp</i> element containing a list of timestamps and a
<i>data</i> element for each requested symbol with a list of values:
<pre style='padding: 0px; padding-top: 15px; background: none; border: none'>
&#60metobs code="200" message="" num_results="4" seperator="," status="success"&#62
&#60timestamp format="%Y-%m-%dT%H:%M:%SZ"&#62
2016-07-13T19:05:00Z,2016-07-13T19:06:00Z,2016-07-13T19:07:00Z,2016-07-13T19:08:00Z
&#60/timestamp&#62
&#60data inst="tower" site="aoss" symbol="air_temp"&#62 29.0,29.1,28.9,29.0&#60/data&#62
&#60data inst="tower" site="aoss" symbol="rel_hum"&#62 61.0,60.0,60.0,61.0&#60/data&#62
&#60data inst="tower" site="aoss" symbol="dewpoint"&#62 20.9,20.8,20.8,21.0&#60/data&#62
&#60data inst="tower" site="aoss" symbol="wind_speed"&#62 5.7,5.4,4.2,3.5&#60/data&#62
&#60data inst="tower" site="aoss" symbol="wind_direction"&#62 342.0,347.0,352.0,338.0&#60/data&#62
&#60data inst="tower" site="aoss" symbol="accum_precip"&#62 0.0,0.0,0.0,0.0&#60/data&#62
&#60data inst="tower" site="aoss" symbol="pressure"&#62 970.0,970.0,970.0,970.0&#60/data&#62
&#60data inst="tower" site="aoss" symbol="altimeter"&#62 29.8,29.8,29.8,29.8&#60/data&#62
&#60data inst="tower" site="aoss" symbol="solar_flux"&#62 474.3,707.9,504.4,498.8&#60/data&#62
&#60/metobs>
&lt;metobs code=&quot;200&quot; message=&quot;&quot; num_results=&quot;2&quot; seperator=&quot;,&quot; status=&quot;success&quot;&gt;<br>
&lt;symbols&gt;<br>
&lt;symbol format=&quot;%Y-%m-%dT%H:%M:%SZ&quot; name=&quot;time&quot; short_name=&quot;time&quot;/&gt;<br>
&lt;symbol inst=&quot;tower&quot; name=&quot;aoss.tower.air_temp&quot; short_name=&quot;air_temp&quot; site=&quot;aoss&quot;/&gt;<br>
&lt;/symbols&gt;<br>
&lt;data&gt;<br>
&lt;row id=&quot;0&quot;&gt;2016-07-11T23:58:00Z 29.5&lt;/row&gt;<br>
&lt;row id=&quot;1&quot;&gt;2016-07-11T23:59:00Z 29.5&lt;/row&gt;<br>
&lt;/data&gt;<br>
&lt;/metobs&gt;<br>
</pre>
</li>
</div>
......
......@@ -4,7 +4,7 @@ from unittest import mock
import metobsapi
def fake_data(interval, symbols, num_vals):
def fake_data(interval, symbols, num_vals, single_result=False):
import random
from datetime import datetime, timedelta
from influxdb.resultset import ResultSet
......@@ -31,12 +31,22 @@ def fake_data(interval, symbols, num_vals):
'tags': tags,
'values': vals,
}
series.append(s)
ret = {
'series': series,
'statement_id': 0,
}
return ResultSet(ret)
if single_result:
series.append(s)
else:
series.append(ResultSet({
'series': [s],
'statement_id': 0,
}))
if single_result:
ret = {
'series': series,
'statement_id': 0,
}
return ResultSet(ret)
else:
return series
class TestDataAPI(unittest.TestCase):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment