From 3c5176237c6b27e2bf3661d7fcd8be074a2405f2 Mon Sep 17 00:00:00 2001 From: Purvansh Singh Date: Sun, 11 Jul 2021 17:47:57 +0530 Subject: [PATCH 1/5] README.md Updated. --- README.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 014ce9a..a708b2c 100644 --- a/README.md +++ b/README.md @@ -4,23 +4,38 @@ Creditrisk-poc is a Hydra powered API which serves loan portfolio data using EBA ## Features creditrisk-poc consist following features: -* Loan & Borrower classes. +* Loan ,Borrower & Collateral classes. * Borrower class collection. -* Loan & Borrower class are linked using a foreign key ("CounterpartyId"). +* Loan, Borrower & Collateral classes are linked using `foreign keys`. * Loan class can perform all the CRUD operations ( GET, PUT, POST, DELETE). * Borrower can perform all the CRUD operations. * Borrower class collection can perform all the CRUD operations. +## Classes are linked in the following manner: + +## NonPerformingLoan.jsonld +The `NonPerformingLoan.jsonld` is a subset vocabulary for NonPerformingLoan portfolios, +vocabulary is generated automatically using `vocab_generator.py` from `NonperformingLoan.owl` ontology. +```bash +python npl_vocab/vocab_generator.py +``` +It will generate the JSON-LD vocabulary which can be used to create ApiDoc. + ## API_DOC -API_Doc is generated through hydra-python-core module doc_writer. +API_Doc is generated through hydra-python-core module `doc_writer` and `nplvoac_parse.py` which automates the creation +of classes and properties from JSON-LD vocabulary. -API_Doc & doc_writer file can be found here : +API_Doc, doc_writer & `nplvocab_parser.py` files can be found here : ``` api_doc | |___ ApiDoc.jsonld |___ api_docwriter.py +|___ nplvocab_parser.py ``` +**nplvocab_parser** parse all the classes & properties from `NonPerformingLoan.jsonld` and provide functions for converting +them to HydraClass & HydraClassProp. + `ApiDoc` is a JSON serialized object, It can be accessed as follows: ```python import json @@ -30,6 +45,10 @@ doc = json.load(ApiDoc_file) ``` you will get the doc in `python dict` format. +### ApiDoc is generated with this flow: +``` +NonPerformingLoan.owl --> ( vocab_generator.py ) NonPerformingLoan.jsonld --> ( nplvocab_parser.py) ApiDoc.jsonld +``` ## Demo To run hydra powered creditrisk-poc API, just do the following: 1) Clone creditrisk-poc From 00a6c8c83cf9cbb3eb2bd6b94b76c19751b427b3 Mon Sep 17 00:00:00 2001 From: Purvansh Singh Date: Sun, 11 Jul 2021 17:49:46 +0530 Subject: [PATCH 2/5] Diagram updated --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a708b2c..55b1ef4 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ creditrisk-poc consist following features: * Borrower class collection can perform all the CRUD operations. ## Classes are linked in the following manner: +![Creditrisk_class_linking](https://user-images.githubusercontent.com/49719371/125194774-4d897280-e270-11eb-95af-4242bb1bffc2.jpg) + ## NonPerformingLoan.jsonld The `NonPerformingLoan.jsonld` is a subset vocabulary for NonPerformingLoan portfolios, From 56fde0e9650858ad620c89c5d1b5b74baaa5a98a Mon Sep 17 00:00:00 2001 From: Purvansh Singh Date: Sun, 11 Jul 2021 21:54:06 +0530 Subject: [PATCH 3/5] collection_iri test Added. --- tests/conftest.py | 6 ++++-- tests/test_functional.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 9a0026b..b88e239 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,6 +4,8 @@ import json import uuid import os +from os.path import abspath, dirname +from pathlib import Path from hydra_python_core import doc_maker from hydra_python_core.doc_writer import DocUrl, HydraLink from sqlalchemy import create_engine @@ -121,8 +123,8 @@ def test_doc(constants): """ HYDRUS_SERVER_URL = constants['HYDRUS_SERVER_URL'] API_NAME = constants['API_NAME'] - API_DOC_PATH = os.path.relpath("tests/ApiDoc.jsonld") - print(API_DOC_PATH) + cwd_path = Path(dirname(dirname(abspath(__file__)))) + API_DOC_PATH = cwd_path / "tests" / "ApiDoc.jsonld" doc_file = open(API_DOC_PATH, "r") doc = json.load(doc_file) diff --git a/tests/test_functional.py b/tests/test_functional.py index 6381989..09e3590 100644 --- a/tests/test_functional.py +++ b/tests/test_functional.py @@ -8,6 +8,7 @@ import json import re import uuid +from hydra_python_core.doc_writer import DocUrl from tests.conftest import gen_dummy_object @@ -338,3 +339,30 @@ def test_Collections_member_DELETE(self, test_app_client, constants, doc): delete_response = test_app_client.delete(full_endpoint) assert delete_response.status_code == 200 + def test_IriTemplate(self, test_app_client, constants, doc): + """Test structure of IriTemplates attached to parsed classes""" + API_NAME = constants['API_NAME'] + index = test_app_client.get(f'/{API_NAME}') + assert index.status_code == 200 + endpoints = json.loads(index.data.decode('utf-8')) + expanded_base_url = DocUrl.doc_url + for endpoint in endpoints['collections']: + collection_name = '/'.join(endpoint["@id"].split(f'/{API_NAME}/')[1:]) + collection = doc.collections[collection_name]['collection'] + class_name = collection.manages["object"].split(expanded_base_url)[1] + response_get = test_app_client.get(endpoint["@id"]) + assert response_get.status_code == 200 + response_get_data = json.loads(response_get.data.decode('utf-8')) + assert 'search' in response_get_data + assert 'hydra:mapping' in response_get_data['search'] + class_ = doc.parsed_classes[class_name]['class'] + class_props = [x.prop for x in class_.supportedProperty] + for mapping in response_get_data['search']['hydra:mapping']: + prop = mapping['hydra:property'] + prop_name = mapping['hydra:variable'] + is_valid_class_prop = prop not in ['limit', 'offset', 'pageIndex'] + # check if IRI property is for searching through a nested_class + # and not this class_ + is_nested_class_prop = "[" in prop_name and "]" in prop_name + if is_valid_class_prop and not is_nested_class_prop: + assert prop in class_props From f4668f5d2fe67cddd930bb9c6ff181f4506e9381 Mon Sep 17 00:00:00 2001 From: Purvansh Singh Date: Sun, 11 Jul 2021 22:24:25 +0530 Subject: [PATCH 4/5] vocab_generator doc added --- docs/vocab_generator.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 docs/vocab_generator.md diff --git a/docs/vocab_generator.md b/docs/vocab_generator.md new file mode 100644 index 0000000..eb1a07e --- /dev/null +++ b/docs/vocab_generator.md @@ -0,0 +1,17 @@ +# vocab_generator + +`vocab_genrator.py` generates `NonPerformingLoan.jsonld` vocabulary from the owl ontology. + +It is located inside the `npl_vocab` directory. +```python +npl_vocab +| +|___ vocab_generator.py +``` +vocab_generator uses [rdflib](https://github.com/RDFLib/rdflib-jsonld) and [pyld](https://github.com/digitalbazaar/pyld) libaries to parse & serialize owl ontology +to jsonld with the `@context.` + +To generate JSON-LD voabulary: +```python +python npl_vocab/vocab_generator.py +``` From 3a76a240d2708d20bc20c3853d20307ef2db3136 Mon Sep 17 00:00:00 2001 From: Purvansh Singh Date: Sun, 11 Jul 2021 23:05:01 +0530 Subject: [PATCH 5/5] nplvocab_parser doc added --- docs/nplvocab_parser.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 docs/nplvocab_parser.md diff --git a/docs/nplvocab_parser.md b/docs/nplvocab_parser.md new file mode 100644 index 0000000..b7be50e --- /dev/null +++ b/docs/nplvocab_parser.md @@ -0,0 +1,28 @@ +# nplvocab_parser + +`nplvocab_parser` parses all the classes & properties from `NonPerformingLoan.jsonld` and convert them to HydraClass & HydraClassProp. + +nplvocab_parser is located in `api_doc` directory +```python +api_doc +| +|___ nplvocab_parser.py +``` +It can be used by importing as a python module: +```python +import NPLVocab_parse as parser + +npl_vocab = parser.get_npl_vocab() +classes = parser.get_all_classes(npl_vocab) +hydra_classes = parser.create_hydra_classes(classes) +``` +nplvocab_parser provide following functions: +* `get_all_classes()` -> Return all the classes from the given Vocabulary. +* `create_hydra_classes()` -> Return list of HydraClass objects. +* `get_class_properties()` -> Return all the properties of the given class. +* `create_hydra_properties()` -> Return list of HydraclasProps from the list of properties. +* `get_class_id()` -> Returns the class id of given class. +* `add_operations_to_class()` -> Return list of hydra properties of given class. + + +