Skip to content

Commit 2639f11

Browse files
authored
REST API endpoint for manifest creation
2 parents f8a11bc + 18cdf4e commit 2639f11

File tree

7 files changed

+452
-51
lines changed

7 files changed

+452
-51
lines changed

api/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## Setup
2+
3+
To start a local Flask server and test your endpoints:
4+
5+
```bash
6+
source .venv/bin/activate
7+
python run_api.py
8+
```
9+
10+
Access the Swagger UI docs at this location:
11+
12+
```bash
13+
http://localhost:3001/v1/ui/
14+
```

api/__init__.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import os
2+
3+
import connexion
4+
5+
from schematic import CONFIG
6+
7+
8+
def create_app():
9+
connexionapp = connexion.FlaskApp(__name__, specification_dir="openapi/")
10+
connexionapp.add_api("api.yaml")
11+
12+
# get the underlying Flask app instance
13+
app = connexionapp.app
14+
15+
# path to config.yml file saved as a Flask config variable
16+
app.config["SCHEMATIC_CONFIG"] = os.path.abspath(
17+
os.path.join(__file__, "../../config.yml")
18+
)
19+
20+
# Configure flask app
21+
# app.config[] = schematic[]
22+
# app.config[] = schematic[]
23+
# app.config[] = schematic[]
24+
25+
# Initialize extension schematic
26+
# import MyExtension
27+
# myext = MyExtension()
28+
# myext.init_app(app)
29+
30+
return app
31+
32+
# def route_code():
33+
# import flask_schematic as sc
34+
# sc.method1()
35+
#

api/openapi/api.yaml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Schematic REST API
4+
version: 0.1.0
5+
description: >-
6+
This service exposes core functionalities from schematic as REST API
7+
endpoints
8+
9+
servers:
10+
- url: /v1
11+
12+
paths:
13+
/manifest/generate:
14+
get:
15+
summary: >-
16+
Endpoints to expose annotation, validation and submission
17+
functionalities from schematic
18+
description: Endpoint to create dynamically create metadata manifest files
19+
parameters:
20+
- in: query
21+
name: schema_url
22+
schema:
23+
type: string
24+
description: Data Model URL
25+
example: >-
26+
https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld
27+
required: true
28+
- in: query
29+
name: title
30+
schema:
31+
type: string
32+
description: Title of Manifest
33+
example: Patient Metadata Manifest
34+
required: false
35+
- in: query
36+
name: data_type
37+
schema:
38+
type: string
39+
nullable: true
40+
description: Data Model Component
41+
example: Patient
42+
required: true
43+
- in: query
44+
name: oauth
45+
schema:
46+
type: boolean
47+
default: true
48+
description: OAuth or Service Account
49+
required: false
50+
- in: query
51+
name: use_annotations
52+
schema:
53+
type: boolean
54+
default: false
55+
description: To Use Annotations
56+
required: false
57+
- in: query
58+
name: dataset_id
59+
schema:
60+
type: string
61+
nullable: true
62+
description: Dataset SynID
63+
required: true
64+
operationId: api.routes.get_manifest_route
65+
responses:
66+
'201':
67+
description: Googlesheet link created.
68+
content:
69+
application/json:
70+
schema:
71+
type: string
72+
tags:
73+
- Manifest Operations

api/routes.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import os
2+
import shutil
3+
import tempfile
4+
import urllib.request
5+
6+
import connexion
7+
from flask import current_app as app, request, g
8+
9+
from schematic import CONFIG
10+
11+
from schematic.manifest.generator import ManifestGenerator
12+
13+
14+
# def before_request(var1, var2):
15+
# # Do stuff before your route executes
16+
# pass
17+
# def after_request(var1, var2):
18+
# # Do stuff after your route executes
19+
# pass
20+
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']
24+
path_to_config = app.config["SCHEMATIC_CONFIG"]
25+
26+
if os.path.isfile(path_to_config):
27+
CONFIG.load_config(path_to_config)
28+
else:
29+
raise FileNotFoundError(
30+
f"No configuration file was found at this path: {path_to_config}"
31+
)
32+
33+
# retrieve a JSON-LD via URL and store it in a temporary location
34+
with urllib.request.urlopen(schema_url) as response:
35+
with tempfile.NamedTemporaryFile(delete=False, suffix=".jsonld") as tmp_file:
36+
shutil.copyfileobj(response, tmp_file)
37+
38+
# get path to temporary JSON-LD file
39+
jsonld = tmp_file.name
40+
41+
# request.data[]
42+
data_type = connexion.request.args["data_type"]
43+
44+
# create object of type ManifestGenerator
45+
manifest_generator = ManifestGenerator(
46+
path_to_json_ld=jsonld,
47+
title=title,
48+
root=data_type,
49+
oauth=oauth,
50+
use_annotations=use_annotations,
51+
)
52+
53+
dataset_id = connexion.request.args["dataset_id"]
54+
55+
# call get_manifest() on manifest_generator
56+
result = manifest_generator.get_manifest(sheet_url=True, dataset_id=dataset_id)
57+
58+
return result

0 commit comments

Comments
 (0)