-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(datasets): add datasets endpoint
- Loading branch information
Showing
6 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import flask | ||
import os | ||
import re | ||
|
||
import peregrine.utils | ||
from peregrine.resources.submission import ( | ||
graphql, | ||
set_read_access_projects_for_public_endpoint, | ||
set_read_access_projects, | ||
) | ||
|
||
from cdiserrors import UserError, AuthZError | ||
|
||
blueprint = flask.Blueprint("datasets", "datasets") | ||
|
||
|
||
@blueprint.route("/", methods=["GET"]) | ||
def get_datasets(): | ||
""" | ||
Get dataset level summary counts, if a deployment is configured | ||
to set PUBLIC_DATASETS to True, this endpoint will be open to | ||
anonymous users | ||
""" | ||
nodes = flask.request.args.get("nodes", "") | ||
nodes = nodes.split(",") | ||
if nodes == []: | ||
raise UserError("Need to provide target nodes in query param") | ||
if os.environ.get("PUBLIC_DATASETS", False) == "true": | ||
set_read_access_projects_for_public_endpoint() | ||
else: | ||
set_read_access_projects() | ||
projects = flask.g.read_access_projects | ||
if not projects: | ||
raise AuthZError("You are not authorized to access any projects") | ||
# construct a query that get counts for all projects | ||
# because graphql can't add structure to group by projects, | ||
# we labeled the count by project index and later parse it | ||
# with regex to add structure to response | ||
query = "{" | ||
for i, project_id in enumerate(projects): | ||
query += ( | ||
" ".join( | ||
map( | ||
lambda x: """i{i}_{node}: _{node}_count(project_id: "{p}")""".format( | ||
i=i, node=x, p=project_id | ||
), | ||
nodes, | ||
) | ||
) | ||
+ " " | ||
) | ||
query += "}" | ||
data, errors = graphql.execute_query(query, variables={}) | ||
if errors: | ||
return flask.jsonify({"data": data, "errors": errors}), 400 | ||
result = {project_id: {} for project_id in projects} | ||
|
||
for name, value in data.iteritems(): | ||
match = re.search("^i(\d)_(.*)", name) | ||
index = int(match.group(1)) | ||
node = match.group(2) | ||
result[projects[index]][node] = value | ||
return flask.jsonify(result) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from test_graphql import post_example_entities_together | ||
from datamodelutils import models | ||
import os | ||
|
||
|
||
def test_authorized_call_with_protected_config( | ||
client, submitter, pg_driver_clean, cgci_blgsp | ||
): | ||
post_example_entities_together(client, pg_driver_clean, submitter) | ||
#: number of nodes to change project_id on, there should be 5 | ||
with pg_driver_clean.session_scope() as s: | ||
cases = pg_driver_clean.nodes(models.Case).all() | ||
case_count = len(cases) | ||
for case in cases[0:-3]: | ||
case.project_id = "OTHER-OTHER" | ||
s.merge(case) | ||
r = client.get("/datasets?nodes=case,aliquot", headers=submitter) | ||
assert r.json.keys() == ["CGCI-BLGSP"] | ||
assert r.json["CGCI-BLGSP"]["case"] == case_count - 2 | ||
|
||
|
||
def test_anonymous_call_with_protected_config(client, pg_driver_clean, cgci_blgsp): | ||
r = client.get("/datasets?nodes=case,aliquot") | ||
assert r.status_code == 401 | ||
|
||
|
||
def test_anonymous_call_with_public_config( | ||
client, submitter, pg_driver_clean, cgci_blgsp, public_dataset_api | ||
): | ||
post_example_entities_together(client, pg_driver_clean, submitter) | ||
with pg_driver_clean.session_scope() as s: | ||
project = models.Project("other", code="OTHER") | ||
program = pg_driver_clean.nodes(models.Program).props(name="CGCI").first() | ||
project.programs = [program] | ||
s.add(project) | ||
aliquot_count = pg_driver_clean.nodes(models.Aliquot).count() | ||
cases = pg_driver_clean.nodes(models.Case).all() | ||
case_count = len(cases) | ||
for case in cases[0:-3]: | ||
case.project_id = "CGCI-OTHER" | ||
s.merge(case) | ||
|
||
r = client.get("/datasets?nodes=case,aliquot") | ||
assert r.json["CGCI-BLGSP"]["case"] == case_count - 2 | ||
assert r.json["CGCI-BLGSP"]["aliquot"] == aliquot_count | ||
assert r.json["CGCI-OTHER"]["aliquot"] == 0 | ||
assert r.json["CGCI-OTHER"]["case"] == 2 |