Skip to content
This repository has been archived by the owner on Dec 16, 2019. It is now read-only.

[WIP] ENH: RESTful API to serve the data format #4 #9

Merged
merged 5 commits into from
Nov 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# API

This is a RESTful API to serve the data format.


## Usage

### Store

You must send a post request to: http://localhost:5000/store
The body of your request must match the following template

{
"output_format": "json",
"fhir_resource_name": "patient"
}

### Mapping

You must send a post request to: http://localhost:5000/mapping
The body of your request must match the following template

{
"output_format": "json",
"fhir_resource_name": "patient"
"database": "CW"
}
Empty file added api/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions api/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from flask import Flask, jsonify
from flask_restful import Api

from api.resources import Mapping, Store


app = Flask(__name__)
api = Api(app)

api.add_resource(Store, '/store')
api.add_resource(Mapping, '/mapping')

@app.route('/')
def index():
return jsonify(
{'message': 'Welcome to Fhir API'}
)


if __name__ == '__main__':
app.run(debug=True)
Empty file added api/common/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions api/common/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import glob
import re


def fhir_resource_path(fhir_resource, parent_folder):
# this is highly inefficient, since we need to scan the entire folder.
jblemoine marked this conversation as resolved.
Show resolved Hide resolved
# It might be interesting to cache the folder structure

# case insensitive glob
# source: https://medium.com/@tylercubell/python-case-insensitive-glob-80ba7306b327
pattern = ".*/{}.yml".format(fhir_resource)
matching_files = [file for file in glob.glob(f'../{parent_folder}/**', recursive=True) if re.match(pattern, file, flags=re.IGNORECASE)]
if not matching_files:
return None
else:
return matching_files[0]
1 change: 1 addition & 0 deletions api/resources/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .resources import Mapping, Store
59 changes: 59 additions & 0 deletions api/resources/resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from flask import jsonify, send_from_directory
# note: prefer send_from_directory to send_file as send_file is not secured.
jblemoine marked this conversation as resolved.
Show resolved Hide resolved
# From the official documentation : "Please never pass filenames to this function from user sources;
# you should use send_from_directory() instead."
from flask_restful import Resource, reqparse
import os
import yaml

from api.common.utils import fhir_resource_path


class Store(Resource):
def post(self):

parser = reqparse.RequestParser()
parser.add_argument('output_format', required=True, type=str, choices=('json', 'yml'))
parser.add_argument('fhir_resource_name', required=True, type=str)

args = parser.parse_args()

file_path = fhir_resource_path(args['fhir_resource_name'], parent_folder=args['output_format'])
if not file_path:
return jsonify(
{"message": "Fhir resource not found."}
)

folder = os.path.dirname(file_path)
file = os.path.basename(file_path)
if args['output_format'] == 'json':
return jsonify(yaml.load(open(file_path)))

elif args['output_format'] == 'yml':
return send_from_directory(folder, file)


class Mapping(Resource):
def post(self):

parser = reqparse.RequestParser()
parser.add_argument('output_format', required=True, type=str, choices=('json', 'yml'))
parser.add_argument('fhir_resource_name', required=True, type=str)
parser.add_argument('database', required=True, type=str)

args = parser.args()

file_path = fhir_resource_path(args['fhir_resource_name'], parent_folder=args['database'])
if not file_path:
return jsonify(
{"message": "Fhir resource not found."}
)

folder = os.path.dirname(file_path)
file = os.path.basename(file_path)

if args['output_format'] == 'json':
return jsonify(yaml.load(open(file_path)))

elif args['output_format'] == 'yml':
return send_from_directory(folder, file)