Skip to content

Commit d9ab3e5

Browse files
authored
REST API endpoint for manifest/validate and model/submit
2 parents 515c86f + 76efd13 commit d9ab3e5

File tree

4 files changed

+242
-51
lines changed

4 files changed

+242
-51
lines changed

api/openapi/api.yaml

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ servers:
1212
paths:
1313
/manifest/generate:
1414
get:
15-
summary: >-
16-
Endpoints to expose annotation, validation and submission
17-
functionalities from schematic
15+
summary: Endpoint to facilitate manifest generation
1816
description: Endpoint to create dynamically create metadata manifest files
1917
parameters:
2018
- in: query
@@ -63,11 +61,111 @@ paths:
6361
required: true
6462
operationId: api.routes.get_manifest_route
6563
responses:
66-
'201':
67-
description: Googlesheet link created.
64+
"201":
65+
description: Googlesheet link created
6866
content:
6967
application/json:
7068
schema:
7169
type: string
7270
tags:
7371
- Manifest Operations
72+
/model/validate:
73+
post:
74+
summary: Endpoint to facilitate manifest validation
75+
description: Endpoint to validate metadata manifest files
76+
requestBody:
77+
content:
78+
multipart/form-data:
79+
schema:
80+
type: object
81+
properties:
82+
# csv_file will be the field name in
83+
# this multipart request
84+
csv_file:
85+
type: string
86+
format: binary
87+
parameters:
88+
- in: query
89+
name: schema_url
90+
schema:
91+
type: string
92+
description: Data Model URL
93+
example: >-
94+
https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld
95+
required: true
96+
- in: query
97+
name: data_type
98+
schema:
99+
type: string
100+
nullable: true
101+
description: Data Model Component
102+
example: Patient
103+
required: true
104+
operationId: api.routes.validate_manifest_route
105+
responses:
106+
"200":
107+
description: Manifest Validated
108+
content:
109+
application/json:
110+
schema:
111+
type: array
112+
items:
113+
type: array
114+
items:
115+
anyOf:
116+
- type: integer
117+
- type: string
118+
- type: array
119+
items:
120+
type: string
121+
tags:
122+
- Model Operations
123+
/model/submit:
124+
post:
125+
summary: Endpoint to facilitate manifest submission
126+
description: Endpoint to submit annotated manifest files
127+
requestBody:
128+
content:
129+
multipart/form-data:
130+
schema:
131+
type: object
132+
properties:
133+
csv_file:
134+
type: string
135+
format: binary
136+
parameters:
137+
- in: query
138+
name: schema_url
139+
schema:
140+
type: string
141+
description: Data Model URL
142+
example: >-
143+
https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld
144+
required: true
145+
- in: query
146+
name: data_type
147+
schema:
148+
type: string
149+
nullable: true
150+
description: Data Model Component
151+
example: Patient
152+
required: true
153+
- in: query
154+
name: dataset_id
155+
schema:
156+
type: string
157+
nullable: true
158+
description: Dataset SynID
159+
required: true
160+
operationId: api.routes.submit_manifest_route
161+
responses:
162+
"200":
163+
description: Manifest submitted
164+
content:
165+
application/json:
166+
schema:
167+
type: boolean
168+
"500":
169+
description: Check schematic log
170+
tags:
171+
- Model Operations

api/routes.py

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import os
22
import shutil
33
import tempfile
4+
import shutil
45
import urllib.request
56

67
import connexion
7-
from flask import current_app as app, request, g
8+
from flask import current_app as app, request, g, jsonify
89

910
from schematic import CONFIG
1011

1112
from schematic.manifest.generator import ManifestGenerator
13+
from schematic.models.metadata import MetadataModel
1214

1315

1416
# def before_request(var1, var2):
@@ -18,25 +20,36 @@
1820
# # Do stuff after your route executes
1921
# pass
2022

21-
# @before_request
22-
def get_manifest_route(schema_url, title, oauth, use_annotations):
23-
# check if file exists at the path created, i.e., app.config['SCHEMATIC_CONFIG']
23+
24+
def config_handler():
2425
path_to_config = app.config["SCHEMATIC_CONFIG"]
2526

27+
# check if file exists at the path created, i.e., app.config['SCHEMATIC_CONFIG']
2628
if os.path.isfile(path_to_config):
2729
CONFIG.load_config(path_to_config)
2830
else:
2931
raise FileNotFoundError(
3032
f"No configuration file was found at this path: {path_to_config}"
3133
)
3234

35+
36+
def get_temp_jsonld(schema_url):
3337
# retrieve a JSON-LD via URL and store it in a temporary location
3438
with urllib.request.urlopen(schema_url) as response:
3539
with tempfile.NamedTemporaryFile(delete=False, suffix=".jsonld") as tmp_file:
3640
shutil.copyfileobj(response, tmp_file)
3741

3842
# get path to temporary JSON-LD file
39-
jsonld = tmp_file.name
43+
return tmp_file.name
44+
45+
46+
# @before_request
47+
def get_manifest_route(schema_url, title, oauth, use_annotations):
48+
# call config_handler()
49+
config_handler()
50+
51+
# get path to temporary JSON-LD file
52+
jsonld = get_temp_jsonld(schema_url)
4053

4154
# request.data[]
4255
data_type = connexion.request.args["data_type"]
@@ -56,3 +69,63 @@ def get_manifest_route(schema_url, title, oauth, use_annotations):
5669
result = manifest_generator.get_manifest(sheet_url=True, dataset_id=dataset_id)
5770

5871
return result
72+
73+
74+
def validate_manifest_route(schema_url, data_type):
75+
# call config_handler()
76+
config_handler()
77+
78+
manifest_file = connexion.request.files["csv_file"]
79+
80+
# save contents of incoming manifest CSV file to temp file
81+
temp_dir = tempfile.gettempdir()
82+
# path to temp file where manifest file contents will be saved
83+
temp_path = os.path.join(temp_dir, manifest_file.filename)
84+
# save content
85+
manifest_file.save(temp_path)
86+
87+
# get path to temporary JSON-LD file
88+
jsonld = get_temp_jsonld(schema_url)
89+
90+
metadata_model = MetadataModel(
91+
inputMModelLocation=jsonld, inputMModelLocationType="local"
92+
)
93+
94+
errors = metadata_model.validateModelManifest(
95+
manifestPath=temp_path, rootNode=data_type
96+
)
97+
98+
return errors
99+
100+
101+
def submit_manifest_route(schema_url):
102+
# call config_handler()
103+
config_handler()
104+
105+
manifest_file = connexion.request.files["csv_file"]
106+
107+
# save contents of incoming manifest CSV file to temp file
108+
temp_dir = tempfile.gettempdir()
109+
# path to temp file where manifest file contents will be saved
110+
temp_path = os.path.join(temp_dir, manifest_file.filename)
111+
# save content
112+
manifest_file.save(temp_path)
113+
114+
# get path to temporary JSON-LD file
115+
jsonld = get_temp_jsonld(schema_url)
116+
117+
dataset_id = connexion.request.args["dataset_id"]
118+
119+
data_type = connexion.request.args["data_type"]
120+
121+
metadata_model = MetadataModel(
122+
inputMModelLocation=jsonld, inputMModelLocationType="local"
123+
)
124+
125+
success = metadata_model.submit_metadata_manifest(
126+
manifest_path=temp_path,
127+
dataset_id=dataset_id,
128+
validate_component=data_type,
129+
)
130+
131+
return success

0 commit comments

Comments
 (0)