Skip to content
This repository has been archived by the owner on Oct 8, 2022. It is now read-only.

Commit

Permalink
allow list of scenarios in map query parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
zzeppozz committed Apr 26, 2021
1 parent 5865d62 commit db1d46d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 26 deletions.
12 changes: 11 additions & 1 deletion lmtrex/services/api/v1/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ def _standardize_params(
'dataset_key': (None, empty_str),
'count_only': False,
'url': (None, empty_str),
'scenariocode': Lifemapper.valid_scenario_codes(),
'scenariocode': (None, empty_str),
'bbox': '-180,-90,180,90',
'color': Lifemapper.VALID_COLORS,
'exceptions': (None, empty_str),
Expand Down Expand Up @@ -339,6 +339,16 @@ def _standardize_params(
if ServiceProvider.is_valid_param(prov):
provs.append(prov)
usr_params['provider'] = provs
# Allow for None or comma-delimited list of scenarios
scens = []
if scenariocode is not None:
# Prepared params are lower case
tmpscens = usr_params['scenariocode'].split(',')
for ts in tmpscens:
scen = ts.strip()
if scen in Lifemapper.valid_scenario_codes():
scens.append(scen)
usr_params['scenariocode'] = scens
# Remove 'gbif_accepted' flag and replace with 'gbif_status' filter for GBIF
# GBIF Taxonomic Constants at:
# https://gbif.github.io/gbif-api/apidocs/org/gbif/api/vocabulary/TaxonomicStatus.html
Expand Down
24 changes: 13 additions & 11 deletions lmtrex/services/api/v1/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def _match_gbif_names(self, namestr, gbif_status):
return scinames, errmsgs

# ...............................................
def _get_lifemapper_records(self, namestr, gbif_status, scenariocode, color):
def _get_lifemapper_records(self, namestr, gbif_status, scenariocodes, color):
errmsgs = []
# First: get name(s)
if gbif_status is False:
Expand All @@ -48,13 +48,13 @@ def _get_lifemapper_records(self, namestr, gbif_status, scenariocode, color):
for sname in scinames:
# TODO: search on occurrenceset, then also pull projection layers
lout = LifemapperAPI.find_map_layers_by_name(
sname, prjscenariocode=scenariocode, color=color)
sname, prjscenariocodes=scenariocodes, color=color)
if len(lout.records) > 0:
stdrecs.extend(lout.records)
errmsgs.extend(lout.errors)
queries.extend(lout.provider_query)
query_term = 'namestr={}; gbif_status={}; scenariocode={}; color={}'.format(
namestr, gbif_status, scenariocode, color)
query_term = 'namestr={}; gbif_status={}; scenariocodes={}; color={}'.format(
namestr, gbif_status, scenariocodes, color)
full_out = S2nOutput(
len(stdrecs), query_term, self.SERVICE_TYPE, lout.provider,
provider_query=queries, record_format=Lifemapper.RECORD_FORMAT_MAP,
Expand All @@ -63,7 +63,7 @@ def _get_lifemapper_records(self, namestr, gbif_status, scenariocode, color):

# ...............................................
def get_records(
self, namestr, req_providers, gbif_status, scenariocode, color):
self, namestr, req_providers, gbif_status, scenariocodes, color):
allrecs = []
# for response metadata
common_query = ''
Expand All @@ -75,7 +75,7 @@ def get_records(
# Lifemapper
if pr == ServiceProvider.Lifemapper[S2nKey.PARAM]:
lmoutput = self._get_lifemapper_records(
namestr, gbif_status, scenariocode, color)
namestr, gbif_status, scenariocodes, color)
allrecs.append(lmoutput)
provnames.append(ServiceProvider.Lifemapper[S2nKey.NAME])
# Assemble
Expand Down Expand Up @@ -117,6 +117,7 @@ def GET(self, namestr=None, provider=None, gbif_parse=True, gbif_accepted=True,
usr_params['provider'], valid_providers)

# What to query
scencodes = usr_params['scenariocode']
namestr = usr_params['namestr']
try:
if namestr is None:
Expand All @@ -125,7 +126,7 @@ def GET(self, namestr=None, provider=None, gbif_parse=True, gbif_accepted=True,
# Query
output = self.get_records(
namestr, valid_req_providers, usr_params['gbif_status'],
usr_params['scenariocode'], usr_params['color'])
scencodes, usr_params['color'])
if invalid_providers:
msg = 'Invalid providers requested: {}'.format(
','.join(invalid_providers))
Expand All @@ -142,7 +143,8 @@ def GET(self, namestr=None, provider=None, gbif_parse=True, gbif_accepted=True,
names = ['Tulipa sylvestris']
names = ['Phlox longifolia Nutt']
svc = MapSvc()
for namestr in names:
for prov in svc.get_providers():
out = svc.GET(namestr=namestr, scenariocode=None, provider=prov)
print_s2n_output(out, do_print_rec=True)
for namestr in names:
for scodes in (None, 'worldclim-curr'):
for prov in svc.get_providers():
out = svc.GET(namestr=namestr, scenariocode=scodes, provider=prov)
print_s2n_output(out, do_print_rec=True)
21 changes: 7 additions & 14 deletions lmtrex/tools/provider/lifemapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def __init__(

# ...............................................
@classmethod
def _standardize_proj_layer_record(cls, rec, prjscenariocode=None, color=None):
def _standardize_proj_layer_record(cls, rec, prjscenariocodes=None, color=None):
errmsgs = []
stat = endpoint = sdm_layer_name = proj_url = None
scen_code = scen_link = species_name = modtime = None
Expand All @@ -56,7 +56,7 @@ def _standardize_proj_layer_record(cls, rec, prjscenariocode=None, color=None):
'Failed to retrieve projectionScenario/code element'))
else:
# ignore
if prjscenariocode is not None and prjscenariocode != scen_code:
if prjscenariocodes and scen_code not in prjscenariocodes:
pass
# Return all valid projection layers or requested projection layer for scenario
else:
Expand Down Expand Up @@ -167,7 +167,7 @@ def _standardize_occ_layer_record(cls, rec, color=None):
# ...............................................
@classmethod
def _standardize_map_output(
cls, output, query_term, service, prjscenariocode=None, color=None, count_only=False,
cls, output, query_term, service, prjscenariocodes=None, color=None, count_only=False,
provider_query=[], err=None):
occ_layer_rec = None
stdrecs = []
Expand Down Expand Up @@ -197,7 +197,7 @@ def _standardize_map_output(
for r in output:
try:
r2 = cls._standardize_proj_layer_record(
r, prjscenariocode=prjscenariocode, color=color)
r, prjscenariocodes=prjscenariocodes, color=color)
if r2['endpoint'] is not None:
stdrecs.append(r2)
except Exception as e:
Expand Down Expand Up @@ -370,15 +370,15 @@ def _standardize_occ_output(cls, output, color=None, count_only=False, err=None)
# ...............................................
@classmethod
def find_map_layers_by_name(
cls, name, prjscenariocode=None, color=None, other_filters={},
cls, name, prjscenariocodes=None, color=None, other_filters={},
logger=None):
"""
List projections for a given scientific name.
Args:
name: a scientific name 'Accepted' according to the GBIF Backbone
Taxonomy
prjscenariocode: a Lifemapper code indicating whether the
prjscenariocodes: one or more Lifemapper codes indicating whether the
environmental data used for creating the projection is
observed, or modeled past or future. Codes are in
LmREx.common.lmconstants Lifemapper.*_SCENARIO_CODE*. If the
Expand All @@ -391,16 +391,9 @@ def find_map_layers_by_name(
Note:
Lifemapper contains only 'Accepted' name froms the GBIF Backbone
Taxonomy and this method requires them for success.
Todo:
search on occurrenceset, then also pull projection layers
"""
other_filters[Lifemapper.NAME_KEY] = name
other_filters[Lifemapper.ATOM_KEY] = 0
# other_filters[Lifemapper.MIN_STAT_KEY] = Lifemapper.COMPLETE_STAT_VAL
# other_filters[Lifemapper.MAX_STAT_KEY] = Lifemapper.COMPLETE_STAT_VAL
# if prjscenariocode is not None:
# other_filters[Lifemapper.SCENARIO_KEY] = prjscenariocode
api = LifemapperAPI(
resource=Lifemapper.PROJ_RESOURCE, other_filters=other_filters)

Expand All @@ -411,7 +404,7 @@ def find_map_layers_by_name(
else:
std_output = cls._standardize_map_output(
api.output, name, APIService.Map, provider_query=[api.url],
prjscenariocode=prjscenariocode, color=color, count_only=False,
prjscenariocodes=prjscenariocodes, color=color, count_only=False,
err=api.error)

return std_output
Expand Down

0 comments on commit db1d46d

Please sign in to comment.