Skip to content

Commit

Permalink
Merge pull request #52 from bento-platform/features/handle-get
Browse files Browse the repository at this point in the history
handle GET parameters
  • Loading branch information
gsfk authored Aug 28, 2023
2 parents 371444c + bcc678e commit 0dce4b2
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 15 deletions.
2 changes: 2 additions & 0 deletions bento_beacon/config_files/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Config:
"info": "record"
}

DEFAULT_PAGINATION_PAGE_SIZE = 10

BENTO_DOMAIN = os.environ.get("BENTOV2_DOMAIN")
BEACON_BASE_URL = os.environ.get("BEACON_BASE_URL")
BENTO_PUBLIC_URL = os.environ.get("BENTOV2_PUBLIC_URL")
Expand Down
66 changes: 51 additions & 15 deletions bento_beacon/utils/beacon_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def request_defaults():
"includeResultsetResponses": "ALL",
"pagination": {
"skip": 0,
"limit": 0
"limit": current_app.config["DEFAULT_PAGINATION_PAGE_SIZE"]
},
"requestedSchemas": []
}
Expand All @@ -21,16 +21,9 @@ def expand_path(id):
return id.replace("/", ".[item].")


# request read from flask request context
def query_parameters_from_request():
if request.method == "POST":
beacon_args = request.get_json() or {}
else:
beacon_args = {}

variants_query = beacon_args.get("query", {}).get(
"requestParameters", {}).get("g_variant") or {}
filters = beacon_args.get("query", {}).get("filters") or []
variants_query = g.request_data.get("requestParameters", {}).get("g_variant") or {}
filters = g.request_data.get("filters") or []

# reject if too many filters
max_filters = current_app.config["MAX_FILTERS"]
Expand All @@ -41,7 +34,7 @@ def query_parameters_from_request():
phenopacket_filters = list(filter(lambda f: f["id"].startswith("phenopacket."), filters))
experiment_filters = list(filter(lambda f: f["id"].startswith("experiment."), filters))
config_filters = [f for f in filters if f not in phenopacket_filters and f not in experiment_filters]

# strip filter prefixes and convert remaining ids to bento format
phenopacket_filters = list(map(lambda f: {"id": expand_path(f["id"])[len("phenopacket."):],
"operator": f["operator"], "value": f["value"]}, phenopacket_filters))
Expand All @@ -50,26 +43,69 @@ def query_parameters_from_request():
return variants_query, phenopacket_filters, experiment_filters, config_filters


# structure GET params so they match the nested structure in POST
def package_get_params(params):
param_keys = list(params)

query_params_primitives = ("includeResultsetResponses", "requestedGranularity", "testMode")
variant_params_primitives = ("alternateBases", "aminoacidChange", "assemblyId", "geneId", "genomicAlleleShortForm",
"mateName", "referenceBases", "referenceName", "variantMaxLength", "variantMinLength",
"variantType")
variant_params_arrays = ("start", "end")
pagination_params = ("skip", "limit")

meta = {}
if ["apiVersion"] in param_keys:
meta["apiVersion"] = params["apiVersion"]

pagination = {}
for key in pagination_params:
if key in param_keys:
pagination[key] = params[key]

g_variant = {}
for key in variant_params_primitives:
if key in param_keys:
g_variant[key] = params[key]
for key in variant_params_arrays:
if key in param_keys:
g_variant[key] = params.getlist(key)

query = {"requestParameters": {"g_variant": g_variant}, "pagination": pagination}
for key in query_params_primitives:
if key in param_keys:
query[key] = params[key]
if "filters" in param_keys:
query["filters"] = params.getlist("filters")

return {"meta": meta, "query": query}


def save_request_data():
defaults = request_defaults()

# queries only use POST for now
# if GET, it's a call to an info endpoint, can ignore anything here for now
if request.method == "POST":
request_args = request.get_json() or {}
else:
request_args = {}
request_args = package_get_params(request.args)

request_meta = request_args.get("meta", {})
request_query = request_args.get("query", {})
request_bento = request_args.get("bento", {})
query_request_parameters = request_query.get("requestParameters")
query_filters = request_query.get("filters")

request_data = {
"apiVersion": request_meta.get("apiVersion", defaults["apiVersion"]),
"requestedSchemas": request_meta.get("requestedSchemas", defaults["requestedSchemas"]),
"pagination": {**defaults["pagination"], **request_query.get("pagination", {})},
"requestedGranularity": request_query.get("requestedGranularity", defaults["granularity"]),
}
if query_request_parameters:
request_data["requestParameters"] = query_request_parameters

if query_filters:
request_data["filters"] = query_filters

if request_bento:
request_data["bento"] = request_bento
Expand All @@ -81,7 +117,7 @@ def validate_request():
if request.method == "POST":
request_args = request.get_json() or {}
else:
# GET currently used for info endpoints only, so no request payload
# GET params are not bound by the beaconRequestBody schema
return

# file path resolver for local json schema
Expand Down

0 comments on commit 0dce4b2

Please sign in to comment.