Skip to content

Commit bf992e1

Browse files
authored
Merge pull request #303 from VinLau/dev
Small change to fastpheno to accept site ID for timeseries
2 parents d581ab4 + b600192 commit bf992e1

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

api/resources/fastpheno.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,20 +170,27 @@ def get(self, seq_id, band):
170170
class FastPhenoGenotypeTimeSeries(Resource):
171171
@fastpheno.param("tree_site_id", _in="path", default="619")
172172
@fastpheno.param("band", _in="path", default="398nm")
173+
@fastpheno.param("site", _in="query", required=False, default="Pintendre")
173174
def get(self, tree_site_id, band):
174175
"""Returns AVG and STDDEV of band values per flight date across all trees sharing a
175176
genotype (e.g. '619' matches all tree_site_id values starting with '619.'). Intended
176-
for genotype-level time series plotting."""
177+
for genotype-level time series plotting. Optionally filter by site name."""
177178
tree_site_id = str(escape(tree_site_id))
178179
band = str(escape(band))
180+
site = request.args.get("site")
179181

180182
if not re.search(r"^[a-zA-Z0-9]{1,10}$", tree_site_id):
181183
return BARUtils.error_exit("Invalid tree site ID"), 400
182184

183185
if not re.search(r"^[a-zA-Z0-9_]{1,20}$", band):
184186
return BARUtils.error_exit("Invalid band"), 400
185187

186-
rows = db.session.execute(
188+
if site is not None:
189+
site = str(escape(site)).capitalize()
190+
if not re.search(r"^[a-zA-Z]{1,15}$", site):
191+
return BARUtils.error_exit("Invalid site name"), 400
192+
193+
query = (
187194
db.select(
188195
Flights.flight_date,
189196
Flights.flights_pk,
@@ -198,13 +205,19 @@ def get(self, tree_site_id, band):
198205
)
199206
.join(Trees, Bands.trees_pk == Trees.trees_pk)
200207
.join(Flights, Bands.flights_pk == Flights.flights_pk)
208+
.join(Sites, Flights.sites_pk == Sites.sites_pk)
201209
.where(
202210
db.or_(Trees.tree_site_id == tree_site_id, Trees.tree_site_id.like(f"{tree_site_id}.%")),
203211
Bands.band == band,
204212
)
205213
.group_by(Flights.flights_pk, Flights.flight_date)
206214
.order_by(Flights.flight_date)
207-
).all()
215+
)
216+
217+
if site is not None:
218+
query = query.where(Sites.site_name == site)
219+
220+
rows = db.session.execute(query).all()
208221

209222
if len(rows) == 0:
210223
return BARUtils.error_exit("No data found for the given parameters"), 400

tests/resources/test_fastpheno.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,16 @@ def test_timeseries_genotype_aggregate(self):
216216
}
217217
self.assertEqual(response.json, expected)
218218

219+
# With site filter
220+
response = self.app_client.get("/fastpheno/timeseries/genotype/619/398nm/aggregate?site=Pintendre")
221+
self.assertEqual(response.json["wasSuccessful"], True)
222+
self.assertEqual(len(response.json["data"]), 1)
223+
224+
# No data when site has no matching trees
225+
response = self.app_client.get("/fastpheno/timeseries/genotype/619/398nm/aggregate?site=Pickering")
226+
expected = {"wasSuccessful": False, "error": "No data found for the given parameters"}
227+
self.assertEqual(response.json, expected)
228+
219229
# No data for valid but non-existent genotype
220230
response = self.app_client.get("/fastpheno/timeseries/genotype/9999/398nm/aggregate")
221231
expected = {"wasSuccessful": False, "error": "No data found for the given parameters"}
@@ -231,6 +241,11 @@ def test_timeseries_genotype_aggregate(self):
231241
expected = {"wasSuccessful": False, "error": "Invalid band"}
232242
self.assertEqual(response.json, expected)
233243

244+
# Invalid site name
245+
response = self.app_client.get("/fastpheno/timeseries/genotype/619/398nm/aggregate?site=123")
246+
expected = {"wasSuccessful": False, "error": "Invalid site name"}
247+
self.assertEqual(response.json, expected)
248+
234249
def test_sites(self):
235250
"""Tests GET /fastpheno/sites"""
236251
response = self.app_client.get("/fastpheno/sites")

0 commit comments

Comments
 (0)