From bcddea086ccbf648c1b78ad7b6fe16485ddd05bb Mon Sep 17 00:00:00 2001 From: YaphetKG <45075777+YaphetKG@users.noreply.github.com> Date: Wed, 25 Oct 2023 12:01:57 -0400 Subject: [PATCH] Rti merge (#28) * tranql upgrade python/docker py to 3.10 * Update server.py to py3.10 yaml * Update tranql to redis-stack and add dev-conf and dev-schema files * Make conf.yml file configurable and add to README * Update requirements * updated docker compose to handle some errors with writing to redis and passing all values to tranql through env * fixing error produced by missing conf in tranql api call * fix uvicorn vulnerability issues related to Plater * remove all 'biolink:' additions in code * upgrade plater version to fix biolink issue * plater biolink changes * Tranql works with new biolink data model * updated Plater to new version * fixed plater version * bump version * force update fix, and flasgger version bump * bump old versions * more vul fixes, and version updates * down to zero vul --------- Co-authored-by: Nathan Braswell Co-authored-by: esurface Co-authored-by: braswent --- Dockerfile | 25 +++---- Dockerfile_Old | 26 +++++++ README.md | 67 ++++++++++++++++-- Vulnerabilities_Doc.md | 20 ++++++ docker-compose.yml | 21 ++++-- redis_data/dump.rdb | Bin 0 -> 123 bytes requirements.txt | 51 +++++++------ requirements_Old.txt | 30 ++++++++ setup.cfg | 2 +- src/tranql/_version.py | 2 +- src/tranql/api.py | 16 ++--- src/tranql/backplane/api/icees_api.py | 8 +-- src/tranql/backplane/server.py | 5 +- src/tranql/conf.test | 2 +- .../tranql/conf/dev-schema.yml | 6 +- src/tranql/conf/redis-schema.yml | 14 ++++ src/tranql/conf/schema.yaml | 2 +- src/tranql/dev-conf.yml | 4 ++ src/tranql/main.py | 5 +- src/tranql/tranql_ast.py | 6 +- src/tranql/tranql_schema.py | 12 ++-- src/tranql/util.py | 2 +- src/tranql/web/src/App.js | 6 +- 23 files changed, 246 insertions(+), 86 deletions(-) create mode 100644 Dockerfile_Old create mode 100644 Vulnerabilities_Doc.md create mode 100644 redis_data/dump.rdb create mode 100644 requirements_Old.txt rename dev-schema.yaml => src/tranql/conf/dev-schema.yml (64%) create mode 100644 src/tranql/conf/redis-schema.yml create mode 100644 src/tranql/dev-conf.yml diff --git a/Dockerfile b/Dockerfile index b8464df..4b164d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,10 @@ -FROM node:14.16.1-alpine as node -FROM python:3.7.3-alpine +FROM python:3.11.6-alpine3.18 +# FROM python:3.9.16-alpine3.17 +# FROM python:3.7.3-alpine OLD -COPY --from=node /usr/lib /usr/lib -COPY --from=node /usr/local/share /usr/local/share -COPY --from=node /usr/local/lib /usr/local/lib -COPY --from=node /usr/local/include /usr/local/include -COPY --from=node /usr/local/bin /usr/local/bin - -RUN apk add --update build-base git libxslt-dev linux-headers make zeromq zeromq-dev -RUN npm i -g npm@9.4.2 +RUN apk add --update build-base git libxslt-dev linux-headers make nodejs-current npm zeromq zeromq-dev +RUN apk upgrade libssl3 libcrypto3 +# RUN apk add ncurses-libs=6.3_p20221119-r1 ENV USER tranql ENV HOME /home/$USER @@ -24,13 +20,12 @@ ENV BACKPLANE=http://tranql-backplane.renci.org COPY --chown=$USER . tranql/ -WORKDIR $HOME/tranql/src/tranql/web -RUN npm install --legacy-peer-deps -ENV NODE_OPTIONS=--max-old-space-size=4096 -ENV GENERATE_SOURCEMAP=false -RUN npm run build +# WORKDIR $HOME/tranql/src/tranql/web +# RUN npm install +# RUN GENERATE_SOURCEMAP=false npm run build WORKDIR $HOME/tranql RUN pip install --user --upgrade pip RUN pip install --user -r requirements.txt +RUN pip uninstall -y py ENV PYTHONPATH=$HOME/tranql/src/ diff --git a/Dockerfile_Old b/Dockerfile_Old new file mode 100644 index 0000000..5503a83 --- /dev/null +++ b/Dockerfile_Old @@ -0,0 +1,26 @@ +FROM python:3.7.3-alpine + +RUN apk add --update build-base git libxslt-dev linux-headers make nodejs-current nodejs-npm zeromq zeromq-dev + +ENV USER tranql +ENV HOME /home/$USER + +RUN addgroup -S $USER && adduser -S $USER -G $USER -s /bin/bash -h $HOME + +USER $USER +WORKDIR $HOME + +ENV PATH=$HOME/.local/bin:$PATH +ENV PUBLIC_URL={{web_prefix}} +ENV BACKPLANE=http://tranql-backplane.renci.org + +COPY --chown=$USER . tranql/ + +WORKDIR $HOME/tranql/src/tranql/web +RUN npm install +RUN GENERATE_SOURCEMAP=false npm run build + +WORKDIR $HOME/tranql +RUN pip install --user --upgrade pip +RUN pip install --user -r requirements.txt +ENV PYTHONPATH=$HOME/tranql/src/ diff --git a/README.md b/README.md index 560ba52..c8313cf 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ TranQL is brand new and strictly alpha. ### Install: -Requires Python 3.7.x. +Requires Python>=3.10 ``` git clone @@ -128,17 +128,69 @@ pip install -r tranql/requirements.txt ``` bin/test ``` -### Run -To run a program, first start the backplane: +### Local Dev Environment + +Run `TranQL` locally in a development environment. This set up uses the `./src/tranql/dev-conf.yml` configuration file +and the `./src/tranql/conf/dev-schema.yml` file. Update those to edit your local configuration. + +1. Set up local environment variables +``` +export REDIS_PASSWORD= +export SCHEMA_CONFIG_PATH=./src/tranql/conf/dev-schema.yml +``` + +2. Look at `dev-schema.yml` file + - Current default is to use `redis` as the database + +3. Install an editable build + +``` +pip install -e . +``` + +4. Choose your server + - Non-docker: + To run a program, first start the backplane: + ``` + cd backplane + PYTHONPATH=$PWD/../.. python server.py + ``` + - Docker with redis + ``` + docker-compose build redis + docker-compose up redis + ``` +5. Run a query + +``` +python main.py --source queries/workflow-5.tranql ``` -cd backplane -PYTHONPATH=$PWD/../.. python server.py + +### Local Docker Environment + +Run `TranQL` in a local docker environment using `docker-compose`. This will use the configurations +in the docker the `docker-compose.yml` file + +1. Set the local environment variables +``` +export REDIS_PASSWORD= +export SCHEMA_CONFIG_PATH=./src/tranql/conf/redis-schema.yml +``` + +2. Build and start the docker containers ``` -Then run the query: +docker-compose build +docker-compose up ``` -bin/tranql --source tranql/queries/workflow-5.tranql + +3. Run a query + +``` +python main.py --source queries/workflow-5.tranql ``` + + ### Web app To run the web app, first start the TranQL API: @@ -149,6 +201,7 @@ PYTHONPATH=$PWD/../ python api.py ``` Then follow the instructions in web/ to start the website. + ### Shell Run the interactive interpreter. diff --git a/Vulnerabilities_Doc.md b/Vulnerabilities_Doc.md new file mode 100644 index 0000000..9a06c0e --- /dev/null +++ b/Vulnerabilities_Doc.md @@ -0,0 +1,20 @@ +# Tranql Vulnerabilities + +## tranql/Requirements.txt file + +### Pip packages + +- flask-cors: High 3.0.7 => fix 3.0.9 +- jinja2: High 2.10 => fix 2.10.1 +- pyyaml: 3 CRITICAL 5.1 => Test newest version at 6.0 + +### Git repositories + +- git+ +- git+ +- git+ + +## tranql/src/tranql/web/package.json file + +Completely broken... cannot build locally. +Tons of conflicting dependencies... checking with Renci if UI is even used. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 3e12c40..c460f2c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,12 +7,23 @@ services: ports: - "8001:8001" command: gunicorn --workers=1 --bind=0.0.0.0:8001 --name=tranql --timeout=600 --reload tranql.api:app - environment: - - SCHEMA_CONFIG_PATH=/home/tranql/dev-schema.yaml + env_file: .env volumes: - ./src:/home/tranql/tranql/src - - ./dev-schema.yaml:/home/tranql/dev-schema.yaml - redis_graph: - image: redislabs/redisgraph + - ./src/tranql/conf/redis-schema.yml:/home/tranql/schema.yaml + + ################################################################################# + ## + ## A memory cache for results of high volume service requests. + ## https://redis.io/docs/stack/get-started/install/docker/ + ## + ################################################################################# + redis: + image: 'redis/redis-stack:6.2.4-v2' + environment: + - REDIS_ARGS=--requirepass $REDIS_PASSWORD + - REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL + ports: + - '6379:6379' volumes: - ./redis_data:/data \ No newline at end of file diff --git a/redis_data/dump.rdb b/redis_data/dump.rdb new file mode 100644 index 0000000000000000000000000000000000000000..637808d3a9b09b3d59a0e6736863ea5bcbf3c51e GIT binary patch literal 123 zcmWG?b@2=~Ffg$E#aWb^l3A=sPIab~ zUmT^ysVTa-skw(De(^B;;z`U;(=8}UP0UToNj<>uy|HQA%GPUZGkBO7nHZ3{OhE4c N>OA@Gy*nS50RRJkFev~4 literal 0 HcmV?d00001 diff --git a/requirements.txt b/requirements.txt index 9afcafd..0281155 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,30 +1,35 @@ -aiohttp==3.5.4 +aiohttp==3.8.6 +bmt==0.8.12 coverage==4.5.3 -flasgger==0.9.2 -flask==1.0.2 -flask-cors==3.0.7 -flask-restx==0.5.1 -gunicorn==19.9.0 -MarkupSafe==2.0.1 -itsdangerous==2.0.1 -jinja2==2.10 +flasgger==0.9.5 +Flask==2.2.5 +Flask-Compress==1.13 +Flask-Cors==3.0.10 +flask-restx>=1.0.3 +gunicorn==21.2.0 +Jinja2==3.1.2 jsonpath-rw==1.4.0 -networkx~=2.5.0 +linkml==1.4.6 +linkml-dataops==0.1.0 +linkml-runtime==1.3.2 +MarkupSafe==2.1.1 openapi==1.1.0 +git+https://github.com/RTIInternational/Plater.git@v0.0.4 +git+https://github.com/TranslatorSRI/reasoner-pydantic@v1.0.0#egg=reasoner-pydantic +git+https://github.com/TranslatorSRI/reasoner-converter@1.2.4#egg=reasoner-converter +reasoner-transpiler==1.7.1 +redis==4.1.4 +requests==2.31.0 +requests-cache==0.4.13 +requests-mock==1.5.2 +PyYAML==6.0.1 +python-Levenshtein==0.12.2 +networkx==2.8.8 pytest==5.4.1 pytest-cov==2.7.1 python-coveralls==2.9.2 python-dateutil==2.8.1 -pyyaml==5.1 -requests==2.25.1 -requests-cache==0.4.13 -requests-mock==1.5.2 -git+https://github.com/helxplatform/Plater.git@v2.0.1 -bmt==0.8.2 -linkml==1.1.17 -linkml-dataops==0.1.0 -linkml-runtime==1.1.21 -reasoner-transpiler==1.7.1 -python-levenshtein==0.12.2 -git+https://github.com/TranslatorSRI/reasoner-pydantic@v1.0.0#egg=reasoner-pydantic -git+https://github.com/TranslatorSRI/reasoner-converter@1.2.4#egg=reasoner-converter +redis==4.1.4 +werkzeug==2.2.3 +urllib3==1.26.17 +uvicorn \ No newline at end of file diff --git a/requirements_Old.txt b/requirements_Old.txt new file mode 100644 index 0000000..9afcafd --- /dev/null +++ b/requirements_Old.txt @@ -0,0 +1,30 @@ +aiohttp==3.5.4 +coverage==4.5.3 +flasgger==0.9.2 +flask==1.0.2 +flask-cors==3.0.7 +flask-restx==0.5.1 +gunicorn==19.9.0 +MarkupSafe==2.0.1 +itsdangerous==2.0.1 +jinja2==2.10 +jsonpath-rw==1.4.0 +networkx~=2.5.0 +openapi==1.1.0 +pytest==5.4.1 +pytest-cov==2.7.1 +python-coveralls==2.9.2 +python-dateutil==2.8.1 +pyyaml==5.1 +requests==2.25.1 +requests-cache==0.4.13 +requests-mock==1.5.2 +git+https://github.com/helxplatform/Plater.git@v2.0.1 +bmt==0.8.2 +linkml==1.1.17 +linkml-dataops==0.1.0 +linkml-runtime==1.1.21 +reasoner-transpiler==1.7.1 +python-levenshtein==0.12.2 +git+https://github.com/TranslatorSRI/reasoner-pydantic@v1.0.0#egg=reasoner-pydantic +git+https://github.com/TranslatorSRI/reasoner-converter@1.2.4#egg=reasoner-converter diff --git a/setup.cfg b/setup.cfg index 16ca521..9b264bd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,7 +19,7 @@ classifiers = package_dir = = src packages = find: -python_requires = >=3.7 +python_requires = 3.10 include_package_data = true install_requires = Flask diff --git a/src/tranql/_version.py b/src/tranql/_version.py index 08d7c07..2c2b3e3 100644 --- a/src/tranql/_version.py +++ b/src/tranql/_version.py @@ -1 +1 @@ -__version__ = "0.4.dev5" +__version__ = "1.0.dev0" diff --git a/src/tranql/api.py b/src/tranql/api.py index ed81ab5..e7931b4 100644 --- a/src/tranql/api.py +++ b/src/tranql/api.py @@ -69,7 +69,7 @@ def base_path(self): definitions_filename = os.path.join(os.path.dirname(__file__), definitions_filename) with open(filename, 'r') as file_obj: template = { - "definitions": yaml.load(file_obj)["definitions"], + "definitions": yaml.full_load(file_obj)["definitions"], "tags": [ {"name": "query"}, {"name": "schema"}, @@ -79,7 +79,7 @@ def base_path(self): ] } with open(definitions_filename, 'r') as definitions_file: - template['definitions'].update(yaml.load(definitions_file)) + template['definitions'].update(yaml.full_load(definitions_file)) swagger = Swagger(app, template=template, config={ "headers": [ @@ -549,7 +549,7 @@ def get(self): default: false description: Specifies if dynamic id lookup of curies will be performed """ - force_update = request.args.get("force_update") + force_update = request.args.get("force_update").lower() == 'true' tranql = TranQL (options={"registry": app.config.get('registry', False)}) schemafactory = tranql.schema_factory schema = schemafactory.get_instance(force_update=force_update) @@ -670,7 +670,7 @@ def post(self): type: string allowed_concept_types: description: > - List of allowed biolink types to search against, e.g. biolink:Disease. + List of allowed biolink types to search against, e.g. biolink.Disease. If null or empty, the search will execute against all supported types. Note that if searching against all types, a very high `query_limit` should be specified since it will be distributed evenly across every supported concept index in the redisgraph @@ -707,7 +707,7 @@ def post(self): """ query = request.json["query"] # Indexes are equal to node labels in the redisgraph instance, - # and each node label is simply a biolink concept type, e.g. biolink:Disease + # and each node label is simply a biolink concept type, e.g. biolink.Disease indexes = request.json.get("allowed_concept_types", None) fields = request.json.get("fields", None) prefix_search = request.json.get("prefix_search", True) @@ -728,7 +728,7 @@ def post(self): if indexes is None or len(indexes) == 0: concept_types = schema.schema[redis_schema_name]["schema"].keys() - indexes = ["biolink:" + title_case(concept_type) for concept_type in concept_types] + indexes = ["biolink." + title_case(concept_type) for concept_type in concept_types] return redis_adapter.search( @@ -739,8 +739,8 @@ def post(self): options={ "prefix_search": prefix_search, # Ensure results are linked to studies - "postprocessing_cypher": "MATCH (:`biolink:StudyVariable`)-[]-(node)" if study_linked else "", - # "postprocessing_cypher": "MATCH ()-[:`biolink:Association`|`biolink:association`|`biolink:Mentions`|`biolink:mentions`]->(node)" if study_linked else "", + "postprocessing_cypher": "MATCH (:`biolink.StudyVariable`)-[]-(node)" if study_linked else "", + # "postprocessing_cypher": "MATCH ()-[:`biolink.Association`|`biolink.association`|`biolink.Mentions`|`biolink.mentions`]->(node)" if study_linked else "", "levenshtein_distance": levenshtein_distance, "query_limit": query_limit } diff --git a/src/tranql/backplane/api/icees_api.py b/src/tranql/backplane/api/icees_api.py index 38efa2d..14f1144 100644 --- a/src/tranql/backplane/api/icees_api.py +++ b/src/tranql/backplane/api/icees_api.py @@ -238,13 +238,13 @@ def get_supported_type(self): def curify_type(self, concept_type_str): """ - Converts to biolink:TypeOfConcept from type_of_concept + Converts to biolink.TypeOfConcept from type_of_concept :param concept_type_str - :return: pascal case of type with prefix biolink: + :return: pascal case of type with prefix biolink. """ - if concept_type_str.startswith('biolink:'): + if concept_type_str.startswith('biolink.'): return concept_type_str - return 'biolink:' + string.capwords(concept_type_str.replace('_', ' '), ' ').replace(' ', '') + return string.capwords(concept_type_str.replace('_', ' '), ' ').replace(' ', '') def synonymize(self, response): knowledge_map_key = 'knowledge_map' diff --git a/src/tranql/backplane/server.py b/src/tranql/backplane/server.py index daf6972..a95a8d9 100644 --- a/src/tranql/backplane/server.py +++ b/src/tranql/backplane/server.py @@ -5,6 +5,7 @@ import logging import os import yaml +from yaml import BaseLoader from flask import Flask from flask_restx import Api from flasgger import Swagger @@ -30,9 +31,9 @@ filename = os.path.join (os.path.dirname (__file__), 'translator_interchange.yaml') definitions_filename = os.path.join (os.path.dirname (__file__), 'definitions.yaml') with open(filename, 'r') as file_obj: - template = yaml.load(file_obj) + template = yaml.load(file_obj, BaseLoader) with open(definitions_filename, 'r') as definitions_file: - template["definitions"].update(yaml.load(definitions_file)) + template["definitions"].update(yaml.load(definitions_file, BaseLoader)) template["tags"] = [ {"name" : "schema"}, {"name" : "query"}, diff --git a/src/tranql/conf.test b/src/tranql/conf.test index 196848e..9ceb6a0 100644 --- a/src/tranql/conf.test +++ b/src/tranql/conf.test @@ -1 +1 @@ - --- backplane: http://localhost \ No newline at end of file + --- backplane: http://localhost:8099 \ No newline at end of file diff --git a/dev-schema.yaml b/src/tranql/conf/dev-schema.yml similarity index 64% rename from dev-schema.yaml rename to src/tranql/conf/dev-schema.yml index b31e6da..7cf8a63 100644 --- a/dev-schema.yaml +++ b/src/tranql/conf/dev-schema.yml @@ -6,11 +6,9 @@ doc : | schema: redis: doc: | - Roger is a knowledge graph built by aggregeting several kgx formatted knowledge graphs from several sources. + Redis is a knowledge graph built by aggregeting several kgx formatted knowledge graphs from several sources. url: "redis:test" redis: true redis_connection_params: - host: redis_graph + host: 0.0.0.0 port: 6379 - # SET USERNAME and PASSWORD - # via ROGER_USERNAME , ROGER_PASSWORD Env vars (i.e capitialize service name) diff --git a/src/tranql/conf/redis-schema.yml b/src/tranql/conf/redis-schema.yml new file mode 100644 index 0000000..2558851 --- /dev/null +++ b/src/tranql/conf/redis-schema.yml @@ -0,0 +1,14 @@ +--- +doc : | + The Translator schema aggregates reasoner schemas. Reasoner schemas + describe transitions between biolink-model types. These transitions are + expressed as predicates, also from the biolink-model. +schema: + redis: + doc: | + Redis is a knowledge graph built by aggregeting several kgx formatted knowledge graphs from several sources. + url: "redis:test" + redis: true + redis_connection_params: + host: redis + port: 6379 diff --git a/src/tranql/conf/schema.yaml b/src/tranql/conf/schema.yaml index b1f74a3..131ae82 100644 --- a/src/tranql/conf/schema.yaml +++ b/src/tranql/conf/schema.yaml @@ -63,7 +63,7 @@ schema: url: "redis:test" redis: true redis_connection_params: - host: redis_graph + host: merge-redis-master port: 6379 # SET USERNAME and PASSWORD # via ROGER_USERNAME , ROGER_PASSWORD Env vars (i.e capitialize service name) diff --git a/src/tranql/dev-conf.yml b/src/tranql/dev-conf.yml new file mode 100644 index 0000000..2ed24a7 --- /dev/null +++ b/src/tranql/dev-conf.yml @@ -0,0 +1,4 @@ +--- +BACKPLANE: http://localhost:8099 +REDIS: true +REDIS_PASSWORD: $REDIS_PASSWORD diff --git a/src/tranql/main.py b/src/tranql/main.py index 4004e2d..7112dcb 100644 --- a/src/tranql/main.py +++ b/src/tranql/main.py @@ -96,6 +96,7 @@ def __init__(self, backplane="http://localhost:8099", options={}): config_path = "conf.yml" self.config = Config (config_path) + # TODO: Why is this used? t = os.path.join (os.path.dirname (__file__), "conf.test") with open(t, "w") as stream: stream.write (f" --- backplane: {self.config['BACKPLANE']}") @@ -231,6 +232,7 @@ def main (): formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=180)) arg_parser.add_argument('-v', '--verbose', help="Verbose mode.", action="store_true") + arg_parser.add_argument('-f', '--conf', help="Configuration file", default='conf.yml') arg_parser.add_argument('-c', '--cache', help="Cache responses from backplane services?", action="store_true") @@ -242,7 +244,7 @@ def main (): action="store_true") arg_parser.add_argument('-s', '--source', help="The program's source file") arg_parser.add_argument('-o', '--output', help="Output destination") - arg_parser.add_argument('-a', '--arg', help="Output destination", + arg_parser.add_argument('-a', '--arg', help="Some args", action="append", default=[]) # -x is placeholder as '-a' taken; should eventually replace with a more fitting letter arg_parser.add_argument('-x', '--asynchronous', default=True, help="Run requests asynchronously resulting in faster queries") @@ -271,6 +273,7 @@ def main (): "dynamic_id_resolution", "registry" ]} + options['config_file'] = args.conf tranql = TranQL (backplane = args.backplane, options = options) for k, v in query_args.items (): logger.debug (f"setting {k}={v}") diff --git a/src/tranql/tranql_ast.py b/src/tranql/tranql_ast.py index 73bdddf..7768ebd 100644 --- a/src/tranql/tranql_ast.py +++ b/src/tranql/tranql_ast.py @@ -304,7 +304,7 @@ def resolve_name (name, type_names): if not isinstance(type_names, list): type_names = [type_names] result = [] - type_names = [snake_case(type_name.replace('biolink:', '')) for type_name in type_names] + type_names = [snake_case(type_name.replace('biolink.', '')) for type_name in type_names] for type_name in type_names: equivalent_identifiers = Bionames.get_ids (name, type_name) for i in equivalent_identifiers: @@ -1028,8 +1028,8 @@ def plan_edge (self, plan, source, target, predicate): schema = None converted = False - source_type = snake_case(source.type_name.replace('biolink:', '')) - target_type = snake_case(target.type_name.replace('biolink:', '')) + source_type = snake_case(source.type_name.replace('biolink.', '')) + target_type = snake_case(target.type_name.replace('biolink.', '')) if predicate.direction == Query.back_arrow: source_type, target_type = target_type, source_type diff --git a/src/tranql/tranql_schema.py b/src/tranql/tranql_schema.py index 54e9636..0bfbd82 100644 --- a/src/tranql/tranql_schema.py +++ b/src/tranql/tranql_schema.py @@ -360,15 +360,15 @@ def __init__(self, backplane, use_registry, tranql_config, skip_redis=False): def snake_case_schema(self, schema): new_schema = {} for node in schema: - new_node_name = snake_case(node.replace('biolink:', '')) + new_node_name = snake_case(node.replace('biolink.', '')) sub_nodes = schema[node] new_schema[new_node_name] = new_schema.get(new_node_name, {}) for sub_node in sub_nodes: - new_subnode_name = snake_case(sub_node.replace('biolink:', '')) + new_subnode_name = snake_case(sub_node.replace('biolink.', '')) new_schema[new_node_name][new_subnode_name] = new_schema[new_node_name].get(new_subnode_name, []) predicates = sub_nodes[sub_node] for predicate in predicates: - new_predicate = snake_case(predicate.replace('biolink:', '')) + new_predicate = snake_case(predicate.replace('biolink.', '')) if new_predicate not in new_schema[new_node_name][new_subnode_name]: new_schema[new_node_name][new_subnode_name].append(new_predicate) return new_schema @@ -422,7 +422,7 @@ def toBiolink(concept): if isinstance(links, str): links = [links] for link in links: - biolink_link = "biolink:" + link + biolink_link = link if not biolink_link in edge_summary: continue (_, _, _, edge_data) = self.schema_graph.get_edge (source_name, target_type, link) individual_count = edge_summary[biolink_link] @@ -531,8 +531,8 @@ def validate_edge (self, source_type, target_type): :param source_type: A source type. :param target_type: A target type. """ - source_type = snake_case(source_type.replace('biolink:', '')) - target_type = snake_case(target_type.replace('biolink:', '')) + source_type = snake_case(source_type.replace('biolink.', '')) + target_type = snake_case(target_type.replace('biolink.', '')) edge = self.schema_graph.get_edge (start=source_type, end=target_type) if not edge: raise InvalidTransitionException (source_type, target_type, explanation=f'No valid transitions exist between {source_type} and {target_type} in this schema.') diff --git a/src/tranql/util.py b/src/tranql/util.py index 02cf75d..1211e6f 100644 --- a/src/tranql/util.py +++ b/src/tranql/util.py @@ -4,7 +4,7 @@ import json import os import re -from collections import Iterable +from collections.abc import Iterable from tranql.disease_vocab import DiseaseVocab from jinja2 import Template import copy diff --git a/src/tranql/web/src/App.js b/src/tranql/web/src/App.js index afdd40c..c1b8240 100644 --- a/src/tranql/web/src/App.js +++ b/src/tranql/web/src/App.js @@ -1021,7 +1021,7 @@ class App extends Component { */ _categoryToType(value) { if (value) { - const blStr = "biolink:"; + const blStr = "biolink."; var typeVal = value.substring(blStr.length, value.length); return typeVal.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) .map(x => x.toLowerCase()) @@ -1036,7 +1036,7 @@ class App extends Component { */ _typeToCategory(value) { if (value) { - const blStr = "biolink:"; + const blStr = "biolink."; const constituents = value.split("_"); const titleCaseValue = constituents.map((word) => word[0].toUpperCase() + word.slice(1)).join(""); return blStr + titleCaseValue; @@ -1083,7 +1083,7 @@ class App extends Component { link["source_id"] = link["subject"]; link["target_id"] = link["object"]; if (link["predicate"] !== undefined && link["predicate"] !== null) { - const blStr = "biolink:"; + const blStr = "biolink."; const predStr = link["predicate"]; const typeVal = predStr.substring(blStr.length, predStr.length); link["type"] = typeVal;