diff --git a/fda-metadata-db/setup-schema.sql b/fda-metadata-db/setup-schema.sql index 08ad85b36a40651769ccaf296d200b8cb070ad1b..c3806d31d27f01c55f3d1f80b5c70a7c080f291d 100644 --- a/fda-metadata-db/setup-schema.sql +++ b/fda-metadata-db/setup-schema.sql @@ -353,7 +353,7 @@ CREATE TABLE IF NOT EXISTS mdb_columns_concepts URI TEXT REFERENCES mdb_concepts (URI), created timestamp without time zone NOT NULL DEFAULT NOW(), FOREIGN KEY (cDBID, tID, cID) REFERENCES mdb_COLUMNS (cDBID, tID, ID), - PRIMARY KEY (cDBID, tID, cID) + PRIMARY KEY (cDBID, tID, cID, URI) ); CREATE TABLE IF NOT EXISTS mdb_VIEW diff --git a/fda-units-service/.gitignore b/fda-units-service/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ba0430d26c996e7f078385407f959c96c271087c --- /dev/null +++ b/fda-units-service/.gitignore @@ -0,0 +1 @@ +__pycache__/ \ No newline at end of file diff --git a/fda-units-service/README.md b/fda-units-service/README.md index 9c91ba6748208e96ef888dad6022b9afa6145644..da7b0ba16ed2dc5843d312998b071452ce6adcfb 100644 --- a/fda-units-service/README.md +++ b/fda-units-service/README.md @@ -3,3 +3,123 @@ Suggest and validates units of measurements defined in Ontology of units of Measure (OM) [1] is used. [1] https://github.com/HajoRijgersberg/OM + +## `POST /api/units/suggest` +Autosuggests user typed in terms. + +Example http request: +POST /api/units/suggest HTTP/1.1 +Content-Type: application/json +Host: localhost:5010 +Content-Length: 37 + +```JSON +{ + "offset": 0, + "ustring": "met" +} +``` + +Response is a JSON object of the following form: + +```JSON +[ + { + "comment": "The metre is a unit of length defined as the length of the path travelled by light in vacuum during a time interval of 1/299 792 458 of a second.", + "name": "metre", + "symbol": "m" + }, + { + "comment": "Candela per square metre is a unit of luminance defined as candela divided by square metre.", + "name": "candela per square metre", + "symbol": "cd/m" + }, + { + "comment": "Cubic metre is a unit of volume defined as the volume of a cube whose sides measure exactly one metre.", + "name": "cubic metre", + "symbol": "m3" + }, +] +``` + +## `POST /api/units/geturi` +Returns the uri of a certain units contained in the ontology OM. + +Example http request: +POST /api/units/geturi HTTP/1.1 +Content-Type: application/json +Host: localhost:5010 +Content-Length: 22 + +```JSON +{ + "uname": "metre" +} +``` + +Response is a JSON object of the following form: + +```JSON +{ + "URI": "http://www.ontology-of-units-of-measure.org/resource/om-2/metre" +} +``` + +## `POST /api/units/validate´ +Validates user typed in units. For example 'diametre' is no unit. + +Example http request: +POST /api/units/validate HTTP/1.1 +Content-Type: application/json +Host: localhost:5010 +Content-Length: 24 + +```JSON +{ + "ustring": "metre" +} +``` + +Respose: true / false + +## `POST /api/units/saveconcept´ +Is an endpoint for saving concepts in the entity 'mdb_concepts' in the MDB. + +Example http request: +POST /api/units/saveconcept HTTP/1.1 +Content-Type: application/json +Host: localhost:5010 +Content-Length: 97 + +```JSON +{ + "name": "metre", + "uri": "http://www.ontology-of-units-of-measure.org/resource/om-2/metre" +} +``` + +The response is a postgres status message, e.g., + +"\"INSERT 0 1\"" + +## `POST /api/units/savecolumnsconcept' +Saves values in the entity 'mdb\_columns\_concepts', which realizes the relation between 'mdb\_columns' and 'mdb\_concepts'. Make sure the concept is contained in 'mdb\_concepts'. + +Example http request: +POST /api/units/savecolumnsconcept HTTP/1.1 +Content-Type: application/json +Host: localhost:5010 +Content-Length: 122 + +```JSON +{ + "cdbid": "1", + "cid": "1", + "tid": "1", + "uri": "http://www.ontology-of-units-of-measure.org/resource/om-2/metre" +} +``` + +The response is a postgres status message, e.g., + +"\"INSERT 0 1\"" diff --git a/fda-units-service/app.py b/fda-units-service/app.py index ea06cd0997c94a557968ef3a540e1920f48ee5ab..e997cdb527177e88896a4a2d848e30d15bf50848 100644 --- a/fda-units-service/app.py +++ b/fda-units-service/app.py @@ -8,6 +8,7 @@ from flasgger.utils import swag_from from flasgger import LazyString, LazyJSONEncoder from list import list_units, get_uri from validate import validator, stringmapper +from save import insert_mdb_concepts, insert_mdb_columns_concepts app = Flask(__name__) app.config["SWAGGER"] = {"title": "FDA-Units-Service", "uiversion": 3} @@ -47,32 +48,62 @@ def suggest(): res = {"success": False, "message": str(e)} return jsonify(res), 500 -@app.route('/api/units/validate', methods=["POST"], endpoint='validate') +@app.route('/api/units/validate/<unit>', methods=["GET"], endpoint='validate') @swag_from('validate.yml') -def valitate(): - input_json = request.get_json() +def valitate(unit): try: - unit = str(input_json['ustring']) - res = validator(stringmapper(unit)) + res = validator(unit) return str(res), 200 except Exception as e: print(e) res = {"success": False, "message": str(e)} return jsonify(res) -@app.route('/api/units/geturi', methods=["POST"], endpoint='geturi') +@app.route('/api/units/uri/<uname>', methods=["GET"], endpoint='uri') @swag_from('geturi.yml') -def geturi(): - input_json = request.get_json() +def geturi(uname): try: - name = str(input_json['uname']) - res = get_uri(name) + res = get_uri(uname) return jsonify(res), 200 except Exception as e: print(e) res = {"success": False, "message": str(e)} return jsonify(res), 500 +@app.route('/api/units/saveconcept', methods=["POST"], endpoint='saveconcept') +@swag_from('saveconcept.yml') +def saveconcept(): + input_json = request.get_json() + try: + uri = str(input_json['uri']) + c_name = str(input_json['name']) + if insert_mdb_concepts(uri, c_name) > 0: + return jsonify({'uri': uri}), 201 + else: + return jsonify({'status': 'error'}), 400 + except Exception as e: + print(e) + res = {"success": False, "message": str(e)} + return jsonify(res), 500 + +@app.route('/api/units/savecolumnsconcept', methods=["POST"], endpoint='savecolumnsconcept') +@swag_from('savecolumnsconcept.yml') +def saveconcept(): + input_json = request.get_json() + try: + uri = str(input_json['uri']) + cid = int(input_json['cid']) + tid = int(input_json['tid']) + cdbid = int(input_json['cdbid']) + if insert_mdb_columns_concepts(cdbid, tid, cid, uri)>0: + return jsonify({'uri': uri}), 201 + else: + return jsonify({'status': 'error'}), 400 + except Exception as e: + print(e) + res = {"success": False, "message": str(e)} + return jsonify(res), 500 + rest_server_port = 5010 eureka_client.init(eureka_server=os.getenv('EUREKA_SERVER', 'http://localhost:9090/eureka/'), app_name="fda-units-service", @@ -82,4 +113,4 @@ eureka_client.init(eureka_server=os.getenv('EUREKA_SERVER', 'http://localhost:90 if __name__ == '__main__': http_server = WSGIServer(('', 5010), app) - http_server.serve_forever() \ No newline at end of file + http_server.serve_forever() diff --git a/fda-units-service/requirements.txt b/fda-units-service/requirements.txt index f02b36dbab54b8a979ba54f0f743ef52ea0ea952..e714c83cacf434ac0848cdb6ee8406fe1a568045 100644 --- a/fda-units-service/requirements.txt +++ b/fda-units-service/requirements.txt @@ -4,3 +4,4 @@ py-eureka-client==0.9.1 docker==5.0.0 gevent==21.8.0 rdflib==6.0.2 +psycopg2-binary==2.8.6 diff --git a/fda-units-service/save.py b/fda-units-service/save.py new file mode 100644 index 0000000000000000000000000000000000000000..fbe400bac95f7175590dd714a64b0377ddc47198 --- /dev/null +++ b/fda-units-service/save.py @@ -0,0 +1,45 @@ +from psycopg2 import connect +import psycopg2.extras +import json + +def insert_mdb_concepts(uri, c_name): + try: + # Connecting to metadatabase + conn=connect( + dbname="fda", + user = "postgres", + host = "fda-metadata-db", + password = "postgres" + ) + + cursor = conn.cursor() + + # Insert tblnames into table mdb_TABLES + cursor.execute("INSERT INTO mdb_concepts (URI,name,created) VALUES (%s,%s,current_timestamp) ON CONFLICT (URI) DO NOTHING", (uri,c_name)) + r = cursor.rowcount + conn.commit() + conn.close() + except Exception as e: + print("Error while connecting to metadatabase.",e) + return r + +def insert_mdb_columns_concepts(cdbid,tid, cid, uri): + try: + # Connecting to metadatabase + conn=connect( + dbname="fda", + user = "postgres", + host = "fda-metadata-db", + password = "postgres" + ) + + cursor = conn.cursor() + + # Insert tblnames into table mdb_TABLES + cursor.execute("INSERT INTO mdb_columns_concepts (cDBID,tID, cID,URI,created) VALUES (%s,%s,%s,%s,current_timestamp) ON CONFLICT (cDBID, tID, cID, URI) DO NOTHING", (cdbid,tid,cid,uri)) + r = cursor.rowcount + conn.commit() + conn.close() + except Exception as e: + print("Error while connecting to metadatabase.",e) + return r \ No newline at end of file diff --git a/fda-units-service/us-yml/geturi.yml b/fda-units-service/us-yml/geturi.yml index cefbb9c04aa70e2bf86cbfa0f1bd2c0d3fb9cdb3..b79cf9032756db339a57ad2b7e76ae57da57e13b 100644 --- a/fda-units-service/us-yml/geturi.yml +++ b/fda-units-service/us-yml/geturi.yml @@ -5,18 +5,13 @@ consumes: produces: - "application/json" parameters: -- in: "body" - name: "body" +- in: "path" + type: "string" + name: "uname" description: "to-do description" required: true - schema: - type: "object" - properties: - uname: - type: "string" - example : "metre" responses: 200: description: "OK" 405: - description: "Invalid input" \ No newline at end of file + description: "Invalid input" diff --git a/fda-units-service/us-yml/savecolumnsconcept.yml b/fda-units-service/us-yml/savecolumnsconcept.yml new file mode 100644 index 0000000000000000000000000000000000000000..ec662c1a3c5871956887fbf7fba7e530609304bd --- /dev/null +++ b/fda-units-service/us-yml/savecolumnsconcept.yml @@ -0,0 +1,31 @@ +summary: "Save concepts to MDB" +description: "This is a simple API for saving units and concepts." +consumes: +- "application/json" +produces: +- "application/json" +parameters: +- in: "body" + name: "body" + description: "to-do description" + required: true + schema: + type: "object" + properties: + uri: + type: "string" + example: "http://www.ontology-of-units-of-measure.org/resource/om-2/metre" + cid: + type: "integer" + example: "1" + tid: + type: "integer" + example: "1" + cdbid: + type: "integer" + example: "1" +responses: + 200: + description: "OK" + 405: + description: "Invalid input" diff --git a/fda-units-service/us-yml/saveconcept.yml b/fda-units-service/us-yml/saveconcept.yml new file mode 100644 index 0000000000000000000000000000000000000000..22144651f10048e2c2b8b440ce888735764f19ea --- /dev/null +++ b/fda-units-service/us-yml/saveconcept.yml @@ -0,0 +1,25 @@ +summary: "Save concepts to MDB" +description: "This is a simple API for saving units and concepts." +consumes: +- "application/json" +produces: +- "application/json" +parameters: +- in: "body" + name: "body" + description: "to-do description" + required: true + schema: + type: "object" + properties: + uri: + type: "string" + example: "http://www.ontology-of-units-of-measure.org/resource/om-2/metre" + name: + type: "string" + example: "metre" +responses: + 200: + description: "OK" + 405: + description: "Invalid input" diff --git a/fda-units-service/us-yml/validate.yml b/fda-units-service/us-yml/validate.yml index bd92c5cb29715274338bf0efe5b59c3ac78f05f8..01cbb337c1a66d5356e99214c4ca59215fc00f5f 100644 --- a/fda-units-service/us-yml/validate.yml +++ b/fda-units-service/us-yml/validate.yml @@ -5,18 +5,13 @@ consumes: produces: - "application/json" parameters: -- in: "body" - name: "body" +- in: "path" + type: "string" + name: "unit" description: "to-do description" required: true - schema: - type: "object" - properties: - ustring: - type: "string" - example : "metre" responses: 200: description: "OK" 405: - description: "Invalid input" \ No newline at end of file + description: "Invalid input"