From 399eb7796c5149358304b51a2e4123a559e59921 Mon Sep 17 00:00:00 2001 From: mboudet Date: Fri, 1 Jul 2022 20:17:02 +0200 Subject: [PATCH] Release 4.4.0 (#356) --- .github/workflows/lint_test.yml | 6 +- CHANGELOG.md | 54 + Makefile | 39 +- Pipfile | 4 +- Pipfile.lock | 1295 ++++++++++------- README.md | 1 + askomics/api/admin.py | 310 ++++ askomics/api/data.py | 12 +- askomics/api/datasets.py | 7 + askomics/api/file.py | 31 +- askomics/api/ontology.py | 59 + askomics/api/query.py | 8 +- askomics/api/results.py | 10 +- askomics/api/sparql.py | 2 +- askomics/api/start.py | 9 +- askomics/app.py | 4 +- askomics/libaskomics/BedFile.py | 32 +- askomics/libaskomics/CsvFile.py | 114 +- askomics/libaskomics/Database.py | 115 ++ askomics/libaskomics/Dataset.py | 61 +- askomics/libaskomics/DatasetsHandler.py | 10 +- askomics/libaskomics/File.py | 12 +- askomics/libaskomics/FilesHandler.py | 122 +- askomics/libaskomics/GffFile.py | 56 +- askomics/libaskomics/LocalAuth.py | 20 +- askomics/libaskomics/OntologyManager.py | 279 ++++ askomics/libaskomics/PrefixManager.py | 82 +- askomics/libaskomics/RdfFile.py | 33 +- askomics/libaskomics/RdfGraph.py | 1 + askomics/libaskomics/Result.py | 29 +- askomics/libaskomics/SparqlQuery.py | 254 +++- askomics/libaskomics/SparqlQueryLauncher.py | 15 +- askomics/libaskomics/TriplestoreExplorer.py | 69 +- .../react/src/components/autocomplete.jsx | 147 ++ askomics/react/src/navbar.jsx | 4 +- askomics/react/src/routes.jsx | 9 +- askomics/react/src/routes/admin/admin.jsx | 3 +- .../react/src/routes/admin/datasetstable.jsx | 2 +- .../react/src/routes/admin/ontologies.jsx | 365 +++++ askomics/react/src/routes/admin/prefixes.jsx | 257 ++++ askomics/react/src/routes/ask/ask.jsx | 7 +- askomics/react/src/routes/data/data.jsx | 10 +- .../src/routes/datasets/datasetstable.jsx | 4 +- askomics/react/src/routes/form/attribute.jsx | 100 +- askomics/react/src/routes/form/query.jsx | 17 +- .../react/src/routes/form_edit/attribute.jsx | 100 +- askomics/react/src/routes/form_edit/query.jsx | 20 +- .../routes/integration/advancedoptions.jsx | 10 +- .../src/routes/integration/bedpreview.jsx | 23 +- .../react/src/routes/integration/csvtable.jsx | 74 +- .../src/routes/integration/gffpreview.jsx | 30 +- .../src/routes/integration/integration.jsx | 5 +- .../src/routes/integration/rdfpreview.jsx | 23 +- askomics/react/src/routes/query/attribute.jsx | 142 +- .../react/src/routes/query/graphfilters.js | 8 +- .../react/src/routes/query/ontolinkview.jsx | 46 + askomics/react/src/routes/query/query.jsx | 163 ++- .../react/src/routes/query/visualization.jsx | 2 +- .../src/routes/results/resultsfilestable.jsx | 3 +- .../react/src/routes/sparql/resultstable.jsx | 2 +- .../react/src/routes/upload/filestable.jsx | 15 + .../react/src/routes/upload/uploadurlform.jsx | 6 +- askomics/static/about.html | 2 +- askomics/static/css/askomics.css | 35 +- askomics/tasks.py | 41 +- config/askomics.ini.template | 36 +- config/askomics.test.ini | 33 +- docker/Dockerfile | 6 +- docker/DockerfileAll | 6 +- docker/DockerfileCelery | 4 +- docs/abstraction.md | 179 ++- docs/ci.md | 2 +- docs/cli.md | 13 + docs/configure.md | 5 +- docs/console.md | 51 + docs/contribute.md | 6 +- docs/data.md | 181 ++- docs/dev-deployment.md | 6 +- docs/docs.md | 8 +- docs/federation.md | 36 +- docs/galaxy.md | 19 +- docs/img/askogalaxy.png | Bin 15352 -> 15318 bytes docs/img/askograph.png | Bin 0 -> 34589 bytes docs/img/attribute_box.png | Bin 0 -> 1560 bytes docs/img/attributes.png | Bin 0 -> 15032 bytes docs/img/csv_convert.png | Bin 0 -> 251893 bytes docs/img/custom_nodes.png | Bin 0 -> 5745 bytes docs/img/external_startpoint.png | Bin 11895 -> 11646 bytes docs/img/faldo.png | Bin 0 -> 18666 bytes docs/img/filters.png | Bin 0 -> 2612 bytes docs/img/form.png | Bin 0 -> 4052 bytes docs/img/form_edit.png | Bin 0 -> 12392 bytes docs/img/form_example.png | Bin 0 -> 12575 bytes docs/img/gff.png | Bin 2854 -> 2275 bytes docs/img/gff_preview.png | Bin 11601 -> 11892 bytes docs/img/minus.png | Bin 0 -> 13218 bytes docs/img/ontology_autocomplete.png | Bin 0 -> 13559 bytes docs/img/ontology_graph.png | Bin 0 -> 17176 bytes docs/img/ontology_integration.png | Bin 0 -> 6323 bytes docs/img/ontology_link.png | Bin 0 -> 13408 bytes docs/img/sparql.png | Bin 0 -> 119634 bytes docs/img/startpoint.png | Bin 15514 -> 15434 bytes docs/img/template.png | Bin 0 -> 3700 bytes docs/img/union.png | Bin 0 -> 16347 bytes docs/img/union_duplicated.png | Bin 0 -> 15609 bytes docs/index.md | 18 +- docs/issues.md | 1 - docs/manage.md | 45 +- docs/ontologies.md | 60 + docs/prefixes.md | 11 + docs/production-deployment.md | 8 +- docs/query.md | 299 ++++ docs/requirements.txt | 3 +- docs/results.md | 79 + docs/style.css | 23 +- docs/template.md | 98 ++ docs/tutorial.md | 115 +- mkdocs.yml | 18 +- package-lock.json | 160 +- package.json | 8 +- setup.py | 6 +- test-data/agro_min.ttl | 70 + test-data/gene.bed | 2 +- test-data/gene.gff3 | 2 + test-data/transcripts.tsv | 22 +- tests/__init__.py | 3 + tests/conftest.py | 95 +- tests/results/abstraction.json | 62 +- tests/results/data.json | 54 - tests/results/data_full.json | 62 + tests/results/data_public.json | 54 + tests/results/init.json | 2 +- tests/results/preview.json | 28 +- tests/results/preview_files.json | 36 +- tests/results/preview_malformed_files.json | 2 +- tests/results/results.json | 2 +- tests/results/results_admin.json | 2 +- tests/results/results_form.json | 2 +- tests/results/sparql_and_graph.json | 3 +- tests/results/sparql_preview.json | 22 +- tests/results/sparql_query.json | 2 +- tests/results/startpoints.json | 12 +- tests/test_api.py | 5 +- tests/test_api_admin.py | 247 +++- tests/test_api_data.py | 12 +- tests/test_api_datasets.py | 30 +- tests/test_api_file.py | 95 +- tests/test_api_ontology.py | 73 + tests/test_api_query.py | 6 +- 149 files changed, 5825 insertions(+), 1555 deletions(-) create mode 100644 askomics/api/ontology.py create mode 100644 askomics/libaskomics/OntologyManager.py create mode 100644 askomics/react/src/components/autocomplete.jsx create mode 100644 askomics/react/src/routes/admin/ontologies.jsx create mode 100644 askomics/react/src/routes/admin/prefixes.jsx create mode 100644 askomics/react/src/routes/query/ontolinkview.jsx create mode 100644 docs/cli.md create mode 100644 docs/console.md create mode 100644 docs/img/askograph.png create mode 100644 docs/img/attribute_box.png create mode 100644 docs/img/attributes.png create mode 100644 docs/img/csv_convert.png create mode 100644 docs/img/custom_nodes.png create mode 100644 docs/img/faldo.png create mode 100644 docs/img/filters.png create mode 100644 docs/img/form.png create mode 100644 docs/img/form_edit.png create mode 100644 docs/img/form_example.png create mode 100644 docs/img/minus.png create mode 100644 docs/img/ontology_autocomplete.png create mode 100644 docs/img/ontology_graph.png create mode 100644 docs/img/ontology_integration.png create mode 100644 docs/img/ontology_link.png create mode 100644 docs/img/sparql.png create mode 100644 docs/img/template.png create mode 100644 docs/img/union.png create mode 100644 docs/img/union_duplicated.png delete mode 100644 docs/issues.md create mode 100644 docs/ontologies.md create mode 100644 docs/prefixes.md create mode 100644 docs/query.md create mode 100644 docs/results.md create mode 100644 docs/template.md create mode 100644 test-data/agro_min.ttl delete mode 100644 tests/results/data.json create mode 100644 tests/results/data_full.json create mode 100644 tests/results/data_public.json create mode 100644 tests/test_api_ontology.py diff --git a/.github/workflows/lint_test.yml b/.github/workflows/lint_test.yml index 1be124fb..84ca6d05 100644 --- a/.github/workflows/lint_test.yml +++ b/.github/workflows/lint_test.yml @@ -8,7 +8,7 @@ jobs: uses: actions/checkout@v2 - uses: actions/setup-python@v1 with: - python-version: 3.7 + python-version: 3.8 - name: Install flake8 run: pip install flake8 - name: Flake8 @@ -33,7 +33,7 @@ jobs: uses: actions/checkout@v2 - uses: actions/setup-python@v1 with: - python-version: 3.6 + python-version: 3.8 - name: Update apt cache run: sudo apt-get update - name: Install python-ldap deps @@ -50,7 +50,7 @@ jobs: docker pull xgaia/corese:latest docker pull xgaia/isql-api:2.1.1 docker pull xgaia/simple-ldap:latest - docker run -d --name virtuoso -p 8891:8890 -p 1112:1111 -e DBA_PASSWORD=dba -e SPARQL_UPDATE=true -e DEFAULT_GRAPH=http://localhost:8891/DAV -t askomics/virtuoso:7.2.5.1 /bin/sh -c "netstat -nr | grep '^0\.0\.0\.0' | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])' | grep -v '^0\.0\.0\.0' | sed 's/$/ askomics-host/' >> /etc/hosts && /virtuoso/virtuoso.sh" + docker run -d --name virtuoso -p 8891:8890 -p 1112:1111 -e DBA_PASSWORD=dba -e DEFAULT_GRAPH=http://localhost:8891/DAV -t askomics/virtuoso:7.2.5.1 /bin/sh -c "netstat -nr | grep '^0\.0\.0\.0' | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])' | grep -v '^0\.0\.0\.0' | sed 's/$/ askomics-host/' >> /etc/hosts && /virtuoso/virtuoso.sh" sleep 1m docker run -d --name redis -p 6380:6379 -t redis:4.0 docker run -d --name galaxy -p 8081:80 -t bgruening/galaxy-stable:20.05 diff --git a/CHANGELOG.md b/CHANGELOG.md index a6897dd9..0766ab02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,60 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 This changelog was started for release 4.2.0. +## [4.4.0] - 2022-07-01 + +### Fixed + +- Fixed an issue with forms (missing field and entity name for label & uri fields) (Issue #255) +- Fixed an issue with the data endpoint for FALDO entities (Issue #279) +- Fixed an issue where integration would fail when setting a category type on a empty column (#334) +- Fixed an issue with saved queries for non-logged users + +### Added + +- Added 'scaff' for autodetection of 'reference' columns +- Added a 'Label' column type: only for second column in CSV files. Will use this value if present, else default to old behavior +- Added button to hide FALDO relations (*included_in*) +- Added 'target=_blank' in query results +- Remote upload is now sent in a Celery task +- Added 'Status' for files (for celery upload, and later for better file management) +- Added tooltips to buttons in the query form (and other forms) +- Added owl integration +- Add better error management for RDF files +- Added 'single tenant' mode: Send queries to all graphs to speed up +- Added ontologies management +- Added prefixes management +- Added 'external graph' management for federated request: federated requests will only target this remote graph +- Added support for multithread in web server, with the *WORKERS* env variable when calling make + +### Changed + +- Changed "Query builder" to "Form editor" in form editing interface +- Changed abstraction building method for relations. (Please refer to #248 and #268). Correct 'phantom' relations +- Changed abstraction building method for attributes. (Please refer to #321 and #324). Correct 'attributes' relations +- Changed abstraction building method for 'strand': only add the required strand type, and not all three types (#277) +- Updated documentation +- Changed the sparql endpoint: now use the authenticated SPARQL endpoint instead of public endpoint. Write permissions are not required anymore +- Reverted base docker image to alpine-13 to solve a docker issue + +### Removed + +- Removed "Remote endpoint" field for non-ttl file +- Removed "Custom_uri" field for ttl file + +### Security + +- Bump axios from 0.21.1 to 0.21.2 +- Bump tar from 6.1.0 to 6.1.11 +- Bump @npmcli/git from 2.0.6 to 2.1.0 +- Bump path-parse from 1.0.6 to 1.0.7 +- Bump prismjs from 1.23.0 to 1.27.0 +- Bump simple-get from 2.8.1 to 2.8.2 +- Bump ssri from 6.0.1 to 6.0.2 +- Bump follow-redirects from 1.14.4 to 1.14.8 +- Bump mkdocs from 1.0.4 to 1.2.3 in /docs +- Bump python-ldap from 3.3.1 to 3.4.0 +- Bump minimist from 1.2.5 to 1.2.6 ## [4.3.1] - 2021-06-16 diff --git a/Makefile b/Makefile index 7b1a35bf..12f74d0c 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ FLASKOPTS= PYTESTOPTS= TESTFILE?=tests NTASKS?=1 +WORKERS?=1 HOST?=0.0.0.0 PORT?=5000 @@ -52,20 +53,20 @@ help: @echo ' make clean Uninstall everything' @echo ' make install [MODE=dev] Install Python and Js dependencies (+ dev dependencies if MODE=dev)' @echo ' make build [MODE=dev] Build javascript (and watch for update if MODE=DEV)' - @echo ' make serve [MODE=dev] [HOST=0.0.0.0] [PORT=5000] [NTASKS=1] Serve AskOmics at $(HOST):$(PORT)' + @echo ' make serve [MODE=dev] [HOST=0.0.0.0] [PORT=5000] [NTASKS=1] [WORKERS=1] Serve AskOmics at $(HOST):$(PORT)' @echo ' make test Lint and test javascript and python code' @echo ' make serve-doc [DOCPORT=8000] Serve documentation at localhost:$(DOCPORT)' @echo ' make update-base-url Update all graphs from an old base_url to a new base_url' @echo ' make clear-cache Clear abstraction cache' @echo '' @echo 'Examples:' - @echo ' make clean install build serve NTASKS=10 Clean install and serve AskOmics in production mode, 10 celery tasks in parallel' - @echo ' make clean install serve MODE=dev NTASKS=10 Clean install and serve AskOmics in development mode, 10 celery tasks in parallel' + @echo ' make clean install build serve NTASKS=10 WORKERS=2 Clean install and serve AskOmics in production mode, 10 celery tasks in parallel, 2 workers on the web server' + @echo ' make clean install serve MODE=dev NTASKS=10 WORKERS=2 Clean install and serve AskOmics in development mode, 10 celery tasks in parallel, 2 workers on the web server' @echo '' @echo ' make clean install Clean install AskOmics' @echo ' make clean install MODE=dev Clean install AskOmics in development mode' - @echo ' make serve NTASKS=10 Serve AskOmics, 10 celery tasks in parallel' - @echo ' make serve MODE=dev NTASKS=10 Serve AskOmics in development mode, 10 celery tasks in parallel' + @echo ' make serve NTASKS=10 WORKERS=2 Serve AskOmics, 10 celery tasks in parallel, 2 workers on the web server' + @echo ' make serve MODE=dev NTASKS=10 WORKERS=2 Serve AskOmics in development mode, 10 celery tasks in parallel, 2 workers on the web server' @echo '' @echo ' make pytest MODE=dev TESTFILE=tests/test_api.py Test tests/test_api file only' @@ -81,7 +82,7 @@ test-js: eslint eslint: check-node-modules @echo -n 'Linting javascript... ' - $(NODEDIR)/.bin/eslint --config $(BASEDIR)/.eslintrc.yml "$(BASEDIR)/askomics/react/src/**" + $(NODEDIR)/.bin/eslint --config $(BASEDIR)/.eslintrc.yml "$(BASEDIR)/askomics/react/src/**" || { echo "ERROR"; exit 1; } @echo "Done" test-python: pylint pytest @@ -94,7 +95,7 @@ pytest: check-venv pylint: check-venv @echo -n 'Linting python... ' . $(ACTIVATE) - flake8 $(BASEDIR)/askomics $(BASEDIR)/tests --ignore=E501,W504 + flake8 $(BASEDIR)/askomics $(BASEDIR)/tests --ignore=E501,W504 || { echo "ERROR"; exit 1; } @echo "Done" serve: check-venv build-config create-user @@ -106,7 +107,7 @@ serve-askomics: check-venv build-config create-user ifeq ($(MODE), dev) FLASK_ENV=development FLASK_APP=app flask run --host=$(HOST) --port $(PORT) else - FLASK_ENV=production FLASK_APP=app gunicorn -b $(HOST):$(PORT) app + FLASK_ENV=production FLASK_APP=app gunicorn -w $(WORKERS) -b $(HOST):$(PORT) app endif serve-celery: check-venv build-config create-user @@ -126,32 +127,32 @@ check-node-modules: build-config: @echo -n 'Building config file... ' - bash cli/set_config.sh + bash cli/set_config.sh || { echo "ERROR"; exit 1; } @echo 'Done' create-user: @echo -n 'Creating first user... ' . $(ACTIVATE) - bash cli/set_user.sh + bash cli/set_user.sh || { echo "ERROR"; exit 1; } @echo 'Done' update-base-url: check-venv @echo 'Updating base url...' . $(ACTIVATE) - bash cli/update_base_url.sh + bash cli/update_base_url.sh || { echo "ERROR"; exit 1; } @echo 'Done' clear-cache: check-venv @echo 'Clearing abstraction cache...' . $(ACTIVATE) - bash cli/clear_cache.sh + bash cli/clear_cache.sh || { echo "ERROR"; exit 1; } @echo 'Done' build: build-js build-js: check-node-modules @echo 'Building askomics.js... ' - $(NPM) run --silent $(NPMOPTS) + $(NPM) run --silent $(NPMOPTS) || { echo "ERROR"; exit 1; } @echo ' Done' install: install-python install-js @@ -161,22 +162,22 @@ fast-install: install-python: check-python @echo -n 'Building python virtual environment... ' - $(PYTHON) -m venv $(VENVDIR) + $(PYTHON) -m venv $(VENVDIR) || { echo "ERROR"; exit 1; } @echo 'Done' @echo -n 'Sourcing Python virtual environment... ' - . $(ACTIVATE) + . $(ACTIVATE) || { echo "ERROR"; exit 1; } @echo 'Done' @echo -n 'Upgrading pip... ' - $(PIP) install --upgrade pip > /dev/null + $(PIP) install --upgrade pip > /dev/null || { echo "ERROR"; exit 1; } @echo 'Done' @echo 'Installing Python dependencies inside virtual environment... ' - $(PIP) install -e . > /dev/null - PIPENV_VERBOSITY=-1 $(PIPENV) install $(PIPENVOPTS) + $(PIP) install -e . > /dev/null || { echo "ERROR"; exit 1; } + PIPENV_VERBOSITY=-1 $(PIPENV) install $(PIPENVOPTS) || { echo "ERROR"; exit 1; } @echo ' Done' install-js: check-npm @echo 'Installing javascript dependencies inside node_modules... ' - $(NPM) install --silent + $(NPM) install || { echo "ERROR"; exit 1; } @echo ' Done' clean: clean-js clean-python diff --git a/Pipfile b/Pipfile index 0dde7cdf..6509b8eb 100644 --- a/Pipfile +++ b/Pipfile @@ -5,7 +5,7 @@ name = "pypi" [packages] werkzeug = "==0.16.1" -flask = "==1.1.4" +flask = "<2" flask-reverse-proxy-fix = "*" validate-email = "*" gunicorn = "*" @@ -13,7 +13,7 @@ python-magic = "*" rdflib = "*" sparqlwrapper = "*" requests = "*" -celery = "*" +celery = "==5.0.5" redis = "*" watchdog = "*" gitpython = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 6c8940c3..ef4d555b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "f208e36a35ade8b9d94b025ec7085c79f6b57dbd69ae9dd2b08c8b06418242fe" + "sha256": "5d768dd0f5c397f0380f7a594b66aed5e23d923674edfa3c62b4e47f5ce3e81e" }, "pipfile-spec": 6, "requires": {}, @@ -19,6 +19,7 @@ "sha256:03e16e94f2b34c31f8bf1206d8ddd3ccaa4c315f7f6a1879b7b1210d229568c2", "sha256:493a2ac6788ce270a2f6a765b017299f60c1998f5a8617908ee9be082f7300fb" ], + "markers": "python_version >= '3.6'", "version": "==5.0.6" }, "argh": { @@ -31,10 +32,10 @@ }, "bcbio-gff": { "hashes": [ - "sha256:74c6920c91ca18ed9cb872e9471c0be442dad143d8176345917eb1fefc86bc37" + "sha256:34dfa970e14f4533dc63c0a5512b7b5221e4a06449e6aaa344162ed5fdd7a1de" ], "index": "pypi", - "version": "==0.6.6" + "version": "==0.6.9" }, "billiard": { "hashes": [ @@ -45,42 +46,42 @@ }, "bioblend": { "hashes": [ - "sha256:a362a251a9429f17713bda51b29ccd3f4616a7613eedeb23e828307afb93eb34", - "sha256:ed37c858c890c41aff41da071838b92bec77a74f1b8d9e0562d40936ce5c255a" + "sha256:057450d39054cf91fff31e9025f269eb08e1ef1b437d71dfc73957e7cb0d8195", + "sha256:814312e3583a4cbb4ffaa1fb103107d9a24c069604abf51c670251fdc8bf094a" ], "index": "pypi", - "version": "==0.15.0" + "version": "==0.16.0" }, "biopython": { "hashes": [ - "sha256:010142a8ec2549ff0649edd497658964ef1a18eefdb9fd942ec1e81b292ce2d9", - "sha256:0b9fbb0d3022dc22716da108b8a81b80d952cd97ac1f106de491dce850f92f62", - "sha256:0df5cddef2819c975e6508adf5d85aa046e449df5420d02b04871c7836b41273", - "sha256:194528eda6856a4c68f840ca0bcc9b544a5edee3548b97521084e7ac38c833ca", - "sha256:195f099c2c0c39518b6df921ab2b3cc43a601896018fc61909ac8385d5878866", - "sha256:1df0bce7fd5e2414d6e18c9229fa0056914d2b9041531c71cac48f38a622142d", - "sha256:1ee0a0b6c2376680fea6642d5080baa419fd73df104a62d58a8baf7a8bbe4564", - "sha256:2bd5a630be2a8e593094f7b1717fc962eda8931b68542b97fbf9bd8e2ac1e08d", - "sha256:4565c97fab16c5697d067b821b6a1da0ec3ef36a9c96cf103ac7b4a94eb9f9ba", - "sha256:48d424453a5512a1d1d41a4acabdfe5291da1f491a2d3606f2b0e4fbd63aeda6", - "sha256:5c0b369f91a76b8e5e36624d075585c3f0f088ea4a6e3d015c48f08e48ce0114", - "sha256:639461a1ac5765406ec8ab8ed619845351f2ff22fed734d86e09e4a7b7719a08", - "sha256:6ed345b1ef100d58d8376e31c280b13fc87bb8f73ccc447f8140344991b61459", - "sha256:75b55000793f6b76334b8e80dc7e6d8cd2b019af917aa431cea6646e8e696c7f", - "sha256:9b4374a47d924d4d4ffe2fea010ce75427bbfd92e45d50d5b1213a478baf680f", - "sha256:ada611f12ee3b0bef7308ef41ee7b94898613b369ab44e0268d74bd1d6a06920", - "sha256:b470c44d7a04e40a0cfc65853b1a5a6bf506a130c334cf4cffa05df07dbda366", - "sha256:c130c8e64ae2e4c7c73f0c24974ac8a832190cc3cf3c3c7b4aaffc974effc993", - "sha256:cc3b0b78022d14f11d508038a288a189d03c97c476d6636c7b6f98bd8bc8462b", - "sha256:cfb93842501ebc0e0ef6520daddcbeeefc9b61736972580917dafd5c8a5a8041", - "sha256:d15d09bfe0d3a8a416a596a3909d9718c811df852d969592b4fa9e0da9cf7375", - "sha256:e0af107cc62a905d13d35dd7b38f335a37752ede45e4617139e84409a6a88dc4", - "sha256:f1076653937947773768455556b1d24acad9575759e9089082f32636b09add54", - "sha256:f5021a398c898b9cf6815cc5171c146a601b935b55364c53e6516a2545ab740c", - "sha256:fe2bcf85d0f5f1888ed7d86c139e9d4e7d54e036c8ac54e929663d63548046a1" + "sha256:03ee5c72b3cc3f0675a8c22ce1c45fe99a32a60db18df059df479ae6cf619708", + "sha256:155c5b95857bca7ebd607210cb9d8ea459bb0b86b3ca37ea44ec47c26ede7e9a", + "sha256:2dbb4388c75b5dfca8ce729e791f465c9c878dbd7ba2ab9a1f9854609d2b5426", + "sha256:365569543ea58dd07ef205ec351c23b6c1a3200d5d321eb28ceaecd55eb5955e", + "sha256:4b3d4eec2e348c3d97a7fde80ee0f2b8ebeed849d2bd64a616833a9be03b93c8", + "sha256:4be31815226052d86d4c2f6a103c40504e34bba3e25cc1b1d687a3203c42fb6e", + "sha256:51eb467a60c38820ad1e6c3a7d4cb10535606f559646e824cc65c96091d91ff7", + "sha256:5ae69c5e09769390643aa0f8064517665df6fb99c37433821d6664584d0ecb8c", + "sha256:72a1477cf1701964c7224e506a54fd65d1cc5228da200b634a17992230aa1cbd", + "sha256:76988ed3d7383d566db1d7fc69c9cf136c6275813fb749fc6753c340f81f1a8f", + "sha256:83bfea8a19f9352c47b13965c4b73853e7aeef3c5aed8489895b0679e32c621b", + "sha256:884a2b99ac7820cb84f70089769a512e3238ee60438b8c934ed519613dc570ce", + "sha256:8f33dafd3c7254fff5e1684b965e45a7c08d9b8e1bf51562b0a521ff9a6f5ea0", + "sha256:947b793e804c59ea45ae46945a57612ad1789ca87af4af0d6a62dcecf3a6246a", + "sha256:9580978803b582e0612b71673cab289e6bf261a865009cfb9501d65bc726a76e", + "sha256:98deacc30b8654cfcdcf707d93fa4e3c8717bbda07c3f9f828cf84753d4a1e4d", + "sha256:aa23a83a220486af6193760d079b36543fe00afcfbd18280ca2fd0b2c1c8dd6d", + "sha256:ab93d5749b375be3682866b3a606aa2ebd3e6d868079793925bf4fbb0987cf1f", + "sha256:b3ab26f26a1956ef26303386510d84e917e31fcbbc94918c336da0163ef628df", + "sha256:bf634a56f449a4123e48e538d661948e5ac29fb452acd2962b8cb834b472a9d7", + "sha256:ceab668be9cbdcddef55ad459f87acd0316ae4a00d32251fea4cf665f5062fda", + "sha256:d9f6ce961e0c380e2a5435f64c96421dbcebeab6a1b41506bd81251feb733c08", + "sha256:e921571b51514a6d35944242d6fef6427c3998acf58940fe1f209ac8a92a6e87", + "sha256:edb07eac99d3b8abd7ba56ff4bedec9263f76dfc3c3f450e7d2e2bcdecf8559b", + "sha256:f0a7e1d94a318f74974345fd0987ec389b16988ec484e67218e900b116b932a8" ], "index": "pypi", - "version": "==1.78" + "version": "==1.79" }, "blinker": { "hashes": [ @@ -95,6 +96,14 @@ ], "version": "==2.49.0" }, + "cached-property": { + "hashes": [ + "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130", + "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0" + ], + "markers": "python_version < '3.8'", + "version": "==1.5.2" + }, "celery": { "hashes": [ "sha256:5e8d364e058554e83bbb116e8377d90c79be254785f357cb2cec026e79febe13", @@ -105,30 +114,34 @@ }, "certifi": { "hashes": [ - "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", - "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" + "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", + "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" ], - "version": "==2020.12.5" + "version": "==2021.10.8" }, - "chardet": { + "charset-normalizer": { "hashes": [ - "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", - "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" + "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721", + "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c" ], - "version": "==4.0.0" + "markers": "python_version >= '3'", + "version": "==2.0.9" }, "click": { "hashes": [ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, "click-didyoumean": { "hashes": [ - "sha256:112229485c9704ff51362fe34b2d4f0b12fc71cc20f6d2b3afabed4b8bfa6aeb" + "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667", + "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035" ], - "version": "==0.0.3" + "markers": "python_full_version >= '3.6.2' and python_full_version < '4.0.0'", + "version": "==0.3.0" }, "click-plugins": { "hashes": [ @@ -139,26 +152,34 @@ }, "click-repl": { "hashes": [ - "sha256:9c4c3d022789cae912aad8a3f5e1d7c2cdd016ee1225b5212ad3e8691563cda5", - "sha256:b9f29d52abc4d6059f8e276132a111ab8d94980afe6a5432b9d996544afa95d5" + "sha256:94b3fbbc9406a236f176e0506524b2937e4b23b6f4c0c0b2a0a83f8a64e9194b", + "sha256:cd12f68d745bf6151210790540b4cb064c7b13e571bc64b6957d98d120dacfd8" ], - "version": "==0.1.6" + "version": "==0.2.0" }, "configparser": { "hashes": [ - "sha256:85d5de102cfe6d14a5172676f09d19c465ce63d6019cf0a4ef13385fc535e828", - "sha256:af59f2cdd7efbdd5d111c1976ecd0b82db9066653362f0962d7bf1d3ab89a1fa" + "sha256:1b35798fdf1713f1c3139016cfcbc461f09edbf099d1fb658d4b7479fcaa3daa", + "sha256:e8b39238fb6f0153a069aa253d349467c3c4737934f253ef6abac5fe0eca1e5d" ], "index": "pypi", - "version": "==5.0.2" + "version": "==5.2.0" }, "deepdiff": { "hashes": [ - "sha256:dd79b81c2d84bfa33aa9d94d456b037b68daff6bb87b80dfaa1eca04da68b349", - "sha256:e054fed9dfe0d83d622921cbb3a3d0b3a6dd76acd2b6955433a0a2d35147774a" + "sha256:e3f1c3a375c7ea5ca69dba6f7920f9368658318ff1d8a496293c79481f48e649", + "sha256:ef3410ca31e059a9d10edfdff552245829835b3ecd03212dc5b533d45a6c3f57" ], "index": "pypi", - "version": "==5.5.0" + "version": "==5.6.0" + }, + "deprecated": { + "hashes": [ + "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d", + "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.2.13" }, "flask": { "hashes": [ @@ -178,18 +199,19 @@ }, "gitdb": { "hashes": [ - "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0", - "sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005" + "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd", + "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa" ], - "version": "==4.0.7" + "markers": "python_version >= '3.6'", + "version": "==4.0.9" }, "gitpython": { "hashes": [ - "sha256:29fe82050709760081f588dd50ce83504feddbebdc4da6956d02351552b1c135", - "sha256:ee24bdc93dce357630764db659edaf6b8d664d4ff5447ccfeedd2dc5c253f41e" + "sha256:dc0a7f2f697657acc8d7f89033e8b1ea94dd90356b2983bca89dc8d2ab3cc647", + "sha256:df83fdf5e684fef7c6ee2c02fc68a5ceb7e7e759d08b694088d0cacb4eba59e5" ], "index": "pypi", - "version": "==3.1.17" + "version": "==3.1.24" }, "gunicorn": { "hashes": [ @@ -201,18 +223,19 @@ }, "idna": { "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" + "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", + "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "version": "==2.10" + "markers": "python_version >= '3'", + "version": "==3.3" }, "importlib-metadata": { "hashes": [ - "sha256:8c501196e49fb9df5df43833bdb1e4328f64847763ec8a50703148b73784d581", - "sha256:d7eb1dea6d6a6086f8be21784cc9e3bcfa55872b52309bc5fad53a8ea444465d" + "sha256:53ccfd5c134223e497627b9815d5030edf77d2ed573922f7a0b8f8bb81a1c100", + "sha256:75bdec14c397f528724c1bfd9709d660b33a4d2e77387a3358f20b848bb5e5fb" ], "markers": "python_version < '3.8'", - "version": "==4.0.1" + "version": "==4.8.2" }, "isodate": { "hashes": [ @@ -226,6 +249,7 @@ "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.0" }, "jinja2": { @@ -233,117 +257,176 @@ "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==2.11.3" }, "kombu": { "hashes": [ - "sha256:6dc509178ac4269b0e66ab4881f70a2035c33d3a622e20585f965986a5182006", - "sha256:f4965fba0a4718d47d470beeb5d6446e3357a62402b16c510b6a2f251e05ac3c" + "sha256:0f5d0763fb916808f617b886697b2be28e6bc35026f08e679697fc814b48a608", + "sha256:d36f0cde6a18d9eb7b6b3aa62a59bfdff7f5724689850e447eca5be8efc9d501" ], - "version": "==5.0.2" + "markers": "python_version >= '3.7'", + "version": "==5.2.2" }, "markupsafe": { "hashes": [ - "sha256:007dc055dbce5b1104876acee177dbfd18757e19d562cd440182e1f492e96b95", - "sha256:031bf79a27d1c42f69c276d6221172417b47cb4b31cdc73d362a9bf5a1889b9f", - "sha256:161d575fa49395860b75da5135162481768b11208490d5a2143ae6785123e77d", - "sha256:24bbc3507fb6dfff663af7900a631f2aca90d5a445f272db5fc84999fa5718bc", - "sha256:2efaeb1baff547063bad2b2893a8f5e9c459c4624e1a96644bbba08910ae34e0", - "sha256:32200f562daaab472921a11cbb63780f1654552ae49518196fc361ed8e12e901", - "sha256:3261fae28155e5c8634dd7710635fe540a05b58f160cef7713c7700cb9980e66", - "sha256:3b54a9c68995ef4164567e2cd1a5e16db5dac30b2a50c39c82db8d4afaf14f63", - "sha256:3c352ff634e289061711608f5e474ec38dbaa21e3e168820d53d5f4015e5b91b", - "sha256:3fb47f97f1d338b943126e90b79cad50d4fcfa0b80637b5a9f468941dbbd9ce5", - "sha256:441ce2a8c17683d97e06447fcbccbdb057cbf587c78eb75ae43ea7858042fe2c", - "sha256:45535241baa0fc0ba2a43961a1ac7562ca3257f46c4c3e9c0de38b722be41bd1", - "sha256:4aca81a687975b35e3e80bcf9aa93fe10cd57fac37bf18b2314c186095f57e05", - "sha256:4cc563836f13c57f1473bc02d1e01fc37bab70ad4ee6be297d58c1d66bc819bf", - "sha256:4fae0677f712ee090721d8b17f412f1cbceefbf0dc180fe91bab3232f38b4527", - "sha256:58bc9fce3e1557d463ef5cee05391a05745fd95ed660f23c1742c711712c0abb", - "sha256:664832fb88b8162268928df233f4b12a144a0c78b01d38b81bdcf0fc96668ecb", - "sha256:70820a1c96311e02449591cbdf5cd1c6a34d5194d5b55094ab725364375c9eb2", - "sha256:79b2ae94fa991be023832e6bcc00f41dbc8e5fe9d997a02db965831402551730", - "sha256:83cf0228b2f694dcdba1374d5312f2277269d798e65f40344964f642935feac1", - "sha256:87de598edfa2230ff274c4de7fcf24c73ffd96208c8e1912d5d0fee459767d75", - "sha256:8f806bfd0f218477d7c46a11d3e52dc7f5fdfaa981b18202b7dc84bbc287463b", - "sha256:90053234a6479738fd40d155268af631c7fca33365f964f2208867da1349294b", - "sha256:a00dce2d96587651ef4fa192c17e039e8cfab63087c67e7d263a5533c7dad715", - "sha256:a08cd07d3c3c17cd33d9e66ea9dee8f8fc1c48e2d11bd88fd2dc515a602c709b", - "sha256:a19d39b02a24d3082856a5b06490b714a9d4179321225bbf22809ff1e1887cc8", - "sha256:d00a669e4a5bec3ee6dbeeeedd82a405ced19f8aeefb109a012ea88a45afff96", - "sha256:dab0c685f21f4a6c95bfc2afd1e7eae0033b403dd3d8c1b6d13a652ada75b348", - "sha256:df561f65049ed3556e5b52541669310e88713fdae2934845ec3606f283337958", - "sha256:e4570d16f88c7f3032ed909dc9e905a17da14a1c4cfd92608e3fda4cb1208bbd", - "sha256:e77e4b983e2441aff0c0d07ee711110c106b625f440292dfe02a2f60c8218bd6", - "sha256:e79212d09fc0e224d20b43ad44bb0a0a3416d1e04cf6b45fed265114a5d43d20", - "sha256:f58b5ba13a5689ca8317b98439fccfbcc673acaaf8241c1869ceea40f5d585bf", - "sha256:fef86115fdad7ae774720d7103aa776144cf9b66673b4afa9bcaa7af990ed07b" - ], - "version": "==2.0.0" + "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", + "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", + "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", + "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", + "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", + "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", + "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", + "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", + "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", + "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", + "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", + "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", + "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", + "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", + "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", + "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", + "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", + "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", + "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", + "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", + "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", + "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", + "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", + "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", + "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", + "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", + "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", + "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", + "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", + "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", + "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", + "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", + "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", + "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", + "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", + "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", + "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", + "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", + "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", + "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", + "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", + "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", + "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", + "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", + "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", + "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", + "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", + "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", + "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", + "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", + "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", + "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", + "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", + "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", + "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", + "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", + "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", + "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", + "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", + "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", + "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", + "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", + "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", + "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", + "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", + "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", + "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", + "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", + "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.1" }, "numpy": { "hashes": [ - "sha256:012426a41bc9ab63bb158635aecccc7610e3eff5d31d1eb43bc099debc979d94", - "sha256:06fab248a088e439402141ea04f0fffb203723148f6ee791e9c75b3e9e82f080", - "sha256:0eef32ca3132a48e43f6a0f5a82cb508f22ce5a3d6f67a8329c81c8e226d3f6e", - "sha256:1ded4fce9cfaaf24e7a0ab51b7a87be9038ea1ace7f34b841fe3b6894c721d1c", - "sha256:2e55195bc1c6b705bfd8ad6f288b38b11b1af32f3c8289d6c50d47f950c12e76", - "sha256:2ea52bd92ab9f768cc64a4c3ef8f4b2580a17af0a5436f6126b08efbd1838371", - "sha256:36674959eed6957e61f11c912f71e78857a8d0604171dfd9ce9ad5cbf41c511c", - "sha256:384ec0463d1c2671170901994aeb6dce126de0a95ccc3976c43b0038a37329c2", - "sha256:39b70c19ec771805081578cc936bbe95336798b7edf4732ed102e7a43ec5c07a", - "sha256:400580cbd3cff6ffa6293df2278c75aef2d58d8d93d3c5614cd67981dae68ceb", - "sha256:43d4c81d5ffdff6bae58d66a3cd7f54a7acd9a0e7b18d97abb255defc09e3140", - "sha256:50a4a0ad0111cc1b71fa32dedd05fa239f7fb5a43a40663269bb5dc7877cfd28", - "sha256:603aa0706be710eea8884af807b1b3bc9fb2e49b9f4da439e76000f3b3c6ff0f", - "sha256:6149a185cece5ee78d1d196938b2a8f9d09f5a5ebfbba66969302a778d5ddd1d", - "sha256:759e4095edc3c1b3ac031f34d9459fa781777a93ccc633a472a5468587a190ff", - "sha256:7fb43004bce0ca31d8f13a6eb5e943fa73371381e53f7074ed21a4cb786c32f8", - "sha256:811daee36a58dc79cf3d8bdd4a490e4277d0e4b7d103a001a4e73ddb48e7e6aa", - "sha256:8b5e972b43c8fc27d56550b4120fe6257fdc15f9301914380b27f74856299fea", - "sha256:99abf4f353c3d1a0c7a5f27699482c987cf663b1eac20db59b8c7b061eabd7fc", - "sha256:a0d53e51a6cb6f0d9082decb7a4cb6dfb33055308c4c44f53103c073f649af73", - "sha256:a12ff4c8ddfee61f90a1633a4c4afd3f7bcb32b11c52026c92a12e1325922d0d", - "sha256:a4646724fba402aa7504cd48b4b50e783296b5e10a524c7a6da62e4a8ac9698d", - "sha256:a76f502430dd98d7546e1ea2250a7360c065a5fdea52b2dffe8ae7180909b6f4", - "sha256:a9d17f2be3b427fbb2bce61e596cf555d6f8a56c222bd2ca148baeeb5e5c783c", - "sha256:ab83f24d5c52d60dbc8cd0528759532736b56db58adaa7b5f1f76ad551416a1e", - "sha256:aeb9ed923be74e659984e321f609b9ba54a48354bfd168d21a2b072ed1e833ea", - "sha256:c843b3f50d1ab7361ca4f0b3639bf691569493a56808a0b0c54a051d260b7dbd", - "sha256:cae865b1cae1ec2663d8ea56ef6ff185bad091a5e33ebbadd98de2cfa3fa668f", - "sha256:cc6bd4fd593cb261332568485e20a0712883cf631f6f5e8e86a52caa8b2b50ff", - "sha256:cf2402002d3d9f91c8b01e66fbb436a4ed01c6498fffed0e4c7566da1d40ee1e", - "sha256:d051ec1c64b85ecc69531e1137bb9751c6830772ee5c1c426dbcfe98ef5788d7", - "sha256:d6631f2e867676b13026e2846180e2c13c1e11289d67da08d71cacb2cd93d4aa", - "sha256:dbd18bcf4889b720ba13a27ec2f2aac1981bd41203b3a3b27ba7a33f88ae4827", - "sha256:df609c82f18c5b9f6cb97271f03315ff0dbe481a2a02e56aeb1b1a985ce38e60" - ], - "version": "==1.19.5" + "sha256:0b78ecfa070460104934e2caf51694ccd00f37d5e5dbe76f021b1b0b0d221823", + "sha256:1247ef28387b7bb7f21caf2dbe4767f4f4175df44d30604d42ad9bd701ebb31f", + "sha256:1403b4e2181fc72664737d848b60e65150f272fe5a1c1cbc16145ed43884065a", + "sha256:170b2a0805c6891ca78c1d96ee72e4c3ed1ae0a992c75444b6ab20ff038ba2cd", + "sha256:2e4ed57f45f0aa38beca2a03b6532e70e548faf2debbeb3291cfc9b315d9be8f", + "sha256:32fe5b12061f6446adcbb32cf4060a14741f9c21e15aaee59a207b6ce6423469", + "sha256:34f3456f530ae8b44231c63082c8899fe9c983fd9b108c997c4b1c8c2d435333", + "sha256:4c9c23158b87ed0e70d9a50c67e5c0b3f75bcf2581a8e34668d4e9d7474d76c6", + "sha256:5d95668e727c75b3f5088ec7700e260f90ec83f488e4c0aaccb941148b2cd377", + "sha256:615d4e328af7204c13ae3d4df7615a13ff60a49cb0d9106fde07f541207883ca", + "sha256:69077388c5a4b997442b843dbdc3a85b420fb693ec8e33020bb24d647c164fa5", + "sha256:74b85a17528ca60cf98381a5e779fc0264b4a88b46025e6bcbe9621f46bb3e63", + "sha256:81225e58ef5fce7f1d80399575576fc5febec79a8a2742e8ef86d7b03beef49f", + "sha256:8890b3360f345e8360133bc078d2dacc2843b6ee6059b568781b15b97acbe39f", + "sha256:92aafa03da8658609f59f18722b88f0a73a249101169e28415b4fa148caf7e41", + "sha256:9864424631775b0c052f3bd98bc2712d131b3e2cd95d1c0c68b91709170890b0", + "sha256:9e6f5f50d1eff2f2f752b3089a118aee1ea0da63d56c44f3865681009b0af162", + "sha256:a3deb31bc84f2b42584b8c4001c85d1934dbfb4030827110bc36bfd11509b7bf", + "sha256:ad010846cdffe7ec27e3f933397f8a8d6c801a48634f419e3d075db27acf5880", + "sha256:b1e2312f5b8843a3e4e8224b2b48fe16119617b8fc0a54df8f50098721b5bed2", + "sha256:bc988afcea53e6156546e5b2885b7efab089570783d9d82caf1cfd323b0bb3dd", + "sha256:c449eb870616a7b62e097982c622d2577b3dbc800aaf8689254ec6e0197cbf1e", + "sha256:c74c699b122918a6c4611285cc2cad4a3aafdb135c22a16ec483340ef97d573c", + "sha256:c885bfc07f77e8fee3dc879152ba993732601f1f11de248d4f357f0ffea6a6d4", + "sha256:e3c3e990274444031482a31280bf48674441e0a5b55ddb168f3a6db3e0c38ec8", + "sha256:e4799be6a2d7d3c33699a6f77201836ac975b2e1b98c2a07f66a38f499cb50ce", + "sha256:e6c76a87633aa3fa16614b61ccedfae45b91df2767cf097aa9c933932a7ed1e0", + "sha256:e89717274b41ebd568cd7943fc9418eeb49b1785b66031bc8a7f6300463c5898", + "sha256:f5162ec777ba7138906c9c274353ece5603646c6965570d82905546579573f73", + "sha256:fde96af889262e85aa033f8ee1d3241e32bf36228318a61f1ace579df4e8170d" + ], + "markers": "python_version < '3.11' and python_version >= '3.7'", + "version": "==1.21.4" }, "ordered-set": { "hashes": [ "sha256:ba93b2df055bca202116ec44b9bead3df33ea63a7d5827ff8e16738b97f33a95" ], + "markers": "python_version >= '3.5'", "version": "==4.0.2" }, "prompt-toolkit": { "hashes": [ - "sha256:bf00f22079f5fadc949f42ae8ff7f05702826a97059ffcc6281036ad40ac6f04", - "sha256:e1b4f11b9336a28fa11810bc623c357420f69dfdb6d2dac41ca2c21a55c033bc" + "sha256:5f29d62cb7a0ecacfa3d8ceea05a63cd22500543472d64298fc06ddda906b25d", + "sha256:7053aba00895473cb357819358ef33f11aa97e4ac83d38efb123e5649ceeecaf" ], - "version": "==3.0.18" + "markers": "python_full_version >= '3.6.2'", + "version": "==3.0.23" }, "pyasn1": { "hashes": [ + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba" + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" ], "version": "==0.4.8" }, "pyasn1-modules": { "hashes": [ + "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8", + "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199", + "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811", + "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed", + "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4", "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", - "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74" + "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", + "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb", + "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45", + "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd", + "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0", + "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d", + "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405" ], "version": "==0.2.8" }, @@ -356,111 +439,126 @@ }, "pyparsing": { "hashes": [ - "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" + "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4", + "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81" ], - "version": "==2.4.7" + "markers": "python_version >= '3.6'", + "version": "==3.0.6" }, "pysam": { "hashes": [ - "sha256:107eca9050d8140910b5ea5c5a9e66313e1155eb44cc180e10f48f9cb71e8095", - "sha256:3eb70111a5ed86cc7a048c9b2205087b1184093e6135f02ad7f144b206951452", - "sha256:9da29490c666a963e5a7f6f5114e86c9b36a8a6adc2227f5772bdc38c09d2d37", - "sha256:9e3597a49e4bc72c31199d6231018ad3034e08a8243b9f8086953afb2ab5a3af", - "sha256:a5a0fc1f0d724d0b7789341add26ba181ac009430021f0998f6083fb62432193", - "sha256:d428a9768691d5ea3c28cc52a949c920ae691aa4c110a8b7328dc4d165ef1ad6", - "sha256:f65659deadc4904984de24cb6f3878b6052cf504a2a85a50b80f2ff7939f96db" + "sha256:0cfa16f76ed3c3119c7b3c8dfdcba9e010fbcdcf87eaa165351bb369da5a6bf1", + "sha256:1d6d49a0b3c626fae410a93d4c80583a8b5ddaacc9b46a080b250dbcebd30a59", + "sha256:2717509556fecddf7c73966fa62066c6a59a7d39b755d8972afa8d143a1d5aa5", + "sha256:493988420db16e6ee03393518e4d272df05f0a35780248c08c61da7411e520e7", + "sha256:7a8a25fceaaa96e5b4c8b0a7fd6bb0b20b6c262dc4cc867c6d1467ac990f1d77", + "sha256:7ea2e019294e4bf25e4892b5de69c43f54fb6ac42b681265268aa322e1f36f5b", + "sha256:7f6a4ec58ad7995b791a71bf35f673ea794e734c587ea7329fca5cce9c53a7af", + "sha256:9422c2d0b581c3d24f247c15bb8981569e636003c4d6cad39ccd1bf205a79f2c", + "sha256:a88f875114bd3d8efb7fade80e0640094383ec5043861aa575175fa9a56edf90", + "sha256:c90341434e7a99439174aa64ca5406f63528be4217d4401fb30ec4ea4629c559", + "sha256:ca0c9289dfdc5e1a81bccdb8305192cd14cf9730bd21320ceca949fde071a572", + "sha256:cfb162358c5284b31b2b88b10947e0f1013da2d85ba0fd0b5723dd142c15329e", + "sha256:cfffad99cf3968cf85aadb70a8a02303f9172ea21abe02d587c44f808c504f52", + "sha256:e13e496da3a432db24f424439834b0ab5f40700a3db6e610d06f8bd639d9fd2d", + "sha256:ef5d8ad01cac8974cd09832c226cbb63a3f7c5bd63727d8e59447021ee16a186", + "sha256:f5a23a5dcf32f01c66d44e89113fa8f7522997ea43fbc0f98e5250a907911a5f" ], "index": "pypi", - "version": "==0.16.0.1" + "version": "==0.18.0" }, "python-dateutil": { "hashes": [ - "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", - "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" + "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", + "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], "index": "pypi", - "version": "==2.8.1" + "version": "==2.8.2" }, "python-ldap": { "hashes": [ - "sha256:4711cacf013e298754abd70058ccc995758177fb425f1c2d30e71adfc1d00aa5" + "sha256:60464c8fc25e71e0fd40449a24eae482dcd0fb7fcf823e7de627a6525b3e0d12" ], "index": "pypi", - "version": "==3.3.1" + "version": "==3.4.0" }, "python-magic": { "hashes": [ - "sha256:8551e804c09a3398790bd9e392acb26554ae2609f29c72abb0b9dee9a5571eae", - "sha256:ca884349f2c92ce830e3f498c5b7c7051fe2942c3ee4332f65213b8ebff15a62" + "sha256:4fec8ee805fea30c07afccd1592c0f17977089895bdfaae5fec870a84e997626", + "sha256:de800df9fb50f8ec5974761054a708af6e4246b03b4bdaee993f948947b0ebcf" ], "index": "pypi", - "version": "==0.4.22" + "version": "==0.4.24" }, "pytz": { "hashes": [ - "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da", - "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798" + "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c", + "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326" ], - "version": "==2021.1" + "version": "==2021.3" }, "pyyaml": { "hashes": [ - "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", - "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", - "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", - "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", - "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", - "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", - "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", - "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", - "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", - "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", - "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", - "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", - "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", - "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", - "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", - "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", - "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", - "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", - "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", - "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", - "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", - "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", - "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", - "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", - "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", - "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", - "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", - "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", - "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" - ], - "version": "==5.4.1" + "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", + "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", + "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", + "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", + "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", + "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", + "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", + "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", + "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", + "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", + "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", + "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", + "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", + "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", + "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", + "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", + "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", + "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", + "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", + "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", + "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", + "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", + "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", + "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", + "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", + "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", + "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", + "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", + "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", + "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", + "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", + "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", + "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" + ], + "markers": "python_version >= '3.6'", + "version": "==6.0" }, "rdflib": { "hashes": [ - "sha256:78149dd49d385efec3b3adfbd61c87afaf1281c30d3fcaf1b323b34f603fb155", - "sha256:88208ea971a87886d60ae2b1a4b2cdc263527af0454c422118d43fe64b357877" + "sha256:6136ae056001474ee2aff5fc5b956e62a11c3a9c66bb0f3d9c0aaa5fbb56854e", + "sha256:b7642daac8cdad1ba157fecb236f5d1b2aa1de64e714dcee80d65e2b794d88a6" ], "index": "pypi", - "version": "==5.0.0" + "version": "==6.0.2" }, "redis": { "hashes": [ - "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2", - "sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24" + "sha256:c8481cf414474e3497ec7971a1ba9b998c8efad0f0d289a009a5bbef040894f9", + "sha256:ccf692811f2c1fc7a92b466aa2599e4a6d2d73d5f736a2c70be600657c0da34a" ], "index": "pypi", - "version": "==3.5.3" + "version": "==4.0.2" }, "requests": { "hashes": [ - "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", - "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" + "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24", + "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7" ], "index": "pypi", - "version": "==2.25.1" + "version": "==2.26.0" }, "requests-toolbelt": { "hashes": [ @@ -474,29 +572,49 @@ "flask" ], "hashes": [ - "sha256:c1227d38dca315ba35182373f129c3e2722e8ed999e52584e6aca7d287870739", - "sha256:c7d380a21281e15be3d9f67a3c4fbb4f800c481d88ff8d8931f39486dd7b4ada" + "sha256:0db297ab32e095705c20f742c3a5dac62fe15c4318681884053d0898e5abb2f6", + "sha256:789a11a87ca02491896e121efdd64e8fd93327b69e8f2f7d42f03e2569648e88" ], "index": "pypi", - "version": "==1.1.0" + "version": "==1.5.0" + }, + "setuptools": { + "hashes": [ + "sha256:6d10741ff20b89cd8c6a536ee9dc90d3002dec0226c78fb98605bfb9ef8a7adf", + "sha256:d144f85102f999444d06f9c0e8c737fd0194f10f2f7e5fdb77573f6e2fa4fad0" + ], + "markers": "python_version >= '3.6'", + "version": "==59.5.0" + }, + "setuptools": { + "hashes": [ + "sha256:b4c634615a0cf5b02cf83c7bedffc8da0ca439f00e79452699454da6fbd4153d", + "sha256:feb5ff19b354cde9efd2344ef6d5e79880ce4be643037641b49508bbb850d060" + ], + "markers": "python_version >= '3.6'", + "version": "==59.4.0" }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "smmap": { "hashes": [ - "sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182", - "sha256:a9a7479e4c572e2e775c404dcd3080c8dc49f39918c2cf74913d30c4c478e3c2" + "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94", + "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936" ], - "version": "==4.0.0" + "markers": "python_version >= '3.6'", + "version": "==5.0.0" }, "sparqlwrapper": { "hashes": [ + "sha256:17ec44b08b8ae2888c801066249f74fe328eec25d90203ce7eadaf82e64484c7", "sha256:357ee8a27bc910ea13d77836dbddd0b914991495b8cc1bf70676578155e962a8", + "sha256:8cf6c21126ed76edc85c5c232fd6f77b9f61f8ad1db90a7147cdde2104aff145", "sha256:c7f9c9d8ebb13428771bc3b6dee54197422507dcc3dea34e30d5dcfc53478dec", "sha256:d6a66b5b8cda141660e07aeb00472db077a98d22cb588c973209c7336850fb3c" ], @@ -505,32 +623,32 @@ }, "tld": { "hashes": [ - "sha256:1a69b2cd4053da5377a0b27e048e97871120abf9cd7a62ff270915d0c11369d6", - "sha256:1b63094d893657eadfd61e49580b4225ce958ca3b8013dbb9485372cde5a3434", - "sha256:3266e6783825a795244a0ed225126735e8121859113b0a7fc830cc49f7bbdaff", - "sha256:478d9b23157c7e3e2d07b0534da3b1e61a619291b6e3f52f5a3510e43acec7e9", - "sha256:5bd36b24aeb14e766ef1e5c01b96fe89043db44a579848f716ec03c40af50a6b", - "sha256:cf1b7af4c1d9c689ca81ea7cf3cae77d1bfd8aaa4c648b58f76a0b3d32e3f6e0", - "sha256:d5938730cdb9ce4b0feac4dc887d971f964dba873a74ad818f0f25c1571c6045" + "sha256:266106ad9035f54cd5cce5f823911a51f697e7c58cb45bfbd6c53b4c2976ece2", + "sha256:69fed19d26bb3f715366fb4af66fdeace896c55c052b00e8aaba3a7b63f3e7f0", + "sha256:826bbe61dccc8d63144b51caef83e1373fbaac6f9ada46fca7846021f5d36fef", + "sha256:843844e4256c943983d86366b5af3ac9cd1c9a0b6465f04d9f70e3b4c1a7989f", + "sha256:a92ac6b84917e7d9e934434b8d37e9be534598f138fbb86b3c0d5426f2621890", + "sha256:b6650f2d5392a49760064bc55d73ce3397a378ef24ded96efb516c6b8ec68c26", + "sha256:ef5b162d6fa295822dacd4fe4df1b62d8df2550795a97399a8905821b58d3702" ], "index": "pypi", - "version": "==0.12.5" + "version": "==0.12.6" }, "typing-extensions": { "hashes": [ - "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", - "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", - "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" + "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e", + "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b" ], - "markers": "python_version < '3.8'", - "version": "==3.10.0.0" + "markers": "python_version < '3.10'", + "version": "==4.0.1" }, "urllib3": { "hashes": [ - "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df", - "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937" + "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece", + "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844" ], - "version": "==1.26.4" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_full_version < '4.0.0'", + "version": "==1.26.7" }, "validate-email": { "hashes": [ @@ -544,30 +662,37 @@ "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30", "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e" ], + "markers": "python_version >= '3.6'", "version": "==5.0.0" }, "watchdog": { "hashes": [ - "sha256:027c532e2fd3367d55fe235510fc304381a6cc88d0dcd619403e57ffbd83c1d2", - "sha256:12645d41d7307601b318c48861e776ce7a9fdcad9f74961013ec39037050582c", - "sha256:16078cd241a95124acd4d8d3efba2140faec9300674b12413cc08be11b825d56", - "sha256:20d4cabfa2ad7239995d81a0163bc0264a3e104a64f33c6f0a21ad75a0d915d9", - "sha256:22c13c19599b0dec7192f8f7d26404d5223cb36c9a450e96430483e685dccd7e", - "sha256:2894440b4ea95a6ef4c5d152deedbe270cae46092682710b7028a04d6a6980f6", - "sha256:4d83c89ba24bd67b7a7d5752a4ef953ec40db69d4d30582bd1f27d3ecb6b61b0", - "sha256:5b391bac7edbdf96fb82a381d04829bbc0d1bb259c206b2b283ef8989340240f", - "sha256:604ca364a79c27a694ab10947cd41de81bf229cff507a3156bf2c56c064971a1", - "sha256:67c645b1e500cc74d550e9aad4829309c5084dc55e8dc4e1c25d5da23e5be239", - "sha256:9f1b124fe2d4a1f37b7068f6289c2b1eba44859eb790bf6bd709adff224a5469", - "sha256:a1b3f76e2a0713b406348dd5b9df2aa02bdd741a6ddf54f4c6410b395e077502", - "sha256:a9005f968220b715101d5fcdde5f5deda54f0d1873f618724f547797171f5e97", - "sha256:aa59afc87a892ed92d7d88d09f4b736f1336fc35540b403da7ee00c3be74bd07", - "sha256:c1325b47463fce231d88eb74f330ab0cb4a1bab5defe12c0c80a3a4f197345b4", - "sha256:dca75d12712997c713f76e6d68ff41580598c7df94cedf83f1089342e7709081", - "sha256:f3edbe1e15e229d2ba8ff5156908adba80d1ba21a9282d9f72247403280fc799" + "sha256:25fb5240b195d17de949588628fdf93032ebf163524ef08933db0ea1f99bd685", + "sha256:3386b367e950a11b0568062b70cc026c6f645428a698d33d39e013aaeda4cc04", + "sha256:3becdb380d8916c873ad512f1701f8a92ce79ec6978ffde92919fd18d41da7fb", + "sha256:4ae38bf8ba6f39d5b83f78661273216e7db5b00f08be7592062cb1fc8b8ba542", + "sha256:8047da932432aa32c515ec1447ea79ce578d0559362ca3605f8e9568f844e3c6", + "sha256:8f1c00aa35f504197561060ca4c21d3cc079ba29cf6dd2fe61024c70160c990b", + "sha256:922a69fa533cb0c793b483becaaa0845f655151e7256ec73630a1b2e9ebcb660", + "sha256:9693f35162dc6208d10b10ddf0458cc09ad70c30ba689d9206e02cd836ce28a3", + "sha256:a0f1c7edf116a12f7245be06120b1852275f9506a7d90227648b250755a03923", + "sha256:a36e75df6c767cbf46f61a91c70b3ba71811dfa0aca4a324d9407a06a8b7a2e7", + "sha256:aba5c812f8ee8a3ff3be51887ca2d55fb8e268439ed44110d3846e4229eb0e8b", + "sha256:ad6f1796e37db2223d2a3f302f586f74c72c630b48a9872c1e7ae8e92e0ab669", + "sha256:ae67501c95606072aafa865b6ed47343ac6484472a2f95490ba151f6347acfc2", + "sha256:b2fcf9402fde2672545b139694284dc3b665fd1be660d73eca6805197ef776a3", + "sha256:b52b88021b9541a60531142b0a451baca08d28b74a723d0c99b13c8c8d48d604", + "sha256:b7d336912853d7b77f9b2c24eeed6a5065d0a0cc0d3b6a5a45ad6d1d05fb8cd8", + "sha256:bd9ba4f332cf57b2c1f698be0728c020399ef3040577cde2939f2e045b39c1e5", + "sha256:be9be735f827820a06340dff2ddea1fb7234561fa5e6300a62fe7f54d40546a0", + "sha256:cca7741c0fcc765568350cb139e92b7f9f3c9a08c4f32591d18ab0a6ac9e71b6", + "sha256:d0d19fb2441947b58fbf91336638c2b9f4cc98e05e1045404d7a4cb7cddc7a65", + "sha256:e02794ac791662a5eafc6ffeaf9bcc149035a0e48eb0a9d40a8feb4622605a3d", + "sha256:e0f30db709c939cabf64a6dc5babb276e6d823fd84464ab916f9b9ba5623ca15", + "sha256:e92c2d33858c8f560671b448205a268096e17870dcf60a9bb3ac7bfbafb7f5f9" ], "index": "pypi", - "version": "==2.1.1" + "version": "==2.1.6" }, "wcwidth": { "hashes": [ @@ -584,12 +709,70 @@ "index": "pypi", "version": "==0.16.1" }, + "wrapt": { + "hashes": [ + "sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179", + "sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096", + "sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374", + "sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df", + "sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185", + "sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785", + "sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7", + "sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909", + "sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918", + "sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33", + "sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068", + "sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829", + "sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af", + "sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79", + "sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce", + "sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc", + "sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36", + "sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade", + "sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca", + "sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32", + "sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125", + "sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e", + "sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709", + "sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f", + "sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b", + "sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb", + "sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb", + "sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489", + "sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640", + "sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb", + "sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851", + "sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d", + "sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44", + "sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13", + "sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2", + "sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb", + "sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b", + "sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9", + "sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755", + "sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c", + "sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a", + "sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf", + "sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3", + "sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229", + "sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e", + "sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de", + "sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554", + "sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10", + "sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80", + "sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056", + "sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.13.3" + }, "zipp": { "hashes": [ - "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76", - "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098" + "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", + "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" ], - "version": "==3.4.1" + "markers": "python_version >= '3.6'", + "version": "==3.6.0" } }, "develop": { @@ -598,96 +781,95 @@ "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==21.2.0" }, "certifi": { "hashes": [ - "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", - "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" + "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", + "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" ], - "version": "==2020.12.5" + "version": "==2021.10.8" }, - "chardet": { + "charset-normalizer": { "hashes": [ - "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", - "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" + "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721", + "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c" ], - "version": "==4.0.0" + "markers": "python_version >= '3'", + "version": "==2.0.9" }, "click": { "hashes": [ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, "coverage": { "extras": [ - "toml" - ], - "hashes": [ - "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c", - "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6", - "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45", - "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a", - "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03", - "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529", - "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a", - "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a", - "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2", - "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6", - "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759", - "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53", - "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a", - "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4", - "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff", - "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502", - "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793", - "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb", - "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905", - "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821", - "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b", - "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81", - "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0", - "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b", - "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3", - "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184", - "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701", - "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a", - "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82", - "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638", - "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5", - "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083", - "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6", - "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90", - "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465", - "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a", - "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3", - "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e", - "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066", - "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf", - "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b", - "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae", - "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669", - "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873", - "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b", - "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6", - "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb", - "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160", - "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c", - "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079", - "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d", - "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6" - ], - "version": "==5.5" + + ], + "hashes": [ + "sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0", + "sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd", + "sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884", + "sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48", + "sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76", + "sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0", + "sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64", + "sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685", + "sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47", + "sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d", + "sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840", + "sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f", + "sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971", + "sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c", + "sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a", + "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de", + "sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17", + "sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4", + "sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521", + "sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57", + "sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b", + "sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282", + "sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644", + "sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475", + "sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d", + "sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da", + "sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953", + "sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2", + "sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e", + "sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c", + "sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc", + "sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64", + "sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74", + "sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617", + "sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3", + "sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d", + "sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa", + "sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739", + "sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8", + "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8", + "sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781", + "sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58", + "sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9", + "sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c", + "sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd", + "sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e", + "sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49" + ], + "markers": "python_version >= '3.6'", + "version": "==6.2" }, "coveralls": { "hashes": [ - "sha256:7bd173b3425733661ba3063c88f180127cc2b20e9740686f86d2622b31b41385", - "sha256:cbb942ae5ef3d2b55388cb5b43e93a269544911535f1e750e1c656aef019ce60" + "sha256:b32a8bb5d2df585207c119d6c01567b81fba690c9c10a753bfe27a335bfc43ea", + "sha256:f42015f31d386b351d4226389b387ae173207058832fbf5c8ec4b40e27b16026" ], "index": "pypi", - "version": "==3.0.1" + "version": "==3.3.1" }, "docopt": { "hashes": [ @@ -697,32 +879,34 @@ }, "flake8": { "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d", + "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d" ], "index": "pypi", - "version": "==3.9.2" + "version": "==4.0.1" }, - "future": { + "ghp-import": { "hashes": [ - "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" + "sha256:5f8962b30b20652cdffa9c5a9812f7de6bcb56ec475acac579807719bf242c46", + "sha256:947b3771f11be850c852c64b561c600fdddf794bab363060854c1ee7ad05e071" ], - "version": "==0.18.2" + "version": "==2.0.2" }, "idna": { "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" + "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", + "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "version": "==2.10" + "markers": "python_version >= '3'", + "version": "==3.3" }, "importlib-metadata": { "hashes": [ - "sha256:8c501196e49fb9df5df43833bdb1e4328f64847763ec8a50703148b73784d581", - "sha256:d7eb1dea6d6a6086f8be21784cc9e3bcfa55872b52309bc5fad53a8ea444465d" + "sha256:53ccfd5c134223e497627b9815d5030edf77d2ed573922f7a0b8f8bb81a1c100", + "sha256:75bdec14c397f528724c1bfd9709d660b33a4d2e77387a3358f20b848bb5e5fb" ], "markers": "python_version < '3.8'", - "version": "==4.0.1" + "version": "==4.8.2" }, "iniconfig": { "hashes": [ @@ -736,76 +920,91 @@ "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==2.11.3" }, - "joblib": { - "hashes": [ - "sha256:9c17567692206d2f3fb9ecf5e991084254fe631665c450b443761c4186a613f7", - "sha256:feeb1ec69c4d45129954f1b7034954241eedfd6ba39b5e9e4b6883be3332d5e5" - ], - "version": "==1.0.1" - }, - "livereload": { - "hashes": [ - "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869" - ], - "version": "==2.6.3" - }, - "lunr": { - "extras": [ - "languages" - ], - "hashes": [ - "sha256:aab3f489c4d4fab4c1294a257a30fec397db56f0a50273218ccc3efdbf01d6ca", - "sha256:c4fb063b98eff775dd638b3df380008ae85e6cb1d1a24d1cd81a10ef6391c26e" - ], - "version": "==0.5.8" - }, "markdown": { "hashes": [ - "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49", - "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c" + "sha256:76df8ae32294ec39dcf89340382882dfa12975f87f45c3ed1ecdb1e8cefc7006", + "sha256:9923332318f843411e9932237530df53162e29dc7a4e2b91e35764583c46c9a3" ], - "version": "==3.3.4" + "markers": "python_version >= '3.6'", + "version": "==3.3.6" }, "markupsafe": { "hashes": [ - "sha256:007dc055dbce5b1104876acee177dbfd18757e19d562cd440182e1f492e96b95", - "sha256:031bf79a27d1c42f69c276d6221172417b47cb4b31cdc73d362a9bf5a1889b9f", - "sha256:161d575fa49395860b75da5135162481768b11208490d5a2143ae6785123e77d", - "sha256:24bbc3507fb6dfff663af7900a631f2aca90d5a445f272db5fc84999fa5718bc", - "sha256:2efaeb1baff547063bad2b2893a8f5e9c459c4624e1a96644bbba08910ae34e0", - "sha256:32200f562daaab472921a11cbb63780f1654552ae49518196fc361ed8e12e901", - "sha256:3261fae28155e5c8634dd7710635fe540a05b58f160cef7713c7700cb9980e66", - "sha256:3b54a9c68995ef4164567e2cd1a5e16db5dac30b2a50c39c82db8d4afaf14f63", - "sha256:3c352ff634e289061711608f5e474ec38dbaa21e3e168820d53d5f4015e5b91b", - "sha256:3fb47f97f1d338b943126e90b79cad50d4fcfa0b80637b5a9f468941dbbd9ce5", - "sha256:441ce2a8c17683d97e06447fcbccbdb057cbf587c78eb75ae43ea7858042fe2c", - "sha256:45535241baa0fc0ba2a43961a1ac7562ca3257f46c4c3e9c0de38b722be41bd1", - "sha256:4aca81a687975b35e3e80bcf9aa93fe10cd57fac37bf18b2314c186095f57e05", - "sha256:4cc563836f13c57f1473bc02d1e01fc37bab70ad4ee6be297d58c1d66bc819bf", - "sha256:4fae0677f712ee090721d8b17f412f1cbceefbf0dc180fe91bab3232f38b4527", - "sha256:58bc9fce3e1557d463ef5cee05391a05745fd95ed660f23c1742c711712c0abb", - "sha256:664832fb88b8162268928df233f4b12a144a0c78b01d38b81bdcf0fc96668ecb", - "sha256:70820a1c96311e02449591cbdf5cd1c6a34d5194d5b55094ab725364375c9eb2", - "sha256:79b2ae94fa991be023832e6bcc00f41dbc8e5fe9d997a02db965831402551730", - "sha256:83cf0228b2f694dcdba1374d5312f2277269d798e65f40344964f642935feac1", - "sha256:87de598edfa2230ff274c4de7fcf24c73ffd96208c8e1912d5d0fee459767d75", - "sha256:8f806bfd0f218477d7c46a11d3e52dc7f5fdfaa981b18202b7dc84bbc287463b", - "sha256:90053234a6479738fd40d155268af631c7fca33365f964f2208867da1349294b", - "sha256:a00dce2d96587651ef4fa192c17e039e8cfab63087c67e7d263a5533c7dad715", - "sha256:a08cd07d3c3c17cd33d9e66ea9dee8f8fc1c48e2d11bd88fd2dc515a602c709b", - "sha256:a19d39b02a24d3082856a5b06490b714a9d4179321225bbf22809ff1e1887cc8", - "sha256:d00a669e4a5bec3ee6dbeeeedd82a405ced19f8aeefb109a012ea88a45afff96", - "sha256:dab0c685f21f4a6c95bfc2afd1e7eae0033b403dd3d8c1b6d13a652ada75b348", - "sha256:df561f65049ed3556e5b52541669310e88713fdae2934845ec3606f283337958", - "sha256:e4570d16f88c7f3032ed909dc9e905a17da14a1c4cfd92608e3fda4cb1208bbd", - "sha256:e77e4b983e2441aff0c0d07ee711110c106b625f440292dfe02a2f60c8218bd6", - "sha256:e79212d09fc0e224d20b43ad44bb0a0a3416d1e04cf6b45fed265114a5d43d20", - "sha256:f58b5ba13a5689ca8317b98439fccfbcc673acaaf8241c1869ceea40f5d585bf", - "sha256:fef86115fdad7ae774720d7103aa776144cf9b66673b4afa9bcaa7af990ed07b" - ], - "version": "==2.0.0" + "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", + "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", + "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", + "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", + "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", + "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", + "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", + "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", + "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", + "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", + "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", + "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", + "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", + "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", + "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", + "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", + "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", + "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", + "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", + "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", + "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", + "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", + "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", + "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", + "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", + "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", + "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", + "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", + "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", + "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", + "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", + "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", + "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", + "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", + "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", + "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", + "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", + "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", + "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", + "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", + "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", + "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", + "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", + "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", + "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", + "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", + "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", + "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", + "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", + "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", + "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", + "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", + "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", + "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", + "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", + "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", + "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", + "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", + "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", + "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", + "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", + "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", + "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", + "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", + "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", + "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", + "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", + "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", + "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.1" }, "mccabe": { "hashes": [ @@ -814,172 +1013,155 @@ ], "version": "==0.6.1" }, - "mkdocs": { + "mergedeep": { "hashes": [ - "sha256:096f52ff52c02c7e90332d2e53da862fde5c062086e1b5356a6e392d5d60f5e9", - "sha256:f0b61e5402b99d7789efa032c7a74c90a20220a9c81749da06dbfbcbd52ffb39" + "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", + "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307" ], - "index": "pypi", - "version": "==1.1.2" + "markers": "python_version >= '3.6'", + "version": "==1.3.4" }, - "nltk": { + "mkdocs": { "hashes": [ - "sha256:240e23ab1ab159ef9940777d30c7c72d7e76d91877099218a7585370c11f6b9e", - "sha256:57d556abed621ab9be225cc6d2df1edce17572efb67a3d754630c9f8381503eb" + "sha256:89f5a094764381cda656af4298727c9f53dc3e602983087e1fe96ea1df24f4c1", + "sha256:a1fa8c2d0c1305d7fc2b9d9f607c71778572a8b110fb26642aa00296c9e6d072" ], - "version": "==3.6.2" + "index": "pypi", + "version": "==1.2.3" }, "packaging": { "hashes": [ - "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", - "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" + "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", + "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" ], - "version": "==20.9" + "markers": "python_version >= '3.6'", + "version": "==21.3" }, "pluggy": { "hashes": [ - "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", - "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" + "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", + "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" ], - "version": "==0.13.1" + "markers": "python_version >= '3.6'", + "version": "==1.0.0" }, "py": { "hashes": [ - "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3", - "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a" + "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", + "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" ], - "version": "==1.10.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.11.0" }, "pycodestyle": { "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20", + "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f" ], - "version": "==2.7.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==2.8.0" }, "pyflakes": { "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c", + "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e" ], - "version": "==2.3.1" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.4.0" }, "pyparsing": { "hashes": [ - "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" + "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4", + "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81" ], - "version": "==2.4.7" + "markers": "python_version >= '3.6'", + "version": "==3.0.6" }, "pytest": { "hashes": [ - "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b", - "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890" + "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89", + "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134" ], "index": "pypi", - "version": "==6.2.4" + "version": "==6.2.5" }, "pytest-cov": { "hashes": [ - "sha256:8535764137fecce504a49c2b742288e3d34bc09eed298ad65963616cc98fd45e", - "sha256:95d4933dcbbacfa377bb60b29801daa30d90c33981ab2a79e9ab4452c165066e" + "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6", + "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470" ], "index": "pypi", - "version": "==2.12.0" + "version": "==3.0.0" + }, + "python-dateutil": { + "hashes": [ + "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", + "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + ], + "index": "pypi", + "version": "==2.8.2" }, "pyyaml": { "hashes": [ - "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", - "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", - "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", - "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", - "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", - "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", - "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", - "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", - "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", - "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", - "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", - "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", - "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", - "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", - "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", - "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", - "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", - "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", - "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", - "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", - "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", - "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", - "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", - "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", - "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", - "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", - "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", - "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", - "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" - ], - "version": "==5.4.1" - }, - "regex": { - "hashes": [ - "sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5", - "sha256:11d773d75fa650cd36f68d7ca936e3c7afaae41b863b8c387a22aaa78d3c5c79", - "sha256:18c071c3eb09c30a264879f0d310d37fe5d3a3111662438889ae2eb6fc570c31", - "sha256:1e1c20e29358165242928c2de1482fb2cf4ea54a6a6dea2bd7a0e0d8ee321500", - "sha256:281d2fd05555079448537fe108d79eb031b403dac622621c78944c235f3fcf11", - "sha256:314d66636c494ed9c148a42731b3834496cc9a2c4251b1661e40936814542b14", - "sha256:32e65442138b7b76dd8173ffa2cf67356b7bc1768851dded39a7a13bf9223da3", - "sha256:339456e7d8c06dd36a22e451d58ef72cef293112b559010db3d054d5560ef439", - "sha256:3916d08be28a1149fb97f7728fca1f7c15d309a9f9682d89d79db75d5e52091c", - "sha256:3a9cd17e6e5c7eb328517969e0cb0c3d31fd329298dd0c04af99ebf42e904f82", - "sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711", - "sha256:4c46e22a0933dd783467cf32b3516299fb98cfebd895817d685130cc50cd1093", - "sha256:4c557a7b470908b1712fe27fb1ef20772b78079808c87d20a90d051660b1d69a", - "sha256:52ba3d3f9b942c49d7e4bc105bb28551c44065f139a65062ab7912bef10c9afb", - "sha256:563085e55b0d4fb8f746f6a335893bda5c2cef43b2f0258fe1020ab1dd874df8", - "sha256:598585c9f0af8374c28edd609eb291b5726d7cbce16be6a8b95aa074d252ee17", - "sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000", - "sha256:67bdb9702427ceddc6ef3dc382455e90f785af4c13d495f9626861763ee13f9d", - "sha256:6d1b01031dedf2503631d0903cb563743f397ccaf6607a5e3b19a3d76fc10480", - "sha256:741a9647fcf2e45f3a1cf0e24f5e17febf3efe8d4ba1281dcc3aa0459ef424dc", - "sha256:7c2a1af393fcc09e898beba5dd59196edaa3116191cc7257f9224beaed3e1aa0", - "sha256:7d9884d86dd4dd489e981d94a65cd30d6f07203d90e98f6f657f05170f6324c9", - "sha256:90f11ff637fe8798933fb29f5ae1148c978cccb0452005bf4c69e13db951e765", - "sha256:919859aa909429fb5aa9cf8807f6045592c85ef56fdd30a9a3747e513db2536e", - "sha256:96fcd1888ab4d03adfc9303a7b3c0bd78c5412b2bfbe76db5b56d9eae004907a", - "sha256:97f29f57d5b84e73fbaf99ab3e26134e6687348e95ef6b48cfd2c06807005a07", - "sha256:980d7be47c84979d9136328d882f67ec5e50008681d94ecc8afa8a65ed1f4a6f", - "sha256:a91aa8619b23b79bcbeb37abe286f2f408d2f2d6f29a17237afda55bb54e7aac", - "sha256:ade17eb5d643b7fead300a1641e9f45401c98eee23763e9ed66a43f92f20b4a7", - "sha256:b9c3db21af35e3b3c05764461b262d6f05bbca08a71a7849fd79d47ba7bc33ed", - "sha256:bd28bc2e3a772acbb07787c6308e00d9626ff89e3bfcdebe87fa5afbfdedf968", - "sha256:bf5824bfac591ddb2c1f0a5f4ab72da28994548c708d2191e3b87dd207eb3ad7", - "sha256:c0502c0fadef0d23b128605d69b58edb2c681c25d44574fc673b0e52dce71ee2", - "sha256:c38c71df845e2aabb7fb0b920d11a1b5ac8526005e533a8920aea97efb8ec6a4", - "sha256:ce15b6d103daff8e9fee13cf7f0add05245a05d866e73926c358e871221eae87", - "sha256:d3029c340cfbb3ac0a71798100ccc13b97dddf373a4ae56b6a72cf70dfd53bc8", - "sha256:e512d8ef5ad7b898cdb2d8ee1cb09a8339e4f8be706d27eaa180c2f177248a10", - "sha256:e8e5b509d5c2ff12f8418006d5a90e9436766133b564db0abaec92fd27fcee29", - "sha256:ee54ff27bf0afaf4c3b3a62bcd016c12c3fdb4ec4f413391a90bd38bc3624605", - "sha256:fa4537fb4a98fe8fde99626e4681cc644bdcf2a795038533f9f711513a862ae6", - "sha256:fd45ff9293d9274c5008a2054ecef86a9bfe819a67c7be1afb65e69b405b3042" - ], - "version": "==2021.4.4" + "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", + "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", + "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", + "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", + "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", + "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", + "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", + "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", + "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", + "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", + "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", + "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", + "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", + "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", + "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", + "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", + "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", + "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", + "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", + "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", + "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", + "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", + "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", + "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", + "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", + "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", + "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", + "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", + "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", + "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", + "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", + "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", + "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" + ], + "markers": "python_version >= '3.6'", + "version": "==6.0" + }, + "pyyaml-env-tag": { + "hashes": [ + "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", + "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069" + ], + "markers": "python_version >= '3.6'", + "version": "==0.1" }, "requests": { "hashes": [ - "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", - "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" + "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24", + "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7" ], "index": "pypi", - "version": "==2.25.1" + "version": "==2.26.0" }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "toml": { @@ -987,83 +1169,68 @@ "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.10.2" }, - "tornado": { - "hashes": [ - "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb", - "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c", - "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288", - "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95", - "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558", - "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe", - "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791", - "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d", - "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326", - "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b", - "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4", - "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c", - "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910", - "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5", - "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c", - "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0", - "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675", - "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd", - "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f", - "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c", - "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea", - "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6", - "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05", - "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd", - "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575", - "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a", - "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37", - "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795", - "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f", - "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32", - "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c", - "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01", - "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4", - "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2", - "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921", - "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085", - "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df", - "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102", - "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5", - "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68", - "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5" - ], - "version": "==6.1" - }, - "tqdm": { - "hashes": [ - "sha256:daec693491c52e9498632dfbe9ccfc4882a557f5fa08982db1b4d3adbe0887c3", - "sha256:ebdebdb95e3477ceea267decfc0784859aa3df3e27e22d23b83e9b272bf157ae" - ], - "version": "==4.60.0" + "tomli": { + "hashes": [ + "sha256:c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee", + "sha256:f04066f68f5554911363063a30b108d2b5a5b1a010aa8b6132af78489fe3aade" + ], + "version": "==1.2.2" }, "typing-extensions": { "hashes": [ - "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", - "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", - "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" + "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e", + "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b" ], - "markers": "python_version < '3.8'", - "version": "==3.10.0.0" + "markers": "python_version < '3.10'", + "version": "==4.0.1" }, "urllib3": { "hashes": [ - "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df", - "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937" + "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece", + "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_full_version < '4.0.0'", + "version": "==1.26.7" + }, + "watchdog": { + "hashes": [ + "sha256:25fb5240b195d17de949588628fdf93032ebf163524ef08933db0ea1f99bd685", + "sha256:3386b367e950a11b0568062b70cc026c6f645428a698d33d39e013aaeda4cc04", + "sha256:3becdb380d8916c873ad512f1701f8a92ce79ec6978ffde92919fd18d41da7fb", + "sha256:4ae38bf8ba6f39d5b83f78661273216e7db5b00f08be7592062cb1fc8b8ba542", + "sha256:8047da932432aa32c515ec1447ea79ce578d0559362ca3605f8e9568f844e3c6", + "sha256:8f1c00aa35f504197561060ca4c21d3cc079ba29cf6dd2fe61024c70160c990b", + "sha256:922a69fa533cb0c793b483becaaa0845f655151e7256ec73630a1b2e9ebcb660", + "sha256:9693f35162dc6208d10b10ddf0458cc09ad70c30ba689d9206e02cd836ce28a3", + "sha256:a0f1c7edf116a12f7245be06120b1852275f9506a7d90227648b250755a03923", + "sha256:a36e75df6c767cbf46f61a91c70b3ba71811dfa0aca4a324d9407a06a8b7a2e7", + "sha256:aba5c812f8ee8a3ff3be51887ca2d55fb8e268439ed44110d3846e4229eb0e8b", + "sha256:ad6f1796e37db2223d2a3f302f586f74c72c630b48a9872c1e7ae8e92e0ab669", + "sha256:ae67501c95606072aafa865b6ed47343ac6484472a2f95490ba151f6347acfc2", + "sha256:b2fcf9402fde2672545b139694284dc3b665fd1be660d73eca6805197ef776a3", + "sha256:b52b88021b9541a60531142b0a451baca08d28b74a723d0c99b13c8c8d48d604", + "sha256:b7d336912853d7b77f9b2c24eeed6a5065d0a0cc0d3b6a5a45ad6d1d05fb8cd8", + "sha256:bd9ba4f332cf57b2c1f698be0728c020399ef3040577cde2939f2e045b39c1e5", + "sha256:be9be735f827820a06340dff2ddea1fb7234561fa5e6300a62fe7f54d40546a0", + "sha256:cca7741c0fcc765568350cb139e92b7f9f3c9a08c4f32591d18ab0a6ac9e71b6", + "sha256:d0d19fb2441947b58fbf91336638c2b9f4cc98e05e1045404d7a4cb7cddc7a65", + "sha256:e02794ac791662a5eafc6ffeaf9bcc149035a0e48eb0a9d40a8feb4622605a3d", + "sha256:e0f30db709c939cabf64a6dc5babb276e6d823fd84464ab916f9b9ba5623ca15", + "sha256:e92c2d33858c8f560671b448205a268096e17870dcf60a9bb3ac7bfbafb7f5f9" ], - "version": "==1.26.4" + "index": "pypi", + "version": "==2.1.6" }, "zipp": { "hashes": [ - "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76", - "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098" + "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", + "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" ], - "version": "==3.4.1" + "markers": "python_version >= '3.6'", + "version": "==3.6.0" } } } diff --git a/README.md b/README.md index a0839fcb..6c863d3e 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,4 @@ AskOmics is a visual SPARQL query interface supporting both intuitive data integ ## Documentation All documentation, included installation instruction is [here](https://flaskomics.readthedocs.io/en/latest/) +A Galaxy Training tutorial is available [here](https://training.galaxyproject.org/training-material/topics/transcriptomics/tutorials/rna-seq-analysis-with-askomics-it/tutorial.html) diff --git a/askomics/api/admin.py b/askomics/api/admin.py index f464182d..5200ebb5 100644 --- a/askomics/api/admin.py +++ b/askomics/api/admin.py @@ -7,6 +7,8 @@ from askomics.libaskomics.FilesHandler import FilesHandler from askomics.libaskomics.LocalAuth import LocalAuth from askomics.libaskomics.Mailer import Mailer +from askomics.libaskomics.PrefixManager import PrefixManager +from askomics.libaskomics.OntologyManager import OntologyManager from askomics.libaskomics.Result import Result from askomics.libaskomics.ResultsHandler import ResultsHandler @@ -256,6 +258,12 @@ def toogle_public_dataset(): datasets_handler.handle_datasets(admin=True) for dataset in datasets_handler.datasets: + if (not data.get("newStatus", False) and dataset.ontology): + return jsonify({ + 'datasets': [], + 'error': True, + 'errorMessage': "Cannot unpublicize a dataset linked to an ontology" + }), 400 current_app.logger.debug(data["newStatus"]) dataset.toggle_public(data["newStatus"], admin=True) @@ -510,3 +518,305 @@ def delete_datasets(): 'error': False, 'errorMessage': '' }) + + +@admin_bp.route("/api/admin/getprefixes", methods=["GET"]) +@api_auth +@admin_required +def get_prefixes(): + """Get all custom prefixes + + Returns + ------- + json + prefixes: list of all custom prefixes + error: True if error, else False + errorMessage: the error message of error, else an empty string + """ + try: + pm = PrefixManager(current_app, session) + prefixes = pm.get_custom_prefixes() + except Exception as e: + traceback.print_exc(file=sys.stdout) + return jsonify({ + 'prefixes': [], + 'error': True, + 'errorMessage': str(e) + }), 500 + + return jsonify({ + 'prefixes': prefixes, + 'error': False, + 'errorMessage': '' + }) + + +@admin_bp.route("/api/admin/addprefix", methods=["POST"]) +@api_auth +@admin_required +def add_prefix(): + """Create a new prefix + + Returns + ------- + json + prefixes: list of all custom prefixes + error: True if error, else False + errorMessage: the error message of error, else an empty string + """ + + data = request.get_json() + if not data or not (data.get("prefix") and data.get("namespace")): + return jsonify({ + 'prefixes': [], + 'error': True, + 'errorMessage': "Missing parameter" + }), 400 + + pm = PrefixManager(current_app, session) + prefixes = pm.get_custom_prefixes() + + prefix = data.get("prefix") + namespace = data.get("namespace") + + if any([prefix == custom['prefix'] for custom in prefixes]): + return jsonify({ + 'prefixes': [], + 'error': True, + 'errorMessage': "Prefix {} is already in use".format(prefix) + }), 400 + + try: + pm.add_custom_prefix(prefix, namespace) + prefixes = pm.get_custom_prefixes() + except Exception as e: + traceback.print_exc(file=sys.stdout) + return jsonify({ + 'prefixes': [], + 'error': True, + 'errorMessage': str(e) + }), 500 + + return jsonify({ + 'prefixes': prefixes, + 'error': False, + 'errorMessage': '' + }) + + +@admin_bp.route("/api/admin/delete_prefixes", methods=["POST"]) +@api_auth +@admin_required +def delete_prefix(): + """Delete a prefix + + Returns + ------- + json + prefixes: list of all custom prefixes + error: True if error, else False + errorMessage: the error message of error, else an empty string + """ + + data = request.get_json() + if not data or not data.get("prefixesIdToDelete"): + return jsonify({ + 'prefixes': [], + 'error': True, + 'errorMessage': "Missing prefixesIdToDelete parameter" + }), 400 + + pm = PrefixManager(current_app, session) + try: + pm.remove_custom_prefixes(data.get("prefixesIdToDelete")) + prefixes = pm.get_custom_prefixes() + except Exception as e: + traceback.print_exc(file=sys.stdout) + return jsonify({ + 'prefixes': [], + 'error': True, + 'errorMessage': str(e) + }), 500 + + return jsonify({ + 'prefixes': prefixes, + 'error': False, + 'errorMessage': '' + }) + + +@admin_bp.route("/api/admin/getontologies", methods=["GET"]) +@api_auth +@admin_required +def get_ontologies(): + """Get all ontologies + + Returns + ------- + json + prefixes: list of all custom prefixes + error: True if error, else False + errorMessage: the error message of error, else an empty string + """ + try: + om = OntologyManager(current_app, session) + ontologies = om.list_full_ontologies() + except Exception as e: + traceback.print_exc(file=sys.stdout) + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': str(e) + }), 500 + + return jsonify({ + 'ontologies': ontologies, + 'error': False, + 'errorMessage': '' + }) + + +@admin_bp.route("/api/admin/addontology", methods=["POST"]) +@api_auth +@admin_required +def add_ontology(): + """Create a new ontology + + Returns + ------- + json + ontologies: list of all ontologies + error: True if error, else False + errorMessage: the error message of error, else an empty string + """ + + data = request.get_json() + if not data or not (data.get("name") and data.get("uri") and data.get("shortName") and data.get("type") and data.get("datasetId") and data.get("labelUri")): + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': "Missing parameter" + }), 400 + + name = data.get("name").strip() + uri = data.get("uri").strip() + short_name = data.get("shortName") + type = data.get("type").strip() + dataset_id = data.get("datasetId") + label_uri = data.get("labelUri").strip() + + om = OntologyManager(current_app, session) + + if type == "ols" and not om.test_ols_ontology(short_name): + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': "{} ontology not found in OLS".format(short_name) + }), 400 + + om = OntologyManager(current_app, session) + ontologies = om.list_full_ontologies() + + if type not in ["none", "local", "ols"]: + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': "Invalid type" + }), 400 + + datasets_info = [{'id': dataset_id}] + + try: + datasets_handler = DatasetsHandler(current_app, session, datasets_info=datasets_info) + datasets_handler.handle_datasets() + except IndexError: + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': "Dataset {} not found".format(dataset_id) + }), 400 + + if not len(datasets_handler.datasets) == 1 or not datasets_handler.datasets[0].public: + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': "Invalid dataset id" + }), 400 + + dataset = datasets_handler.datasets[0] + + if any([name == onto['name'] or short_name == onto['short_name'] for onto in ontologies]): + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': "Name and short name must be unique" + }), 400 + + if any([dataset_id == onto['dataset_id'] for onto in ontologies]): + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': "Dataset is already linked to another ontology" + }), 400 + + try: + om.add_ontology(name, uri, short_name, dataset.id, dataset.graph_name, dataset.endpoint, remote_graph=dataset.remote_graph, type=type, label_uri=label_uri) + ontologies = om.list_full_ontologies() + except Exception as e: + traceback.print_exc(file=sys.stdout) + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': str(e) + }), 500 + + return jsonify({ + 'ontologies': ontologies, + 'error': False, + 'errorMessage': '' + }) + + +@admin_bp.route("/api/admin/delete_ontologies", methods=["POST"]) +@api_auth +@admin_required +def delete_ontologies(): + """Delete one or more ontologies + + Returns + ------- + json + ontologies: list of all ontologies + error: True if error, else False + errorMessage: the error message of error, else an empty string + """ + + data = request.get_json() + if not data or not data.get("ontologiesIdToDelete"): + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': "Missing ontologiesIdToDelete parameter" + }), 400 + + om = OntologyManager(current_app, session) + + ontologies = om.list_full_ontologies() + onto_to_delete = [{"id": ontology['id'], "dataset_id": ontology['dataset_id']} for ontology in ontologies if ontology['id'] in data.get("ontologiesIdToDelete")] + + try: + om.remove_ontologies(onto_to_delete) + ontologies = om.list_full_ontologies() + except Exception as e: + traceback.print_exc(file=sys.stdout) + return jsonify({ + 'ontologies': [], + 'error': True, + 'errorMessage': str(e) + }), 500 + + return jsonify({ + 'ontologies': ontologies, + 'error': False, + 'errorMessage': '' + }) diff --git a/askomics/api/data.py b/askomics/api/data.py index 2e92d875..24a26cdd 100644 --- a/askomics/api/data.py +++ b/askomics/api/data.py @@ -5,7 +5,6 @@ from askomics.api.auth import api_auth from askomics.libaskomics.SparqlQuery import SparqlQuery -from askomics.libaskomics.SparqlQueryLauncher import SparqlQueryLauncher from flask import (Blueprint, current_app, jsonify, session) @@ -26,7 +25,7 @@ def get_data(uri): """ try: - query = SparqlQuery(current_app, session) + query = SparqlQuery(current_app, session, get_graphs=True) graphs, endpoints = query.get_graphs_and_endpoints(all_selected=True) endpoints = [val['uri'] for val in endpoints.values()] @@ -40,14 +39,7 @@ def get_data(uri): base_uri = current_app.iniconfig.get('triplestore', 'namespace_data') full_uri = "<%s%s>" % (base_uri, uri) - raw_query = "SELECT DISTINCT ?predicat ?object\nWHERE {\n?URI ?predicat ?object\nVALUES ?URI {%s}}\n" % (full_uri) - federated = query.is_federated() - replace_froms = query.replace_froms() - - sparql = query.format_query(raw_query, replace_froms=replace_froms, federated=federated) - - query_launcher = SparqlQueryLauncher(current_app, session, get_result_query=True, federated=federated, endpoints=endpoints) - header, data = query_launcher.process_query(sparql) + data = query.get_uri_parameters(full_uri, endpoints) except Exception as e: current_app.logger.error(str(e).replace('\\n', '\n')) diff --git a/askomics/api/datasets.py b/askomics/api/datasets.py index bceb125e..665a0490 100644 --- a/askomics/api/datasets.py +++ b/askomics/api/datasets.py @@ -119,6 +119,7 @@ def toogle_public(): error: True if error, else False errorMessage: the error message of error, else an empty string """ + data = request.get_json() if not (data and data.get("id")): return jsonify({ @@ -135,6 +136,12 @@ def toogle_public(): datasets_handler.handle_datasets() for dataset in datasets_handler.datasets: + if (not data.get("newStatus", False) and dataset.ontology): + return jsonify({ + 'datasets': [], + 'error': True, + 'errorMessage': "Cannot unpublicize a dataset linked to an ontology" + }), 400 current_app.logger.debug(data.get("newStatus", False)) dataset.toggle_public(data.get("newStatus", False)) diff --git a/askomics/api/file.py b/askomics/api/file.py index 62e9587e..5d224030 100644 --- a/askomics/api/file.py +++ b/askomics/api/file.py @@ -1,4 +1,5 @@ """Api routes""" +import requests import sys import traceback import urllib @@ -7,6 +8,7 @@ from askomics.libaskomics.FilesHandler import FilesHandler from askomics.libaskomics.FilesUtils import FilesUtils from askomics.libaskomics.Dataset import Dataset +from askomics.libaskomics.RdfFile import RdfFile from flask import (Blueprint, current_app, jsonify, request, send_from_directory, session) @@ -188,8 +190,19 @@ def upload_url(): }), 400 try: - files = FilesHandler(current_app, session) - files.download_url(data["url"]) + if session["user"]["quota"] > 0: + with requests.get(data["url"], stream=True) as r: + # Check header for total size, and check quota. + if r.headers.get('Content-length'): + total_size = int(r.headers.get('Content-length')) + disk_space + if total_size >= session["user"]["quota"]: + return jsonify({ + 'errorMessage': "File will exceed quota", + "error": True + }), 400 + + session_dict = {'user': session['user']} + current_app.celery.send_task('download_file', (session_dict, data["url"])) except Exception as e: traceback.print_exc(file=sys.stdout) return jsonify({ @@ -224,6 +237,7 @@ def get_preview(): }), 400 try: + files_handler = FilesHandler(current_app, session) files_handler.handle_files(data['filesId']) @@ -318,19 +332,22 @@ def integrate(): for file in files_handler.files: - data["externalEndpoint"] = data["externalEndpoint"] if data.get("externalEndpoint") else None - data["customUri"] = data["customUri"] if data.get("customUri") else None + data["externalEndpoint"] = data["externalEndpoint"] if (data.get("externalEndpoint") and isinstance(file, RdfFile)) else None + data["externalGraph"] = data["externalGraph"] if (data.get("externalGraph") and isinstance(file, RdfFile)) else None + data["customUri"] = data["customUri"] if (data.get("customUri") and not isinstance(file, RdfFile)) else None dataset_info = { "celery_id": None, "file_id": file.id, "name": file.human_name, "graph_name": file.file_graph, - "public": data.get("public") if session["user"]["admin"] else False + "public": (data.get("public", False) if session["user"]["admin"] else False) or current_app.iniconfig.getboolean("askomics", "single_tenant", fallback=False) } + endpoint = data["externalEndpoint"] or current_app.iniconfig.get('triplestore', 'endpoint') + dataset = Dataset(current_app, session, dataset_info) - dataset.save_in_db() + dataset.save_in_db(endpoint, data["externalGraph"]) data["dataset_id"] = dataset.id dataset_ids.append(dataset.id) task = current_app.celery.send_task('integrate', (session_dict, data, request.host_url)) @@ -393,7 +410,7 @@ def get_column_types(): types: list of available column types """ - data = ["numeric", "text", "category", "boolean", "date", "reference", "strand", "start", "end", "general_relation", "symetric_relation"] + data = ["numeric", "text", "category", "boolean", "date", "reference", "strand", "start", "end", "general_relation", "symetric_relation", "label"] return jsonify({ "types": data diff --git a/askomics/api/ontology.py b/askomics/api/ontology.py new file mode 100644 index 00000000..fc1efe37 --- /dev/null +++ b/askomics/api/ontology.py @@ -0,0 +1,59 @@ +import traceback +import sys + +from askomics.api.auth import api_auth +from askomics.libaskomics.OntologyManager import OntologyManager + +from flask import (Blueprint, current_app, jsonify, request, session) + +onto_bp = Blueprint('ontology', __name__, url_prefix='/') + + +@onto_bp.route("/api/ontology//autocomplete", methods=["GET"]) +@api_auth +def autocomplete(short_ontology): + """Get the default sparql query + + Returns + ------- + json + """ + + if "user" not in session and current_app.iniconfig.getboolean("askomics", "protect_public"): + return jsonify({ + "error": True, + "errorMessage": "Ontology {} not found".format(short_ontology), + "results": [] + }), 401 + try: + om = OntologyManager(current_app, session) + ontology = om.get_ontology(short_name=short_ontology) + if not ontology: + return jsonify({ + "error": True, + "errorMessage": "Ontology {} not found".format(short_ontology), + "results": [] + }), 404 + + if ontology['type'] == "none": + return jsonify({ + "error": True, + "errorMessage": "Ontology {} does not have autocompletion".format(short_ontology), + "results": [] + }), 404 + + results = om.autocomplete(ontology["uri"], ontology["type"], request.args.get("q"), short_ontology, ontology["graph"], ontology["endpoint"], ontology['label_uri'], ontology['remote_graph']) + + except Exception as e: + traceback.print_exc(file=sys.stdout) + return jsonify({ + "error": True, + "errorMessage": str(e), + "results": [] + }), 500 + + return jsonify({ + "error": False, + "errorMessage": "", + "results": results + }), 200 diff --git a/askomics/api/query.py b/askomics/api/query.py index f5bfc8af..45dd8c6d 100644 --- a/askomics/api/query.py +++ b/askomics/api/query.py @@ -186,14 +186,8 @@ def save_result(): 'errorMessage': "Missing graphState parameter" }), 400 - query = SparqlQuery(current_app, session, data["graphState"]) - query.build_query_from_json(preview=False, for_editor=False) - info = { - "graph_state": query.json, - "query": query.sparql, - "graphs": query.graphs, - "endpoints": query.endpoints, + "graph_state": data["graphState"], "celery_id": None } diff --git a/askomics/api/results.py b/askomics/api/results.py index 854aeb08..d87f9e9e 100644 --- a/askomics/api/results.py +++ b/askomics/api/results.py @@ -14,6 +14,8 @@ def can_access(user): + if not user: + return False login_allowed = current_app.iniconfig.getboolean('askomics', 'enable_sparql_console', fallback=False) return login_allowed or user['admin'] @@ -164,8 +166,9 @@ def get_graph_and_sparql_query(): graphs = result.graphs endpoints = result.endpoints # Get all graphs and endpoint, and mark as selected the used one - query = SparqlQuery(current_app, session) + query = SparqlQuery(current_app, session, get_graphs=True) graphs, endpoints = query.get_graphs_and_endpoints(selected_graphs=graphs, selected_endpoints=endpoints) + console_enabled = can_access(session.get('user')) except Exception as e: traceback.print_exc(file=sys.stdout) @@ -186,7 +189,8 @@ def get_graph_and_sparql_query(): 'endpoints': endpoints, 'diskSpace': disk_space, 'error': False, - 'errorMessage': '' + 'errorMessage': '', + 'console_enabled': console_enabled }) @@ -359,7 +363,7 @@ def get_sparql_query(): 'error': True, 'errorMessage': "You do not have access to this result" }), 401 - query = SparqlQuery(current_app, session) + query = SparqlQuery(current_app, session, get_graphs=True) sparql = result.get_sparql_query() diff --git a/askomics/api/sparql.py b/askomics/api/sparql.py index c501ab92..043897c8 100644 --- a/askomics/api/sparql.py +++ b/askomics/api/sparql.py @@ -32,7 +32,7 @@ def init(): disk_space = files_utils.get_size_occupied_by_user() if "user" in session else None # Get graphs and endpoints - query = SparqlQuery(current_app, session) + query = SparqlQuery(current_app, session, get_graphs=True) graphs, endpoints = query.get_graphs_and_endpoints(all_selected=True) # Default query diff --git a/askomics/api/start.py b/askomics/api/start.py index eca8f91b..910af044 100644 --- a/askomics/api/start.py +++ b/askomics/api/start.py @@ -5,6 +5,7 @@ from askomics.api.auth import api_auth from askomics.libaskomics.LocalAuth import LocalAuth from askomics.libaskomics.Start import Start +from askomics.libaskomics.OntologyManager import OntologyManager from flask import (Blueprint, current_app, jsonify, session) @@ -64,6 +65,9 @@ def start(): except Exception: pass + ontologies_manager = OntologyManager(current_app, session) + ontologies = ontologies_manager.list_ontologies() + config = { "footerMessage": current_app.iniconfig.get('askomics', 'footer_message'), "frontMessage": front_message, @@ -79,7 +83,10 @@ def start(): "namespaceInternal": current_app.iniconfig.get('triplestore', 'namespace_internal'), "proxyPath": proxy_path, "user": {}, - "logged": False + "logged": False, + "ontologies": ontologies, + "singleTenant": current_app.iniconfig.getboolean('askomics', 'single_tenant', fallback=False), + "autocompleteMaxResults": current_app.iniconfig.getint("askomics", "autocomplete_max_results", fallback=10) } json = { diff --git a/askomics/app.py b/askomics/app.py index 1c23650b..e26b858c 100644 --- a/askomics/app.py +++ b/askomics/app.py @@ -19,6 +19,7 @@ from askomics.api.view import view_bp from askomics.api.results import results_bp from askomics.api.galaxy import galaxy_bp +from askomics.api.ontology import onto_bp from celery import Celery from kombu import Exchange, Queue @@ -46,7 +47,8 @@ datasets_bp, query_bp, results_bp, - galaxy_bp + galaxy_bp, + onto_bp ) diff --git a/askomics/libaskomics/BedFile.py b/askomics/libaskomics/BedFile.py index 7e55a7be..98802ada 100644 --- a/askomics/libaskomics/BedFile.py +++ b/askomics/libaskomics/BedFile.py @@ -17,7 +17,7 @@ class BedFile(File): Public or private dataset """ - def __init__(self, app, session, file_info, host_url=None, external_endpoint=None, custom_uri=None): + def __init__(self, app, session, file_info, host_url=None, external_endpoint=None, custom_uri=None, external_graph=None): """init Parameters @@ -31,7 +31,7 @@ def __init__(self, app, session, file_info, host_url=None, external_endpoint=Non host_url : None, optional AskOmics url """ - File.__init__(self, app, session, file_info, host_url, external_endpoint=external_endpoint, custom_uri=custom_uri) + File.__init__(self, app, session, file_info, host_url, external_endpoint=external_endpoint, custom_uri=custom_uri, external_graph=external_graph) self.entity_name = '' self.category_values = {} @@ -94,13 +94,19 @@ def set_rdf_abstraction_domain_knowledge(self): self.graph_abstraction_dk.add((self.namespace_data[self.format_uri(self.entity_name, remove_space=True)], rdflib.RDF.type, rdflib.OWL["Class"])) self.graph_abstraction_dk.add((self.namespace_data[self.format_uri(self.entity_name, remove_space=True)], rdflib.RDFS.label, rdflib.Literal(self.entity_name))) + attribute_blanks = {} + for attribute in self.attribute_abstraction: + blank = BNode() + for attr_type in attribute["type"]: - self.graph_abstraction_dk.add((attribute["uri"], rdflib.RDF.type, attr_type)) - self.graph_abstraction_dk.add((attribute["uri"], rdflib.RDFS.label, attribute["label"])) - self.graph_abstraction_dk.add((attribute["uri"], rdflib.RDFS.domain, attribute["domain"])) - self.graph_abstraction_dk.add((attribute["uri"], rdflib.RDFS.range, attribute["range"])) + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, attr_type)) + self.graph_abstraction_dk.add((blank, self.namespace_internal["uri"], attribute["uri"])) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.label, attribute["label"])) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.domain, attribute["domain"])) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.range, attribute["range"])) + attribute_blanks[attribute["uri"]] = blank # Domain Knowledge if "values" in attribute.keys(): for value in attribute["values"]: @@ -115,7 +121,9 @@ def set_rdf_abstraction_domain_knowledge(self): if self.faldo_entity: for key, value in self.faldo_abstraction.items(): if value: - self.graph_abstraction_dk.add((value, rdflib.RDF.type, self.faldo_abstraction_eq[key])) + blank = attribute_blanks[value] + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, self.faldo_abstraction_eq[key])) + self.graph_abstraction_dk.add((blank, self.namespace_internal["uri"], value)) def generate_rdf_content(self): """Generate RDF content of the BED file @@ -218,6 +226,7 @@ def generate_rdf_content(self): # Strand strand = False + strand_type = None if feature.strand == "+": self.category_values["strand"] = {"+", } relation = self.namespace_data[self.format_uri("strand")] @@ -226,6 +235,7 @@ def generate_rdf_content(self): self.faldo_abstraction["strand"] = relation self.graph_chunk.add((entity, relation, attribute)) strand = True + strand_type = "+" elif feature.strand == "-": self.category_values["strand"] = {"-", } relation = self.namespace_data[self.format_uri("strand")] @@ -234,6 +244,7 @@ def generate_rdf_content(self): self.faldo_abstraction["strand"] = relation self.graph_chunk.add((entity, relation, attribute)) strand = True + strand_type = "-" else: self.category_values["strand"] = {".", } relation = self.namespace_data[self.format_uri("strand")] @@ -242,17 +253,18 @@ def generate_rdf_content(self): self.faldo_abstraction["strand"] = relation self.graph_chunk.add((entity, relation, attribute)) strand = True + strand_type = "." if strand: - if "strand" not in attribute_list: - attribute_list.append("strand") + if ("strand", strand_type) not in attribute_list: + attribute_list.append(("strand", strand_type)) self.attribute_abstraction.append({ "uri": self.namespace_data[self.format_uri("strand")], "label": rdflib.Literal("strand"), "type": [self.namespace_internal[self.format_uri("AskomicsCategory")], rdflib.OWL.ObjectProperty], "domain": entity_type, "range": self.namespace_data[self.format_uri("{}Category".format("strand"))], - "values": ["+", "-", "."] + "values": [strand_type] }) # Score diff --git a/askomics/libaskomics/CsvFile.py b/askomics/libaskomics/CsvFile.py index 299a2965..821f00dd 100644 --- a/askomics/libaskomics/CsvFile.py +++ b/askomics/libaskomics/CsvFile.py @@ -8,6 +8,7 @@ from rdflib import BNode from askomics.libaskomics.File import File +from askomics.libaskomics.OntologyManager import OntologyManager from askomics.libaskomics.Utils import cached_property @@ -28,7 +29,7 @@ class CsvFile(File): Public """ - def __init__(self, app, session, file_info, host_url=None, external_endpoint=None, custom_uri=None): + def __init__(self, app, session, file_info, host_url=None, external_endpoint=None, custom_uri=None, external_graph=None): """init Parameters @@ -42,7 +43,7 @@ def __init__(self, app, session, file_info, host_url=None, external_endpoint=Non host_url : None, optional AskOmics url """ - File.__init__(self, app, session, file_info, host_url, external_endpoint=external_endpoint, custom_uri=custom_uri) + File.__init__(self, app, session, file_info, host_url, external_endpoint=external_endpoint, custom_uri=custom_uri, external_graph=external_graph) self.preview_limit = 30 try: self.preview_limit = self.settings.getint("askomics", "npreview") @@ -191,8 +192,12 @@ def guess_column_type(self, values, header_index): if self.header[header_index].find("@") > 0: return "general_relation" + # If it matches "label" + if header_index == 1 and re.match(r".*label.*", self.header[header_index].lower(), re.IGNORECASE) is not None: + return "label" + special_types = { - 'reference': ('chr', 'ref'), + 'reference': ('chr', 'ref', 'scaff'), 'strand': ('strand', ), 'start': ('start', 'begin'), 'end': ('end', 'stop'), @@ -295,7 +300,7 @@ def is_date(value): try: parser.parse(value, dayfirst=True).date() return True - except parser.ParserError: + except Exception: return False @property @@ -357,8 +362,7 @@ def set_rdf_abstraction_domain_knowledge(self): def set_rdf_domain_knowledge(self): """Set the domain knowledge""" for index, attribute in enumerate(self.header): - - if self.columns_type[index] in ('category', 'reference', 'strand'): + if self.columns_type[index] in ('category', 'reference', 'strand') and self.header[index] in self.category_values: s = self.namespace_data["{}Category".format(self.format_uri(attribute, remove_space=True))] p = self.namespace_internal["category"] for value in self.category_values[self.header[index]]: @@ -392,6 +396,11 @@ def set_rdf_abstraction(self): if self.columns_type[0] == 'start_entity': self.graph_abstraction_dk.add((entity, rdflib.RDF.type, self.namespace_internal['startPoint'])) + available_ontologies = {} + for ontology in OntologyManager(self.app, self.session).list_ontologies(): + available_ontologies[ontology['short_name']] = ontology['uri'] + attribute_blanks = {} + # Attributes and relations for index, attribute_name in enumerate(self.header): @@ -401,6 +410,11 @@ def set_rdf_abstraction(self): if index == 0: continue + # Skip label for second column + if self.columns_type[index] == "label" and index == 1: + continue + + blank = BNode() # Relation if self.columns_type[index] in ('general_relation', 'symetric_relation'): symetric_relation = True if self.columns_type[index] == 'symetric_relation' else False @@ -410,7 +424,45 @@ def set_rdf_abstraction(self): label = rdflib.Literal(splitted[0]) rdf_range = self.rdfize(splitted[1]) rdf_type = rdflib.OWL.ObjectProperty - self.graph_abstraction_dk.add((attribute, rdflib.RDF.type, self.namespace_internal["AskomicsRelation"])) + + # New way of storing relations (starting from 4.4.0) + + endpoint = rdflib.Literal(self.external_endpoint) if self.external_endpoint else rdflib.Literal(self.settings.get('triplestore', 'endpoint')) + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, rdflib.OWL.ObjectProperty)) + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, self.namespace_internal["AskomicsRelation"])) + self.graph_abstraction_dk.add((blank, self.namespace_internal["uri"], attribute)) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.label, label)) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.domain, entity)) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.range, rdf_range)) + self.graph_abstraction_dk.add((blank, rdflib.DCAT.endpointURL, endpoint)) + self.graph_abstraction_dk.add((blank, rdflib.DCAT.dataset, rdflib.Literal(self.name))) + if symetric_relation: + self.graph_abstraction_dk.add((blank, rdflib.RDFS.domain, rdf_range)) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.range, entity)) + + continue + + # Manage ontologies + if self.columns_type[index] in available_ontologies: + + attribute = self.rdfize(attribute_name) + label = rdflib.Literal(attribute_name) + rdf_range = self.rdfize(available_ontologies[self.columns_type[index]]) + rdf_type = rdflib.OWL.ObjectProperty + + # New way of storing relations (starting from 4.4.0) + blank = BNode() + endpoint = rdflib.Literal(self.external_endpoint) if self.external_endpoint else rdflib.Literal(self.settings.get('triplestore', 'endpoint')) + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, rdflib.OWL.ObjectProperty)) + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, self.namespace_internal["AskomicsRelation"])) + self.graph_abstraction_dk.add((blank, self.namespace_internal["uri"], attribute)) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.label, label)) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.domain, entity)) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.range, rdf_range)) + self.graph_abstraction_dk.add((blank, rdflib.DCAT.endpointURL, endpoint)) + self.graph_abstraction_dk.add((blank, rdflib.DCAT.dataset, rdflib.Literal(self.name))) + + continue # Category elif self.columns_type[index] in ('category', 'reference', 'strand'): @@ -418,7 +470,7 @@ def set_rdf_abstraction(self): label = rdflib.Literal(attribute_name) rdf_range = self.namespace_data["{}Category".format(self.format_uri(attribute_name, remove_space=True))] rdf_type = rdflib.OWL.ObjectProperty - self.graph_abstraction_dk.add((attribute, rdflib.RDF.type, self.namespace_internal["AskomicsCategory"])) + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, self.namespace_internal["AskomicsCategory"])) # Numeric elif self.columns_type[index] in ('numeric', 'start', 'end'): @@ -448,19 +500,22 @@ def set_rdf_abstraction(self): rdf_range = rdflib.XSD.string rdf_type = rdflib.OWL.DatatypeProperty - self.graph_abstraction_dk.add((attribute, rdflib.RDF.type, rdf_type)) - self.graph_abstraction_dk.add((attribute, rdflib.RDFS.label, label)) - self.graph_abstraction_dk.add((attribute, rdflib.RDFS.domain, entity)) - self.graph_abstraction_dk.add((attribute, rdflib.RDFS.range, rdf_range)) - if symetric_relation: - self.graph_abstraction_dk.add((attribute, rdflib.RDFS.domain, rdf_range)) - self.graph_abstraction_dk.add((attribute, rdflib.RDFS.range, entity)) + attribute_blanks[attribute] = blank + + # New way of storing attributes (starting from 4.4.0) + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, rdf_type)) + self.graph_abstraction_dk.add((blank, self.namespace_internal["uri"], attribute)) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.label, label)) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.domain, entity)) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.range, rdf_range)) # Faldo: if self.faldo_entity: for key, value in self.faldo_abstraction.items(): if value: - self.graph_abstraction_dk.add((value, rdflib.RDF.type, self.faldo_abstraction_eq[key])) + blank = attribute_blanks[value] + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, self.faldo_abstraction_eq[key])) + self.graph_abstraction_dk.add((blank, self.namespace_internal["uri"], value)) def generate_rdf_content(self): """Generator of the rdf content @@ -472,6 +527,10 @@ def generate_rdf_content(self): """ total_lines = sum(1 for line in open(self.path)) + available_ontologies = {} + for ontology in OntologyManager(self.app, self.session).list_ontologies(): + available_ontologies[ontology['short_name']] = ontology['uri'] + with open(self.path, 'r', encoding='utf-8') as file: reader = csv.reader(file, dialect=self.dialect) @@ -489,6 +548,11 @@ def generate_rdf_content(self): # Faldo self.faldo_entity = True if 'start' in self.columns_type and 'end' in self.columns_type else False + has_label = None + # Get first value, ignore others + if "label" in self.columns_type and self.columns_type.index("label") == 1: + has_label = True + # Loop on lines for row_number, row in enumerate(reader): @@ -501,7 +565,10 @@ def generate_rdf_content(self): # Entity entity = self.rdfize(row[0], custom_namespace=self.namespace_entity) - label = self.get_uri_label(row[0]) + if has_label and row[1]: + label = row[1] + else: + label = self.get_uri_label(row[0]) self.graph_chunk.add((entity, rdflib.RDF.type, entity_type)) self.graph_chunk.add((entity, rdflib.RDFS.label, rdflib.Literal(label))) @@ -525,6 +592,11 @@ def generate_rdf_content(self): relation = None symetric_relation = False + # Skip label type for second column + # if type is label but not second column, default to string + if current_type == "label" and column_number == 1: + continue + # Skip entity and blank cells if column_number == 0 or (not cell and not current_type == "strand"): continue @@ -536,6 +608,12 @@ def generate_rdf_content(self): relation = self.rdfize(splitted[0]) attribute = self.rdfize(cell) + # Ontology + elif current_type in available_ontologies: + symetric_relation = False + relation = self.rdfize(current_header) + attribute = self.rdfize(cell) + # Category elif current_type in ('category', 'reference', 'strand'): potential_relation = self.rdfize(current_header) @@ -583,7 +661,7 @@ def generate_rdf_content(self): elif current_type == "date": relation = self.rdfize(current_header) - attribute = rdflib.Literal(self.convert_type(cell)) + attribute = rdflib.Literal(self.convert_type(cell, try_date=True)) # default is text else: diff --git a/askomics/libaskomics/Database.py b/askomics/libaskomics/Database.py index 5afadeae..9fc02acb 100644 --- a/askomics/libaskomics/Database.py +++ b/askomics/libaskomics/Database.py @@ -76,6 +76,8 @@ def init_database(self): self.create_files_table() self.create_datasets_table() self.create_abstraction_table() + self.create_prefixes_table() + self.create_ontologies_table() def create_user_table(self): """Create the user table""" @@ -196,6 +198,39 @@ def update_datasets_table(self): except Exception: pass + query = ''' + ALTER TABLE datasets + ADD ontology boolean NULL + DEFAULT(0) + ''' + + try: + self.execute_sql_query(query) + except Exception: + pass + + query = ''' + ALTER TABLE datasets + ADD endpoint text NULL + DEFAULT(null) + ''' + + try: + self.execute_sql_query(query) + except Exception: + pass + + query = ''' + ALTER TABLE datasets + ADD remote_graph text NULL + DEFAULT(null) + ''' + + try: + self.execute_sql_query(query) + except Exception: + pass + def create_integration_table(self): """Create the integration table""" query = ''' @@ -350,6 +385,28 @@ def create_files_table(self): ''' self.execute_sql_query(query) + query = ''' + ALTER TABLE files + ADD status text NOT NULL + DEFAULT('available') + ''' + + try: + self.execute_sql_query(query) + except Exception: + pass + + query = ''' + ALTER TABLE files + ADD task_id text NULL + DEFAULT(NULL) + ''' + + try: + self.execute_sql_query(query) + except Exception: + pass + def create_abstraction_table(self): """Create abstraction table""" query = """ @@ -361,3 +418,61 @@ def create_abstraction_table(self): ) """ self.execute_sql_query(query) + + def create_prefixes_table(self): + """Create the prefix table""" + query = ''' + CREATE TABLE IF NOT EXISTS prefixes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + prefix text NOT NULL, + namespace text NOT NULL + ) + ''' + self.execute_sql_query(query) + + def create_ontologies_table(self): + """Create the ontologies table""" + query = ''' + CREATE TABLE IF NOT EXISTS ontologies ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name text NOT NULL, + uri text NOT NULL, + short_name text NOT NULL, + type text DEFAULT 'sparql', + dataset_id INTEGER NOT NULL, + graph text NOT NULL, + FOREIGN KEY(dataset_id) REFERENCES datasets(id) + ) + ''' + self.execute_sql_query(query) + + query = ''' + ALTER TABLE ontologies + ADD label_uri text NOT NULL + DEFAULT('rdfs:label') + ''' + + try: + self.execute_sql_query(query) + except Exception: + pass + + query = ''' + ALTER TABLE ontologies + ADD endpoint text NULL + ''' + + try: + self.execute_sql_query(query) + except Exception: + pass + + query = ''' + ALTER TABLE ontologies + ADD remote_graph text NULL + ''' + + try: + self.execute_sql_query(query) + except Exception: + pass diff --git a/askomics/libaskomics/Dataset.py b/askomics/libaskomics/Dataset.py index 927f4896..c3fd7b1b 100644 --- a/askomics/libaskomics/Dataset.py +++ b/askomics/libaskomics/Dataset.py @@ -45,6 +45,9 @@ def __init__(self, app, session, dataset_info={}): self.public = dataset_info["public"] if "public" in dataset_info else False self.start = dataset_info["start"] if "start" in dataset_info else None self.end = dataset_info["end"] if "end" in dataset_info else None + self.ontology = dataset_info["ontology"] if "ontology" in dataset_info else False + self.endpoint = dataset_info["endpoint"] if "endpoint" in dataset_info else False + self.remote_graph = dataset_info["remote_graph"] if "remote_graph" in dataset_info else False def set_info_from_db(self, admin=False): """Set the info in from the database""" @@ -58,7 +61,7 @@ def set_info_from_db(self, admin=False): where_query = "AND user_id = ?" query = ''' - SELECT celery_id, file_id, name, graph_name, public, start, end + SELECT celery_id, file_id, name, graph_name, public, start, end, ontology, endpoint, remote_graph FROM datasets WHERE id = ? {} @@ -73,11 +76,40 @@ def set_info_from_db(self, admin=False): self.public = rows[0][4] self.start = rows[0][5] self.end = rows[0][6] + self.ontology = rows[0][7] + self.endpoint = rows[0][8] + self.remote_graph = rows[0][9] - def save_in_db(self): + def save_in_db(self, endpoint, remote_graph=None, set_graph=False): """Save the dataset into the database""" database = Database(self.app, self.session) + subquery = "NULL" + args = ( + self.session["user"]["id"], + self.celery_id, + self.file_id, + self.name, + self.public, + 0, + endpoint, + remote_graph + ) + + if set_graph: + subquery = "?" + args = ( + self.session["user"]["id"], + self.celery_id, + self.file_id, + self.name, + self.graph_name, + self.public, + 0, + endpoint, + remote_graph + ) + query = ''' INSERT INTO datasets VALUES( NULL, @@ -85,7 +117,7 @@ def save_in_db(self): ?, ?, ?, - NULL, + {}, ?, "queued", strftime('%s', 'now'), @@ -93,18 +125,14 @@ def save_in_db(self): ?, NULL, NULL, - NULL + NULL, + 0, + ?, + ? ) - ''' + '''.format(subquery) - self.id = database.execute_sql_query(query, ( - self.session["user"]["id"], - self.celery_id, - self.file_id, - self.name, - self.public, - 0 - ), get_id=True) + self.id = database.execute_sql_query(query, args, get_id=True) def toggle_public(self, new_status, admin=False): """Change public status of a dataset (triplestore and db) @@ -228,3 +256,10 @@ def delete_from_db(self, admin=False): '''.format(where_query) database.execute_sql_query(query, query_params) + + query = ''' + DELETE FROM ontologies + WHERE dataset_id = ? + ''' + + database.execute_sql_query(query, (self.id,)) diff --git a/askomics/libaskomics/DatasetsHandler.py b/askomics/libaskomics/DatasetsHandler.py index 332dfc80..cdd1d172 100644 --- a/askomics/libaskomics/DatasetsHandler.py +++ b/askomics/libaskomics/DatasetsHandler.py @@ -51,7 +51,7 @@ def get_datasets(self): database = Database(self.app, self.session) query = ''' - SELECT id, name, public, status, start, end, ntriples, error_message, traceback, percent + SELECT id, name, public, status, start, end, ntriples, error_message, traceback, percent, ontology FROM datasets WHERE user_id = ? ''' @@ -76,7 +76,8 @@ def get_datasets(self): 'ntriples': row[6], 'error_message': row[7], 'traceback': row[8], - 'percent': row[9] + 'percent': row[9], + 'ontology': row[10] } datasets.append(dataset) @@ -97,7 +98,7 @@ def get_all_datasets(self): database = Database(self.app, self.session) query = ''' - SELECT datasets.id, datasets.name, datasets.public, datasets.status, datasets.start, datasets.end, datasets.ntriples, datasets.error_message, datasets.traceback, datasets.percent, users.username + SELECT datasets.id, datasets.name, datasets.public, datasets.status, datasets.start, datasets.end, datasets.ntriples, datasets.error_message, datasets.traceback, datasets.percent, users.username, datasets.ontology FROM datasets INNER JOIN users ON datasets.user_id=users.user_id ''' @@ -123,7 +124,8 @@ def get_all_datasets(self): 'error_message': row[7], 'traceback': row[8], 'percent': row[9], - 'user': row[10] + 'user': row[10], + 'ontology': row[11] } datasets.append(dataset) diff --git a/askomics/libaskomics/File.py b/askomics/libaskomics/File.py index 24292fa8..030f30e3 100644 --- a/askomics/libaskomics/File.py +++ b/askomics/libaskomics/File.py @@ -69,7 +69,7 @@ class File(Params): User graph """ - def __init__(self, app, session, file_info, host_url=None, external_endpoint=None, custom_uri=None): + def __init__(self, app, session, file_info, host_url=None, external_endpoint=None, custom_uri=None, external_graph=None): """init Parameters @@ -97,6 +97,7 @@ def __init__(self, app, session, file_info, host_url=None, external_endpoint=Non self.ntriples = 0 self.timestamp = int(time.time()) self.external_endpoint = external_endpoint + self.external_graph = external_graph self.default_graph = "{}".format(self.settings.get('triplestore', 'default_graph')) self.user_graph = "{}:{}_{}".format( @@ -130,6 +131,7 @@ def __init__(self, app, session, file_info, host_url=None, external_endpoint=Non self.faldo = Namespace('http://biohackathon.org/resource/faldo/') self.prov = Namespace('http://www.w3.org/ns/prov#') self.dc = Namespace('http://purl.org/dc/elements/1.1/') + self.dcat = Namespace('http://www.w3.org/ns/dcat#') self.faldo_entity = False self.faldo_abstraction = { @@ -277,6 +279,8 @@ def set_metadata(self): self.graph_metadata.add((rdflib.Literal(self.file_graph), self.prov.wasDerivedFrom, rdflib.Literal(self.name))) self.graph_metadata.add((rdflib.Literal(self.file_graph), self.dc.hasVersion, rdflib.Literal(get_distribution('askomics').version))) self.graph_metadata.add((rdflib.Literal(self.file_graph), self.prov.describesService, rdflib.Literal(os.uname()[1]))) + if self.external_graph: + self.graph_metadata.add((rdflib.Literal(self.file_graph), self.dcat.Dataset, rdflib.Literal(self.external_graph))) if self.public: self.graph_metadata.add((rdflib.Literal(self.file_graph), self.namespace_internal['public'], rdflib.Literal(True))) @@ -461,7 +465,7 @@ def get_rdf_type(self, value): return rdflib.XSD.string - def convert_type(self, value): + def convert_type(self, value, try_date=False): """Convert a value to a date, an int or float or text Parameters @@ -480,9 +484,11 @@ def convert_type(self, value): try: return float(value) except ValueError: + if not try_date: + return value try: return parser.parse(value, dayfirst=True).date() - except parser.ParserError: + except Exception: return value return value diff --git a/askomics/libaskomics/FilesHandler.py b/askomics/libaskomics/FilesHandler.py index 54bc495c..04254028 100644 --- a/askomics/libaskomics/FilesHandler.py +++ b/askomics/libaskomics/FilesHandler.py @@ -24,7 +24,7 @@ class FilesHandler(FilesUtils): Upload path """ - def __init__(self, app, session, host_url=None, external_endpoint=None, custom_uri=None): + def __init__(self, app, session, host_url=None, external_endpoint=None, custom_uri=None, external_graph=None): """init Parameters @@ -47,6 +47,7 @@ def __init__(self, app, session, host_url=None, external_endpoint=None, custom_u self.date = None self.external_endpoint = external_endpoint self.custom_uri = custom_uri + self.external_graph = external_graph def handle_files(self, files_id): """Handle file @@ -60,13 +61,13 @@ def handle_files(self, files_id): for file in files_infos: if file['type'] == 'csv/tsv': - self.files.append(CsvFile(self.app, self.session, file, host_url=self.host_url, external_endpoint=self.external_endpoint, custom_uri=self.custom_uri)) + self.files.append(CsvFile(self.app, self.session, file, host_url=self.host_url, external_endpoint=self.external_endpoint, custom_uri=self.custom_uri, external_graph=self.external_graph)) elif file['type'] == 'gff/gff3': - self.files.append(GffFile(self.app, self.session, file, host_url=self.host_url, external_endpoint=self.external_endpoint, custom_uri=self.custom_uri)) + self.files.append(GffFile(self.app, self.session, file, host_url=self.host_url, external_endpoint=self.external_endpoint, custom_uri=self.custom_uri, external_graph=self.external_graph)) elif file['type'] in ('rdf/ttl', 'rdf/xml', 'rdf/nt'): - self.files.append(RdfFile(self.app, self.session, file, host_url=self.host_url, external_endpoint=self.external_endpoint, custom_uri=self.custom_uri)) + self.files.append(RdfFile(self.app, self.session, file, host_url=self.host_url, external_endpoint=self.external_endpoint, custom_uri=self.custom_uri, external_graph=self.external_graph)) elif file['type'] == 'bed': - self.files.append(BedFile(self.app, self.session, file, host_url=self.host_url, external_endpoint=self.external_endpoint, custom_uri=self.custom_uri)) + self.files.append(BedFile(self.app, self.session, file, host_url=self.host_url, external_endpoint=self.external_endpoint, custom_uri=self.custom_uri, external_graph=self.external_graph)) def get_files_infos(self, files_id=None, files_path=None, return_path=False): """Get files info @@ -89,7 +90,7 @@ def get_files_infos(self, files_id=None, files_path=None, return_path=False): subquery_str = '(' + ' OR '.join(['id = ?'] * len(files_id)) + ')' query = ''' - SELECT id, name, type, size, path, date + SELECT id, name, type, size, path, date, status FROM files WHERE user_id = ? AND {} @@ -101,7 +102,7 @@ def get_files_infos(self, files_id=None, files_path=None, return_path=False): subquery_str = '(' + ' OR '.join(['path = ?'] * len(files_path)) + ')' query = ''' - SELECT id, name, type, size, path, date + SELECT id, name, type, size, path, date, status FROM files WHERE user_id = ? AND {} @@ -112,7 +113,7 @@ def get_files_infos(self, files_id=None, files_path=None, return_path=False): else: query = ''' - SELECT id, name, type, size, path, date + SELECT id, name, type, size, path, date, status FROM files WHERE user_id = ? ''' @@ -126,7 +127,8 @@ def get_files_infos(self, files_id=None, files_path=None, return_path=False): 'name': row[1], 'type': row[2], 'size': row[3], - 'date': row[5] + 'date': row[5], + 'status': row[6] } if return_path: file['path'] = row[4] @@ -142,7 +144,7 @@ def get_all_files_infos(self): database = Database(self.app, self.session) query = ''' - SELECT files.id, files.name, files.type, files.size, files.date, users.username + SELECT files.id, files.name, files.type, files.size, files.date, files.status, users.username FROM files INNER JOIN users ON files.user_id=users.user_id ''' @@ -157,7 +159,8 @@ def get_all_files_infos(self): 'type': row[2], 'size': row[3], 'date': row[4], - 'user': row[5] + 'status': row[5], + 'user': row[6] } files.append(file) @@ -203,7 +206,7 @@ def write_data_into_file(self, data, file_name, mode, should_exist=False): with open(file_path, mode) as file: file.write(data) - def store_file_info_in_db(self, name, filetype, file_name, size): + def store_file_info_in_db(self, name, filetype, file_name, size, status="available", task_id=None): """Store the file info in the database Parameters @@ -216,6 +219,12 @@ def store_file_info_in_db(self, name, filetype, file_name, size): Local file name size : string Size of file + status: string + Status of the file (downloading, available, unavailable) + Returns + ------- + str + file id """ file_path = "{}/{}".format(self.upload_path, file_name) @@ -228,6 +237,8 @@ def store_file_info_in_db(self, name, filetype, file_name, size): ?, ?, ?, + ?, + ?, ? ) ''' @@ -237,7 +248,7 @@ def store_file_info_in_db(self, name, filetype, file_name, size): filetype = 'csv/tsv' elif filetype in ('text/turtle', 'ttl'): filetype = 'rdf/ttl' - elif filetype == "text/xml": + elif filetype in ["text/xml", "application/rdf+xml"]: filetype = "rdf/xml" elif filetype == "application/n-triples": filetype = "rdf/nt" @@ -248,7 +259,57 @@ def store_file_info_in_db(self, name, filetype, file_name, size): self.date = int(time.time()) - database.execute_sql_query(query, (self.session['user']['id'], name, filetype, file_path, size, self.date)) + return database.execute_sql_query(query, (self.session['user']['id'], name, filetype, file_path, size, self.date, status, task_id), get_id=True) + + def update_file_info(self, file_id, size=None, status="", task_id=""): + """Update file size and status + + Parameters + ---------- + file_id : str + File id + file_size : str + File current size + status : str + File status + task_id : str + Current task id + """ + + if not (size is not None or status or task_id): + return + + query_vars = [] + database = Database(self.app, self.session) + + size_query = "" + status_query = "" + task_query = "" + + # Should be a cleaner way of doing this... + if size is not None: + size_query = "size=?," if (status or task_id) else "size=?" + query_vars.append(size) + + if status: + status_query = "status=?," if task_id else "status=?" + query_vars.append(status) + + if task_id: + task_query = "task_id=?" + query_vars.append(task_id) + + query_vars.append(file_id) + + query = ''' + UPDATE files SET + {} + {} + {} + WHERE id=? + '''.format(size_query, status_query, task_query) + + database.execute_sql_query(query, tuple(query_vars)) def persist_chunk(self, chunk_info): """Persist a file by chunk. Store info in db if the chunk is the last @@ -297,7 +358,7 @@ def persist_chunk(self, chunk_info): pass raise(e) - def download_url(self, url): + def download_url(self, url, task_id): """Download a file from an URL and insert info in database Parameters @@ -309,14 +370,33 @@ def download_url(self, url): name = url.split("/")[-1] file_name = self.get_file_name() path = "{}/{}".format(self.upload_path, file_name) + file_id = self.store_file_info_in_db(name, "", file_name, 0, "downloading", task_id) # Get file - req = requests.get(url) - with open(path, 'wb') as file: - file.write(req.content) - - # insert in db - self.store_file_info_in_db(name, "", file_name, os.path.getsize(path)) + try: + with requests.get(url, stream=True) as r: + r.raise_for_status() + count = 0 + with open(path, 'wb') as file: + for chunk in r.iter_content(chunk_size=1024 * 1024 * 10): + # Update size every ~1GO + # + Check quota + if count == 100: + if self.session['user']['quota'] > 0: + total_size = self.get_size_occupied_by_user() + os.path.getsize(path) + if total_size >= self.session['user']['quota']: + raise Exception("Exceeded quota") + self.update_file_info(file_id, size=os.path.getsize(path)) + count = 0 + + file.write(chunk) + count += 1 + + # Update final value + self.update_file_info(file_id, size=os.path.getsize(path), status="available") + + except Exception: + self.update_file_info(file_id, size=os.path.getsize(path), status="error") def get_type(self, file_ext): """Get files type, based on extension diff --git a/askomics/libaskomics/GffFile.py b/askomics/libaskomics/GffFile.py index 102691b4..7c413de7 100644 --- a/askomics/libaskomics/GffFile.py +++ b/askomics/libaskomics/GffFile.py @@ -18,7 +18,7 @@ class GffFile(File): Public or private dataset """ - def __init__(self, app, session, file_info, host_url=None, external_endpoint=None, custom_uri=None): + def __init__(self, app, session, file_info, host_url=None, external_endpoint=None, custom_uri=None, external_graph=None): """init Parameters @@ -32,7 +32,7 @@ def __init__(self, app, session, file_info, host_url=None, external_endpoint=Non host_url : None, optional AskOmics url """ - File.__init__(self, app, session, file_info, host_url, external_endpoint=external_endpoint, custom_uri=custom_uri) + File.__init__(self, app, session, file_info, host_url, external_endpoint=external_endpoint, custom_uri=custom_uri, external_graph=external_graph) self.entities = [] self.entities_to_integrate = [] @@ -108,13 +108,32 @@ def set_rdf_abstraction_domain_knowledge(self): self.graph_abstraction_dk.add((self.namespace_data[self.format_uri(entity, remove_space=True)], rdflib.RDF.type, rdflib.OWL["Class"])) self.graph_abstraction_dk.add((self.namespace_data[self.format_uri(entity, remove_space=True)], rdflib.RDFS.label, rdflib.Literal(entity))) - for attribute in self.attribute_abstraction: - for attr_type in attribute["type"]: - self.graph_abstraction_dk.add((attribute["uri"], rdflib.RDF.type, attr_type)) - self.graph_abstraction_dk.add((attribute["uri"], rdflib.RDFS.label, attribute["label"])) - self.graph_abstraction_dk.add((attribute["uri"], rdflib.RDFS.domain, attribute["domain"])) - self.graph_abstraction_dk.add((attribute["uri"], rdflib.RDFS.range, attribute["range"])) + attribute_blanks = {} + for attribute in self.attribute_abstraction: + blank = BNode() + # New way of storing relations (starting from 4.4.0) + if attribute.get("relation"): + endpoint = rdflib.Literal(self.external_endpoint) if self.external_endpoint else rdflib.Literal(self.settings.get('triplestore', 'endpoint')) + for attr_type in attribute["type"]: + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, attr_type)) + self.graph_abstraction_dk.add((blank, self.namespace_internal["uri"], attribute["uri"])) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.label, attribute["label"])) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.domain, attribute["domain"])) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.range, attribute["range"])) + self.graph_abstraction_dk.add((blank, rdflib.DCAT.endpointURL, endpoint)) + self.graph_abstraction_dk.add((blank, rdflib.DCAT.dataset, rdflib.Literal(self.name))) + + else: + # New way of storing attributes (starting from 4.4.0) + for attr_type in attribute["type"]: + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, attr_type)) + self.graph_abstraction_dk.add((blank, self.namespace_internal["uri"], attribute["uri"])) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.label, attribute["label"])) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.domain, attribute["domain"])) + self.graph_abstraction_dk.add((blank, rdflib.RDFS.range, attribute["range"])) + + attribute_blanks[attribute["uri"]] = blank # Domain Knowledge if "values" in attribute.keys(): for value in attribute["values"]: @@ -129,7 +148,9 @@ def set_rdf_abstraction_domain_knowledge(self): if self.faldo_entity: for key, value in self.faldo_abstraction.items(): if value: - self.graph_abstraction_dk.add((value, rdflib.RDF.type, self.faldo_abstraction_eq[key])) + blank = attribute_blanks[value] + self.graph_abstraction_dk.add((blank, rdflib.RDF.type, self.faldo_abstraction_eq[key])) + self.graph_abstraction_dk.add((blank, self.namespace_internal["uri"], value)) def format_gff_entity(self, entity): """Format a gff entity name by removing type (type:entity --> entity) @@ -182,7 +203,7 @@ def generate_rdf_content(self): faldo_strand = None faldo_start = None faldo_end = None - + strand_type = None # Entity if not feature.id: if "ID" not in feature.qualifiers.keys(): @@ -272,6 +293,7 @@ def generate_rdf_content(self): attribute = self.namespace_data[self.format_uri("+")] faldo_strand = self.get_faldo_strand("+") self.faldo_abstraction["strand"] = relation + strand_type = "+" # self.graph_chunk.add((entity, relation, attribute)) elif feature.location.strand == -1: self.category_values["strand"] = {"-", } @@ -279,6 +301,7 @@ def generate_rdf_content(self): attribute = self.namespace_data[self.format_uri("-")] faldo_strand = self.get_faldo_strand("-") self.faldo_abstraction["strand"] = relation + strand_type = "-" # self.graph_chunk.add((entity, relation, attribute)) else: self.category_values["strand"] = {".", } @@ -286,16 +309,17 @@ def generate_rdf_content(self): attribute = self.namespace_data[self.format_uri(".")] faldo_strand = self.get_faldo_strand(".") self.faldo_abstraction["strand"] = relation + strand_type = "." - if (feature.type, "strand") not in attribute_list: - attribute_list.append((feature.type, "strand")) + if (feature.type, "strand", strand_type) not in attribute_list: + attribute_list.append((feature.type, "strand", strand_type)) self.attribute_abstraction.append({ "uri": self.namespace_data[self.format_uri("strand")], "label": rdflib.Literal("strand"), "type": [self.namespace_internal[self.format_uri("AskomicsCategory")], rdflib.OWL.ObjectProperty], "domain": entity_type, "range": self.namespace_data[self.format_uri("{}Category".format("strand"))], - "values": ["+", "-", "."] + "values": [strand_type] }) # Qualifiers (9th columns) @@ -319,7 +343,8 @@ def generate_rdf_content(self): "domain": entity_type, "range": value, "qualifier_key": qualifier_key, - "feature_type": feature.type + "feature_type": feature.type, + "relation": True }) skip = True else: @@ -336,7 +361,8 @@ def generate_rdf_content(self): "label": rdflib.Literal(qualifier_key), "type": [rdflib.OWL.ObjectProperty, self.namespace_internal[self.format_uri("AskomicsRelation")]], "domain": entity_type, - "range": self.namespace_data[self.format_uri(related_type)] + "range": self.namespace_data[self.format_uri(related_type)], + "relation": True }) else: diff --git a/askomics/libaskomics/LocalAuth.py b/askomics/libaskomics/LocalAuth.py index 4759cedb..a1bf0c4f 100644 --- a/askomics/libaskomics/LocalAuth.py +++ b/askomics/libaskomics/LocalAuth.py @@ -1044,22 +1044,21 @@ def send_mail_to_new_user(self, user): mailer = Mailer(self.app, self.session) if mailer.check_mailer(): body = textwrap.dedent(""" - Welcome {username}! + Dear {username}! - We heard that administrators of {url} create an account for you. + An account with this email adress was created by the administrators of {url}. - To use it, use the following link to create your password. Then, login with you email adress ({email}) or username ({username}). + To use it, please use the following link to create your password. You will then be able to log in with your username ({username}). {url}/password_reset?token={token} - If you don’t use this link within 3 hours, it will expire. To get a new password creation link, visit {url}/password_reset + This link will expire after 3 hours. To get a new password creation link, please visit {url}/password_reset Thanks, The AskOmics Team """.format( username=user["username"], - email=user["email"], url=self.settings.get('askomics', 'instance_url'), token=token )) @@ -1104,16 +1103,17 @@ def send_reset_link(self, login): body = textwrap.dedent(""" Dear {user}, - We heard that you lost your AskOmics password. Sorry about that! + A password reset request has been received for your {url} account. - But don’t worry! You can use the following link to reset your password: + If you did not initiate this request, feel free to ignore this message. - {url}/password_reset?token={token} + You can use the following link to reset your password: - If you don’t use this link within 3 hours, it will expire. To get a new password reset link, visit {url}/password_reset + {url}/password_reset?token={token} + This link will expire after 3 hours. To get a new password reset link, please visit {url}/password_reset - Thanks, + Best regards, The AskOmics Team """.format( diff --git a/askomics/libaskomics/OntologyManager.py b/askomics/libaskomics/OntologyManager.py new file mode 100644 index 00000000..eed16a87 --- /dev/null +++ b/askomics/libaskomics/OntologyManager.py @@ -0,0 +1,279 @@ +import requests + +from collections import defaultdict +from urllib.parse import quote_plus + + +from askomics.libaskomics.Database import Database +from askomics.libaskomics.Params import Params + + +class OntologyManager(Params): + """Manage ontologies + + Attributes + ---------- + namespace_internal : str + askomics namespace, from config file + namespace_data : str + askomics prefix, from config file + prefix : dict + dict of all prefixes + """ + + def __init__(self, app, session): + """init + + Parameters + ---------- + app : Flask + Flask app + session : + AskOmics session + """ + Params.__init__(self, app, session) + + def list_ontologies(self): + """Get all ontologies + + Returns + ------- + list + ontologies + """ + + database = Database(self.app, self.session) + + query = ''' + SELECT id, name, uri, short_name, type + FROM ontologies + ''' + + rows = database.execute_sql_query(query) + + ontologies = [] + for row in rows: + prefix = { + 'id': row[0], + 'name': row[1], + 'uri': row[2], + 'short_name': row[3], + 'type': row[4] + } + ontologies.append(prefix) + + return ontologies + + def list_full_ontologies(self): + """Get all ontologies for admin + + Returns + ------- + list + ontologies + """ + + database = Database(self.app, self.session) + + query = ''' + SELECT ontologies.id, ontologies.name, ontologies.uri, ontologies.short_name, ontologies.type, ontologies.label_uri, datasets.id, datasets.name, ontologies.graph, ontologies.endpoint, ontologies.remote_graph + FROM ontologies + INNER JOIN datasets ON datasets.id=ontologies.dataset_id + ''' + + rows = database.execute_sql_query(query) + + ontologies = [] + for row in rows: + prefix = { + 'id': row[0], + 'name': row[1], + 'uri': row[2], + 'short_name': row[3], + 'type': row[4], + 'label_uri': row[5], + 'dataset_id': row[6], + 'dataset_name': row[7], + 'graph': row[8], + 'endpoint': row[9], + 'remote_graph': row[10] + } + ontologies.append(prefix) + + return ontologies + + def get_ontology(self, short_name="", uri=""): + """Get a specific ontology based on short name or uri + + Returns + ------- + dict + ontology + """ + + if not (short_name or uri): + return None + + if short_name: + where_clause = "WHERE short_name = ?" + args = (short_name,) + + if uri: + where_clause = "WHERE uri = ?" + args = (uri,) + + database = Database(self.app, self.session) + + query = ''' + SELECT id, name, uri, short_name, type, dataset_id, graph, label_uri, endpoint, remote_graph + FROM ontologies + {} + '''.format(where_clause) + + rows = database.execute_sql_query(query, args) + + if not rows: + return None + + ontology = rows[0] + return { + 'id': ontology[0], + 'name': ontology[1], + 'uri': ontology[2], + 'short_name': ontology[3], + 'type': ontology[4], + 'dataset_id': ontology[5], + 'graph': ontology[6], + 'label_uri': ontology[7], + 'endpoint': ontology[8], + 'remote_graph': ontology[9] + } + + def add_ontology(self, name, uri, short_name, dataset_id, graph, endpoint, remote_graph=None, type="local", label_uri="rdfs:label"): + """Create a new ontology + + Returns + ------- + list of dict + Prefixes information + """ + database = Database(self.app, self.session) + if not endpoint: + endpoint = self.settings.get('triplestore', 'endpoint') + + query = ''' + INSERT INTO ontologies VALUES( + NULL, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ? + ) + ''' + + database.execute_sql_query(query, (name, uri, short_name, type, dataset_id, graph, label_uri, endpoint, remote_graph)) + + query = ''' + UPDATE datasets SET + ontology=1 + WHERE id=? + ''' + + database.execute_sql_query(query, (dataset_id,)) + + def remove_ontologies(self, ontology_ids): + """Remove ontologies + + Returns + ------- + None + """ + # Make sure we only remove the 'ontology' tag to datasets without any ontologies + ontologies = self.list_full_ontologies() + datasets = defaultdict(set) + datasets_to_modify = set() + ontos_to_delete = [ontology['id'] for ontology in ontology_ids] + + for onto in ontologies: + datasets[onto['dataset_id']].add(onto['id']) + + for key, values in datasets.items(): + if values.issubset(ontos_to_delete): + datasets_to_modify.add(key) + + database = Database(self.app, self.session) + + query = ''' + DELETE FROM ontologies + WHERE id = ? + ''' + + dataset_query = ''' + UPDATE datasets SET + ontology=0 + WHERE id=? + ''' + + for ontology in ontology_ids: + database.execute_sql_query(query, (ontology['id'],)) + if ontology['dataset_id'] in datasets_to_modify: + database.execute_sql_query(dataset_query, (ontology['dataset_id'],)) + + def test_ols_ontology(self, shortname): + base_url = "https://www.ebi.ac.uk/ols/api/ontologies/" + quote_plus(shortname.lower()) + + r = requests.get(base_url) + return r.status_code == 200 + + def autocomplete(self, ontology_uri, ontology_type, query_term, onto_short_name, onto_graph, onto_endpoint, custom_label, remote_graph): + """Search in ontology + + Returns + ------- + list of dict + Results + """ + # Circular import + from askomics.libaskomics.SparqlQuery import SparqlQuery + max_results = self.settings.getint("askomics", "autocomplete_max_results", fallback=10) + + if ontology_type == "local": + query = SparqlQuery(self.app, self.session, get_graphs=False) + # TODO: Actually store the graph in the ontology to quicken search + query.set_graphs([onto_graph]) + query.set_endpoints(set([self.settings.get('triplestore', 'endpoint'), onto_endpoint])) + if remote_graph: + query.set_remote_graph({onto_endpoint: [remote_graph]}) + + return query.autocomplete_local_ontology(ontology_uri, query_term, max_results, custom_label) + elif ontology_type == "ols": + base_url = "https://www.ebi.ac.uk/ols/api/select" + arguments = { + "q": query_term, + "ontology": quote_plus(onto_short_name.lower()), + "rows": max_results, + "type": "class", + "fieldList": "label" + } + + data = [] + + try: + r = requests.get(base_url, params=arguments, timeout=10) + + if not r.status_code == 200: + return data + + res = r.json() + if res['response']['docs']: + data = [term['label'] for term in res['response']['docs']] + + except requests.exceptions.Timeout: + pass + + return data diff --git a/askomics/libaskomics/PrefixManager.py b/askomics/libaskomics/PrefixManager.py index 3dc71dfc..493fab53 100644 --- a/askomics/libaskomics/PrefixManager.py +++ b/askomics/libaskomics/PrefixManager.py @@ -1,3 +1,4 @@ +from askomics.libaskomics.Database import Database from askomics.libaskomics.Params import Params import rdflib @@ -40,7 +41,9 @@ def __init__(self, app, session): 'rdf:': str(rdflib.RDF), 'rdfs:': str(rdflib.RDFS), 'owl:': str(rdflib.OWL), - 'xsd:': str(rdflib.XSD) + 'xsd:': str(rdflib.XSD), + 'skos:': str(rdflib.SKOS), + 'dcat:': str(rdflib.DCAT) } def get_prefix(self): @@ -79,4 +82,81 @@ def get_namespace(self, prefix): try: return prefix_cc[prefix] except Exception: + prefixes = self.get_custom_prefixes(prefix) + if prefixes: + return prefixes[0]["namespace"] return "" + + def get_custom_prefixes(self, prefix=None): + """Get custom (admin-defined) prefixes + + Returns + ------- + list of dict + Prefixes information + """ + database = Database(self.app, self.session) + + query_args = () + subquery = "" + + if prefix: + query_args = (prefix, ) + subquery = "WHERE prefix = ?" + + query = ''' + SELECT id, prefix, namespace + FROM prefixes + {} + '''.format(subquery) + + rows = database.execute_sql_query(query, query_args) + + prefixes = [] + for row in rows: + prefix = { + 'id': row[0], + 'prefix': row[1], + 'namespace': row[2], + } + prefixes.append(prefix) + + return prefixes + + def add_custom_prefix(self, prefix, namespace): + """Create a new custom (admin-defined) prefixes + + Returns + ------- + list of dict + Prefixes information + """ + database = Database(self.app, self.session) + + query = ''' + INSERT INTO prefixes VALUES( + NULL, + ?, + ? + ) + ''' + + database.execute_sql_query(query, (prefix, namespace,)) + + def remove_custom_prefixes(self, prefixes_id): + """Create a new custom (admin-defined) prefixes + + Returns + ------- + list of dict + Prefixes information + """ + database = Database(self.app, self.session) + + query = ''' + DELETE FROM prefixes + WHERE id = ? + ''' + + for prefix_id in prefixes_id: + database.execute_sql_query(query, (prefix_id,)) diff --git a/askomics/libaskomics/RdfFile.py b/askomics/libaskomics/RdfFile.py index 0954d91f..008bbd3b 100644 --- a/askomics/libaskomics/RdfFile.py +++ b/askomics/libaskomics/RdfFile.py @@ -14,7 +14,7 @@ class RdfFile(File): Public or private dataset """ - def __init__(self, app, session, file_info, host_url=None, external_endpoint=None, custom_uri=None): + def __init__(self, app, session, file_info, host_url=None, external_endpoint=None, custom_uri=None, external_graph=None): """init Parameters @@ -28,7 +28,7 @@ def __init__(self, app, session, file_info, host_url=None, external_endpoint=Non host_url : None, optional AskOmics url """ - File.__init__(self, app, session, file_info, host_url, external_endpoint=external_endpoint, custom_uri=custom_uri) + File.__init__(self, app, session, file_info, host_url, external_endpoint=external_endpoint, custom_uri=custom_uri, external_graph=external_graph) self.type_dict = { "rdf/ttl": "turtle", @@ -40,7 +40,7 @@ def set_preview(self): """Summary""" pass - def get_location(self): + def get_location_and_remote_graph(self): """Get location of data if specified Returns @@ -50,10 +50,19 @@ def get_location(self): """ graph = RdfGraph(self.app, self.session) graph.parse(self.path, format=self.type_dict[self.type]) - triple = (None, self.prov.atLocation, None) - for s, p, o in graph.graph.triples(triple): - return str(o) - return None + triple_loc = (None, self.prov.atLocation, None) + triple_graph = (None, self.dcat.Dataset, None) + loc = None + remote_graph = None + for s, p, o in graph.graph.triples(triple_loc): + loc = str(o) + break + + for s, p, o in graph.graph.triples(triple_graph): + remote_graph = str(o) + break + + return loc, remote_graph def get_preview(self): """Get a preview of the frist 100 lines of a ttl file @@ -69,6 +78,12 @@ def get_preview(self): for x in range(1, 100): head += ttl_file.readline() + location = None + try: + location, remote_graph = self.get_location_and_remote_graph() + except Exception as e: + self.error_message = str(e) + return { 'type': self.type, 'id': self.id, @@ -77,13 +92,15 @@ def get_preview(self): 'error_message': self.error_message, 'data': { 'preview': head, - 'location': self.get_location() + 'location': location, + 'remote_graph': remote_graph } } def delete_metadata_location(self): """Delete metadata from data""" self.graph_chunk.remove((None, self.prov.atLocation, None)) + self.graph_chunk.remove((None, self.dcat.Dataset, None)) def integrate(self, public=False): """Integrate the file into the triplestore diff --git a/askomics/libaskomics/RdfGraph.py b/askomics/libaskomics/RdfGraph.py index 0bd40e0b..0024a3ed 100644 --- a/askomics/libaskomics/RdfGraph.py +++ b/askomics/libaskomics/RdfGraph.py @@ -40,6 +40,7 @@ def __init__(self, app, session): self.graph.bind('faldo', "http://biohackathon.org/resource/faldo/") self.graph.bind('dc', 'http://purl.org/dc/elements/1.1/') self.graph.bind('prov', 'http://www.w3.org/ns/prov#') + self.graph.bind('dcat', 'http://www.w3.org/ns/dcat#') self.ntriple = 0 self.percent = None diff --git a/askomics/libaskomics/Result.py b/askomics/libaskomics/Result.py index 07e74ca5..d48f7725 100644 --- a/askomics/libaskomics/Result.py +++ b/askomics/libaskomics/Result.py @@ -389,6 +389,33 @@ def save_in_db(self): return self.id + def populate_db(self, graphs, endpoints): + """Update status of results in db + + Parameters + ---------- + query : bool, optional + True if error during integration + error_message : bool, optional + Error string if error is True + """ + + database = Database(self.app, self.session) + + query = ''' + UPDATE results SET + graphs_and_endpoints=? + WHERE user_id=? AND id=? + ''' + + variables = [ + json.dumps({"graphs": graphs, "endpoints": endpoints}), + self.session["user"]["id"], + self.id + ] + + database.execute_sql_query(query, tuple(variables)) + def update_public_status(self, public): """Change public status @@ -471,7 +498,7 @@ def update_db_status(self, status, size=None, update_celery=False, update_date=F def rollback(self): """Delete file""" - self.delete_file_from_filesystem(self) + self.delete_file_from_filesystem() def delete_result(self): """Remove results from db and filesystem""" diff --git a/askomics/libaskomics/SparqlQuery.py b/askomics/libaskomics/SparqlQuery.py index ae098b87..57d2c29a 100644 --- a/askomics/libaskomics/SparqlQuery.py +++ b/askomics/libaskomics/SparqlQuery.py @@ -6,6 +6,8 @@ from askomics.libaskomics.SparqlQueryLauncher import SparqlQueryLauncher from askomics.libaskomics.Utils import Utils +from collections import defaultdict + class SparqlQuery(Params): """Format a sparql query @@ -18,7 +20,7 @@ class SparqlQuery(Params): all public graph """ - def __init__(self, app, session, json_query=None): + def __init__(self, app, session, json_query=None, get_graphs=False): """init Parameters @@ -35,6 +37,7 @@ def __init__(self, app, session, json_query=None): self.graphs = [] self.endpoints = [] + self.remote_graphs = defaultdict(list) self.selects = [] self.federated = False @@ -44,8 +47,9 @@ def __init__(self, app, session, json_query=None): self.local_endpoint_f = self.settings.get('federation', 'local_endpoint') except Exception: pass - - self.set_graphs_and_endpoints() + # No need to call this twice if we need it later (sparql queries) + if get_graphs: + self.set_graphs_and_endpoints() def set_graphs(self, graphs): """Set graphs @@ -67,6 +71,16 @@ def set_endpoints(self, endpoints): """ self.endpoints = endpoints + def set_remote_graph(self, remote_graphs): + """Set endpoints + + Parameters + ---------- + endpoints : list + Endpoints + """ + self.remote_graphs = remote_graphs + def is_federated(self): """Return True if there is more than 1 endpoint @@ -275,7 +289,7 @@ def get_default_query_with_prefix(self): self.get_default_query() ) - def format_query(self, query, limit=30, replace_froms=True, federated=False): + def format_query(self, query, limit=30, replace_froms=True, federated=False, ignore_single_tenant=True): """Format the Sparql query - remove all FROM @@ -295,11 +309,13 @@ def format_query(self, query, limit=30, replace_froms=True, federated=False): formatted sparql query """ froms = '' - if replace_froms: - froms = self.get_froms() if federated: - federated_line = "{}\n{}".format(self.get_federated_line(), self.get_federated_froms()) + federated_line = "" if self.settings.getboolean("askomics", "single_tenant", fallback=False) else "{}\n{}".format(self.get_federated_line(), self.get_federated_froms()) + federated_graphs_string = self.get_federated_remote_from_graphs() + else: + if replace_froms and (not self.settings.getboolean("askomics", "single_tenant", fallback=False)): + froms = self.get_froms() query_lines = query.split('\n') @@ -310,6 +326,7 @@ def format_query(self, query, limit=30, replace_froms=True, federated=False): if not line.upper().lstrip().startswith('FROM') and not line.upper().lstrip().startswith('LIMIT') and not line.upper().lstrip().startswith('@FEDERATE'): if line.upper().lstrip().startswith('SELECT') and federated: new_query += "\n{}\n".format(federated_line) + new_query += "\n{}\n".format(federated_graphs_string) new_query += '\n{}'.format(line) # Add new FROM if line.upper().lstrip().startswith('SELECT'): @@ -374,6 +391,22 @@ def get_federated_froms_from_graphs(self, graphs): from_string = "@from <{}>".format(self.local_endpoint_f) for graph in graphs: from_string += " <{}>".format(graph) + return from_string + + def get_federated_remote_from_graphs(self): + """Get @from string fir the federated query engine + + Returns + ------- + string + The from string + """ + from_string = "" + + for endpoint in self.endpoints: + remote_graphs = self.remote_graphs.get(endpoint, []) + if len(remote_graphs) == 1: + from_string += "\n@graph <{}> <{}>".format(endpoint, remote_graphs[0]) return from_string @@ -391,7 +424,7 @@ def get_endpoints_string(self): return endpoints_string - def set_graphs_and_endpoints(self, entities=None, graphs=None, endpoints=None): + def set_graphs_and_endpoints(self, entities=None, graphs=None, endpoints=None, ontologies={}): """Get all public and private graphs containing the given entities Parameters @@ -399,26 +432,33 @@ def set_graphs_and_endpoints(self, entities=None, graphs=None, endpoints=None): entities : list, optional list of entity uri """ - substrlst = [] filter_entity_string = '' if entities: - for entity in entities: - substrlst.append("?entity_uri = <{}>".format(entity)) - filter_entity_string = 'FILTER (' + ' || '.join(substrlst) + ')' + substr = ",".join(["<{}>".format(entity) for entity in entities]) + filter_entity_string = 'FILTER (?entity_uri IN( ' + substr + ' ))' filter_public_string = 'FILTER (?public = )' if 'user' in self.session: filter_public_string = 'FILTER (?public = || ?creator = <{}>)'.format(self.session["user"]["username"]) query = ''' - SELECT DISTINCT ?graph ?endpoint + SELECT DISTINCT ?graph ?endpoint ?entity_uri ?remote_graph WHERE {{ + ?graph_abstraction askomics:public ?public . + ?graph_abstraction dc:creator ?creator . ?graph askomics:public ?public . ?graph dc:creator ?creator . + GRAPH ?graph_abstraction {{ + ?graph_abstraction prov:atLocation ?endpoint . + OPTIONAL {{?graph_abstraction dcat:Dataset ?remote_graph .}} + ?entity_uri a ?askomics_type . + }} GRAPH ?graph {{ - ?graph prov:atLocation ?endpoint . - ?entity_uri a askomics:entity . + {{ [] a ?entity_uri . }} + UNION + {{ ?entity_uri a ?askomics_type . }} }} + VALUES ?askomics_type {{askomics:entity askomics:ontology}} {} {} }} @@ -428,11 +468,17 @@ def set_graphs_and_endpoints(self, entities=None, graphs=None, endpoints=None): header, results = query_launcher.process_query(self.prefix_query(query)) self.graphs = [] self.endpoints = [] + self.remote_graphs = defaultdict(list) for res in results: if not graphs or res["graph"] in graphs: - self.graphs.append(res["graph"]) + # Override with onto graph if matching uri + if ontologies.get(res['entity_uri']): + graph = ontologies[res['entity_uri']]['graph'] + else: + graph = res["graph"] + self.graphs.append(graph) - # If local triplestore url is not accessible by federetad query engine + # If local triplestore url is not accessible by federated query engine if res["endpoint"] == self.settings.get('triplestore', 'endpoint') and self.local_endpoint_f is not None: endpoint = self.local_endpoint_f else: @@ -440,10 +486,143 @@ def set_graphs_and_endpoints(self, entities=None, graphs=None, endpoints=None): if not endpoints or endpoint in endpoints: self.endpoints.append(endpoint) + if res.get("remote_graph"): + self.remote_graphs[endpoint].append(res.get("remote_graph")) self.endpoints = Utils.unique(self.endpoints) self.federated = len(self.endpoints) > 1 + def get_uri_parameters(self, uri, endpoints): + """Get parameters for a specific data URI + + Parameters + ---------- + uri : string + URI to search + + Returns + ------- + dict + The corresponding parameters + """ + raw_query = ''' + SELECT DISTINCT ?predicate ?object ?faldo_value ?faldo_relation + WHERE {{ + ?URI ?predicate ?object . + ?URI a ?entitytype . + + FILTER(! STRSTARTS(STR(?predicate), STR(askomics:))) + OPTIONAL {{ + + ?faldo_uri rdfs:domain ?entitytype . + ?faldo_uri rdfs:label ?attribute_label . + + OPTIONAL {{ + ?object faldo:begin/faldo:position ?faldo_value . + ?faldo_uri rdf:type askomics:faldoStart + }} + + OPTIONAL {{ + ?object faldo:end/faldo:position ?faldo_value . + ?faldo_uri rdf:type askomics:faldoEnd + }} + + OPTIONAL {{ + ?object faldo:begin/faldo:reference/rdfs:label ?faldo_value . + ?faldo_uri rdf:type askomics:faldoReference + }} + + OPTIONAL {{ + ?object faldo:begin/rdf:type ?Gene1_strandCategory . + ?Gene1_strand_faldoStrand a ?Gene1_strandCategory . + ?Gene1_strand_faldoStrand rdfs:label ?faldo_value . + ?faldo_uri rdf:type askomics:faldoStrand . + }} + + OPTIONAL {{ + ?faldo_uri askomics:uri ?node_uri + }} + + VALUES ?predicate {{faldo:location}} + }} + VALUES ?URI {{{}}} + BIND(IF(isBlank(?faldo_uri), ?node_uri ,?faldo_uri) as ?faldo_relation) + }} + '''.format(uri) + + federated = self.is_federated() + replace_froms = self.replace_froms() + + raw_query = self.prefix_query(raw_query) + + sparql = self.format_query(raw_query, replace_froms=replace_froms, federated=federated) + + query_launcher = SparqlQueryLauncher(self.app, self.session, get_result_query=True, federated=federated, endpoints=endpoints) + _, data = query_launcher.process_query(sparql) + + formated_data = [] + for row in data: + + predicate = row['predicate'] + object = row['object'] + + if row.get('faldo_relation'): + predicate = row.get("faldo_relation") + + if row.get('faldo_value'): + object = row.get('faldo_value') + + formated_data.append({ + 'predicate': predicate, + 'object': object, + }) + + return formated_data + + def autocomplete_local_ontology(self, uri, query, max_terms, label): + """Get results for a specific query + + Parameters + ---------- + uri : string + ontology uri + query : string + query to search + + Returns + ------- + dict + The corresponding parameters + """ + + subquery = "" + + if query: + subquery = 'FILTER(contains(lcase(?label), "{}"))'.format(query.lower()) + raw_query = ''' + SELECT DISTINCT ?label + WHERE {{ + ?uri rdf:type owl:Class . + ?uri {} ?label . + {} + }} + '''.format(label, subquery) + + raw_query = self.prefix_query(raw_query) + + is_federated = self.is_federated() + + sparql = self.format_query(raw_query, limit=max_terms, replace_froms=True, federated=is_federated) + + query_launcher = SparqlQueryLauncher(self.app, self.session, get_result_query=True, federated=is_federated) + _, data = query_launcher.process_query(sparql) + + formated_data = [] + for row in data: + formated_data.append(row['label']) + + return formated_data + def format_sparql_variable(self, name): """Format a name into a sparql variable by remove spacial char and add a ? @@ -873,6 +1052,8 @@ def build_query_from_json(self, preview=False, for_editor=False): for_editor : bool, optional Remove FROMS and @federate """ + # Circular import + from askomics.libaskomics.OntologyManager import OntologyManager entities = [] attributes = {} linked_attributes = [] @@ -890,14 +1071,19 @@ def build_query_from_json(self, preview=False, for_editor=False): var_to_replace = [] + ontologies = {} + om = OntologyManager(self.app, self.session) + # Browse attributes to get entities for attr in self.json["attr"]: entities = entities + attr["entityUris"] + if attr["type"] == "uri" and attr.get("ontology", False) is True and not attr["entityUris"][0] in ontologies: + ontologies[attr["entityUris"][0]] = om.get_ontology(uri=attr["entityUris"][0]) entities = list(set(entities)) # uniq list # Set graphs in function of entities needed - self.set_graphs_and_endpoints(entities=entities) + self.set_graphs_and_endpoints(entities=entities, ontologies=ontologies) # self.log.debug(self.json) @@ -1009,7 +1195,20 @@ def build_query_from_json(self, preview=False, for_editor=False): # Classic relation else: - relation = "<{}>".format(link["uri"]) + # Manage ontology stuff + inverse = "" + recurrence = "" + relation = link["uri"] + + if relation.startswith("^"): + inverse = "^" + relation = relation.lstrip("^") + + if relation.endswith("*"): + recurrence = "*" + relation = relation.rstrip("*") + + relation = inverse + "<{}>".format(relation) + recurrence triple = { "subject": source, "predicate": relation, @@ -1031,7 +1230,6 @@ def build_query_from_json(self, preview=False, for_editor=False): # Browse attributes for attribute in self.json["attr"]: - # Get blockid and sblockid of the attribute node block_id, sblock_id, pblock_ids = self.get_block_ids(attribute["nodeId"]) @@ -1040,13 +1238,20 @@ def build_query_from_json(self, preview=False, for_editor=False): subject = self.format_sparql_variable("{}{}_uri".format(attribute["entityLabel"], attribute["nodeId"])) predicate = attribute["uri"] obj = "<{}>".format(attribute["entityUris"][0]) - if not self.is_bnode(attribute["entityUris"][0], self.json["nodes"]): + if not (self.is_bnode(attribute["entityUris"][0], self.json["nodes"]) or attribute.get("ontology", False) is True): self.store_triple({ "subject": subject, "predicate": predicate, "object": obj, "optional": False }, block_id, sblock_id, pblock_ids) + if attribute.get("ontology", False) is True: + self.store_triple({ + "subject": subject, + "predicate": predicate, + "object": "owl:Class", + "optional": False + }, block_id, sblock_id, pblock_ids) if attribute["visible"]: self.selects.append(subject) @@ -1114,6 +1319,8 @@ def build_query_from_json(self, preview=False, for_editor=False): subject = self.format_sparql_variable("{}{}_uri".format(attribute["entityLabel"], attribute["nodeId"])) if attribute["uri"] == "rdfs:label": predicate = attribute["uri"] + if ontologies.get(attribute["entityUris"][0]): + predicate = ontologies[attribute["entityUris"][0]]["label_uri"] else: predicate = "<{}>".format(attribute["uri"]) @@ -1300,9 +1507,10 @@ def build_query_from_json(self, preview=False, for_editor=False): )) var_to_replace.append((category_value_uri, var_2)) - from_string = self.get_froms_from_graphs(self.graphs) + from_string = "" if self.settings.getboolean("askomics", "single_tenant", fallback=False) else self.get_froms_from_graphs(self.graphs) federated_from_string = self.get_federated_froms_from_graphs(self.graphs) endpoints_string = self.get_endpoints_string() + federated_graphs_string = self.get_federated_remote_from_graphs() # Linked attributes: replace SPARQL variable target by source self.replace_variables_in_blocks(var_to_replace) @@ -1332,6 +1540,7 @@ def build_query_from_json(self, preview=False, for_editor=False): query = """ {endpoints} {federated} +{remote_graphs} SELECT DISTINCT {selects} WHERE {{ @@ -1343,6 +1552,7 @@ def build_query_from_json(self, preview=False, for_editor=False): """.format( endpoints=endpoints_string, federated=federated_from_string, + remote_graphs=federated_graphs_string, selects=' '.join(self.selects), triples='\n '.join([self.triple_dict_to_string(triple_dict) for triple_dict in self.triples]), blocks='\n '.join([self.triple_block_to_string(triple_block) for triple_block in self.triples_blocks]), diff --git a/askomics/libaskomics/SparqlQueryLauncher.py b/askomics/libaskomics/SparqlQueryLauncher.py index aae8cc51..64fe2802 100644 --- a/askomics/libaskomics/SparqlQueryLauncher.py +++ b/askomics/libaskomics/SparqlQueryLauncher.py @@ -44,6 +44,7 @@ def __init__(self, app, session, get_result_query=False, federated=False, endpoi except Exception: pass + local = False # Use the federated query engine if federated: self.federated = True @@ -65,16 +66,20 @@ def __init__(self, app, session, get_result_query=False, federated=False, endpoi self.triplestore = self.settings.get('triplestore', 'triplestore') self.url_endpoint = self.settings.get('triplestore', 'endpoint') self.url_updatepoint = self.settings.get('triplestore', 'updatepoint') + local = True + + self.endpoint = SPARQLWrapper(self.url_endpoint, self.url_updatepoint) + + if local: try: self.endpoint.setCredentials( self.settings.get('triplestore', 'username'), self.settings.get('triplestore', 'password') ) + self.endpoint.setHTTPAuth(self.settings.get('triplestore', 'http_auth', fallback="basic")) except Exception: pass - self.endpoint = SPARQLWrapper(self.url_endpoint, self.url_updatepoint) - def load_data(self, file_name, graph, host_url): """Load data in function of the triplestore @@ -220,7 +225,7 @@ def insert_data(self, ttl, graph, metadata=False): TYPE query result """ - triples = self.get_triples_from_graph(ttl) if metadata else ttl.serialize(format='nt').decode("utf-8") + triples = self.get_triples_from_graph(ttl) if metadata else ttl.serialize(format='nt') query = ''' INSERT {{ @@ -305,8 +310,8 @@ def execute_query(self, query, disable_log=False, isql_api=False): if self.endpoint.isSparqlUpdateRequest(): self.endpoint.setMethod('POST') # Virtuoso hack - if self.triplestore == 'virtuoso': - self.endpoint.queryType = "SELECT" + # if self.triplestore == 'virtuoso': + # self.endpoint.queryType = "SELECT" results = self.endpoint.query() # Select diff --git a/askomics/libaskomics/TriplestoreExplorer.py b/askomics/libaskomics/TriplestoreExplorer.py index 50557c6c..ced8a54e 100644 --- a/askomics/libaskomics/TriplestoreExplorer.py +++ b/askomics/libaskomics/TriplestoreExplorer.py @@ -208,12 +208,14 @@ def get_abstraction(self): """ insert, abstraction = self.get_cached_asbtraction() + single_tenant = self.settings.getboolean("askomics", "single_tenant", fallback=False) + # No abstraction entry in database, create it if not abstraction: abstraction = { - "entities": self.get_abstraction_entities(), - "attributes": self.get_abstraction_attributes(), - "relations": self.get_abstraction_relations() + "entities": self.get_abstraction_entities(single_tenant), + "attributes": self.get_abstraction_attributes(single_tenant), + "relations": self.get_abstraction_relations(single_tenant) } # Cache abstraction in DB, only for logged users @@ -305,7 +307,7 @@ def uncache_abstraction(self, public=True, force=False): database.execute_sql_query(query, sql_var) - def get_abstraction_entities(self): + def get_abstraction_entities(self, single_tenant=False): """Get abstraction entities Returns @@ -328,7 +330,7 @@ def get_abstraction_entities(self): GRAPH ?graph {{ ?graph prov:atLocation ?endpoint . ?entity_uri a ?entity_type . - VALUES ?entity_type {{ askomics:entity askomics:bnode }} . + VALUES ?entity_type {{ askomics:entity askomics:bnode askomics:ontology}} . # Faldo OPTIONAL {{ ?entity_uri a ?entity_faldo . @@ -362,6 +364,7 @@ def get_abstraction_entities(self): "label": label, "instancesHaveLabels": True if "have_no_label" not in result else False if result["have_no_label"] == "1" else True, "faldo": True if "entity_faldo" in result else False, + "ontology": True if result["entity_type"] == "{}ontology".format(self.settings.get("triplestore", "namespace_internal")) else False, "endpoints": [result["endpoint"]], "graphs": [result["graph"]], } @@ -378,7 +381,7 @@ def get_abstraction_entities(self): return entities - def get_abstraction_attributes(self): + def get_abstraction_attributes(self, single_tenant=False): """Get user abstraction attributes from the triplestore Returns @@ -407,13 +410,16 @@ def get_abstraction_attributes(self): ?graph askomics:public ?public . ?graph dc:creator ?creator . GRAPH ?graph {{ - ?attribute_uri a ?attribute_type . + ?node a ?attribute_type . VALUES ?attribute_type {{ owl:DatatypeProperty askomics:AskomicsCategory }} - ?attribute_uri rdfs:label ?attribute_label . - ?attribute_uri rdfs:range ?attribute_range . + ?node rdfs:label ?attribute_label . + ?node rdfs:range ?attribute_range . + # Retrocompatibility + OPTIONAL {{?node askomics:uri ?new_attribute_uri}} + BIND( IF(isBlank(?node),?new_attribute_uri, ?node) as ?attribute_uri ) # Faldo OPTIONAL {{ - ?attribute_uri a ?attribute_faldo . + ?node a ?attribute_faldo . VALUES ?attribute_faldo {{ askomics:faldoStart askomics:faldoEnd askomics:faldoStrand askomics:faldoReference }} }} # Categories (DK) @@ -424,10 +430,10 @@ def get_abstraction_attributes(self): }} # Attribute of entity (or motherclass of entity) {{ - ?attribute_uri rdfs:domain ?mother . + ?node rdfs:domain ?mother . ?entity_uri rdfs:subClassOf ?mother . }} UNION {{ - ?attribute_uri rdfs:domain ?entity_uri . + ?node rdfs:domain ?entity_uri . }} FILTER ( ?public = {} @@ -441,13 +447,13 @@ def get_abstraction_attributes(self): attributes = [] for result in data: - # Attributes - if "attribute_uri" in result and "attribute_label" in result and result["attribute_type"] != "{}AskomicsCategory".format(self.settings.get("triplestore", "namespace_internal")) and result["attribute_range"] in litterals: - attr_tpl = (result["attribute_uri"], result["entity_uri"]) + attribute_uri = result.get("attribute_uri") + if attribute_uri and "attribute_label" in result and result["attribute_type"] != "{}AskomicsCategory".format(self.settings.get("triplestore", "namespace_internal")) and result["attribute_range"] in litterals: + attr_tpl = (attribute_uri, result["entity_uri"]) if attr_tpl not in attributes_list: attributes_list.append(attr_tpl) attribute = { - "uri": result["attribute_uri"], + "uri": attribute_uri, "label": result["attribute_label"], "graphs": [result["graph"], ], "entityUri": result["entity_uri"], @@ -465,12 +471,12 @@ def get_abstraction_attributes(self): index_attribute = attributes_list.index(attr_tpl) # Categories - if "attribute_uri" in result and result["attribute_type"] == "{}AskomicsCategory".format(self.settings.get("triplestore", "namespace_internal")) and "category_value_uri" in result: - attr_tpl = (result["attribute_uri"], result["entity_uri"]) + if attribute_uri and result["attribute_type"] == "{}AskomicsCategory".format(self.settings.get("triplestore", "namespace_internal")) and "category_value_uri" in result: + attr_tpl = (attribute_uri, result["entity_uri"]) if attr_tpl not in attributes_list: attributes_list.append(attr_tpl) attribute = { - "uri": result["attribute_uri"], + "uri": attribute_uri, "label": result["attribute_label"], "graphs": [result["graph"], ], "entityUri": result["entity_uri"], @@ -497,7 +503,7 @@ def get_abstraction_attributes(self): return attributes - def get_abstraction_relations(self): + def get_abstraction_relations(self, single_tenant=False): """Get user abstraction relations from the triplestore Returns @@ -513,24 +519,27 @@ def get_abstraction_relations(self): query_builder = SparqlQuery(self.app, self.session) query = ''' - SELECT DISTINCT ?graph ?entity_uri ?entity_faldo ?entity_label ?node_type ?attribute_uri ?attribute_faldo ?attribute_label ?attribute_range ?property_uri ?property_faldo ?property_label ?range_uri ?category_value_uri ?category_value_label + SELECT DISTINCT ?graph ?entity_uri ?entity_faldo ?entity_label ?attribute_uri ?attribute_faldo ?attribute_label ?attribute_range ?property_uri ?property_faldo ?property_label ?range_uri ?category_value_uri ?category_value_label WHERE {{ # Graphs ?graph askomics:public ?public . ?graph dc:creator ?creator . GRAPH ?graph {{ # Property (relations and categories) - ?property_uri a owl:ObjectProperty . - ?property_uri a askomics:AskomicsRelation . - ?property_uri rdfs:label ?property_label . - ?property_uri rdfs:range ?range_uri . + ?node a owl:ObjectProperty . + ?node a askomics:AskomicsRelation . + ?node rdfs:label ?property_label . + ?node rdfs:range ?range_uri . + # Retrocompatibility + OPTIONAL {{?node askomics:uri ?new_property_uri}} + BIND( IF(isBlank(?node), ?new_property_uri, ?node) as ?property_uri) }} # Relation of entity (or motherclass of entity) {{ - ?property_uri rdfs:domain ?mother . + ?node rdfs:domain ?mother . ?entity_uri rdfs:subClassOf ?mother . }} UNION {{ - ?property_uri rdfs:domain ?entity_uri . + ?node rdfs:domain ?entity_uri . }} FILTER ( ?public = {} @@ -542,15 +551,15 @@ def get_abstraction_relations(self): relations_list = [] relations = [] - for result in data: # Relation if "property_uri" in result: - rel_tpl = (result["property_uri"], result["entity_uri"], result["range_uri"]) + property_uri = result.get("property_uri") + rel_tpl = (property_uri, result["entity_uri"], result["range_uri"]) if rel_tpl not in relations_list: relations_list.append(rel_tpl) relation = { - "uri": result["property_uri"], + "uri": property_uri, "label": result["property_label"], "graphs": [result["graph"], ], "source": result["entity_uri"], diff --git a/askomics/react/src/components/autocomplete.jsx b/askomics/react/src/components/autocomplete.jsx new file mode 100644 index 00000000..452e9575 --- /dev/null +++ b/askomics/react/src/components/autocomplete.jsx @@ -0,0 +1,147 @@ +import React, { Component} from 'react' +import axios from 'axios' +import PropTypes from 'prop-types' +import { Input } from 'reactstrap' +import Autosuggest from 'react-autosuggest'; + + +export default class Autocomplete extends Component { + constructor (props) { + super(props) + this.state = { + ontologyShort: this.getAutoComplete(), + maxResults: this.props.config.autocompleteMaxResults, + options: [] + } + + this.handleFilterValue = this.props.handleFilterValue.bind(this) + this.autocompleteOntology = this.autocompleteOntology.bind(this) + this.onSuggestionsFetchRequested = this.onSuggestionsFetchRequested.bind(this) + this.onSuggestionsClearRequested = this.onSuggestionsClearRequested.bind(this) + this.cancelRequest + this.handleOntoValue = this.handleOntoValue.bind(this) + this.WAIT_INTERVAL = 500 + this.timerID + } + + getAutoComplete () { + let selectedOnto = this.props.config.ontologies.find(onto => onto.uri == this.props.entityUri) + if (selectedOnto){ + return selectedOnto.short_name + } + return "" + } + + autocompleteOntology (value) { + if (this.state.ontologyShort.length == 0){ return } + + let userInput = value + let requestUrl = '/api/ontology/' + this.state.ontologyShort + "/autocomplete" + + if (value.length < 3) { return } + + axios.get(requestUrl, {baseURL: this.props.config.proxyPath, params:{q: userInput}, cancelToken: new axios.CancelToken((c) => { this.cancelRequest = c }) }) + .then(response => { + this.setState({ + options: response.data.results + }) + }) + .catch(error => { + console.log(error, error.response.data.errorMessage) + this.setState({ + error: true, + errorMessage: error.response.data.errorMessage, + status: error.response.status, + waiting: false + }) + }) + } + + + handleOntoValue (event, value) { + this.handleFilterValue({target:{value: value.newValue, id: this.props.attributeId}}) + } + + + renderSuggestion (suggestion, {query, isHighlighted}) { + let textArray = suggestion.split(RegExp(query, "gi")); + let match = suggestion.match(RegExp(query, "gi")); + + return ( + + {textArray.map((item, index) => ( + + {item} + {index !== textArray.length - 1 && match && ( + {match[index]} + )} + + ))} + + ); + } + + onSuggestionsClearRequested () { + this.setState({ + options: [] + }) + } + + getSuggestionValue (suggestion) { + return suggestion + }; + + onSuggestionsFetchRequested ( value ){ + clearTimeout(this.timerID) + this.timerID = setTimeout(() => { + this.autocompleteOntology(value.value) + }, this.WAIT_INTERVAL) + }; + + + renderInputComponent (inputProps){ + return( +
+ +
+ ) + } + + + shouldRenderSuggestions(value, reason){ + return value.trim().length > 2; + } + + render () { + + let value = this.props.filterValue + + let inputProps = { + placeholder: '', + value, + onChange: this.handleOntoValue + }; + + return ( + + ) + + } +} + +Autocomplete.propTypes = { + handleFilterValue: PropTypes.func, + entityUri: PropTypes.string, + attributeId: PropTypes.number, + filterValue: PropTypes.string, + config: PropTypes.object, +} diff --git a/askomics/react/src/navbar.jsx b/askomics/react/src/navbar.jsx index ff3062fc..01b5e457 100644 --- a/askomics/react/src/navbar.jsx +++ b/askomics/react/src/navbar.jsx @@ -43,6 +43,8 @@ export default class AskoNavbar extends Component { adminLinks = ( Admin + Prefixes + Ontologies ) } @@ -104,4 +106,4 @@ export default class AskoNavbar extends Component { AskoNavbar.propTypes = { waitForStart: PropTypes.bool, config: PropTypes.object -} \ No newline at end of file +} diff --git a/askomics/react/src/routes.jsx b/askomics/react/src/routes.jsx index 6555c070..94e92c7e 100644 --- a/askomics/react/src/routes.jsx +++ b/askomics/react/src/routes.jsx @@ -14,6 +14,8 @@ import Logout from './routes/login/logout' import PasswordReset from './routes/login/passwordreset' import Account from './routes/account/account' import Admin from './routes/admin/admin' +import Prefixes from './routes/admin/prefixes' +import Ontologies from './routes/admin/ontologies' import Sparql from './routes/sparql/sparql' import FormQuery from './routes/form/query' import FormEditQuery from './routes/form_edit/query' @@ -44,7 +46,10 @@ export default class Routes extends Component { gitUrl: null, disableIntegration: null, namespaceData: null, - namespaceInternal: null + namespaceInternal: null, + ontologies: [], + singleTenant: false, + autocompleteMaxResults: 10 } } this.cancelRequest @@ -113,6 +118,8 @@ export default class Routes extends Component { this.setState(p)} {...props}/>}/> ( this.setState(p)} />)} /> ( this.setState(p)} />)} /> + ( this.setState(p)} />)} /> + ( this.setState(p)} />)} /> diff --git a/askomics/react/src/routes/admin/admin.jsx b/askomics/react/src/routes/admin/admin.jsx index 17cebd31..9f4bfb63 100644 --- a/askomics/react/src/routes/admin/admin.jsx +++ b/askomics/react/src/routes/admin/admin.jsx @@ -43,7 +43,7 @@ export default class Admin extends Component { instanceUrl: "", usersSelected: [], filesSelected: [], - datasetsSelected: [] + datasetsSelected: [], } this.handleChangeUserInput = this.handleChangeUserInput.bind(this) this.handleChangeFname = this.handleChangeFname.bind(this) @@ -404,6 +404,7 @@ export default class Admin extends Component { this.setState(p)} queriesLoading={this.state.queriesLoading} />
+ ) } diff --git a/askomics/react/src/routes/admin/datasetstable.jsx b/askomics/react/src/routes/admin/datasetstable.jsx index e961b6b4..dd199566 100644 --- a/askomics/react/src/routes/admin/datasetstable.jsx +++ b/askomics/react/src/routes/admin/datasetstable.jsx @@ -99,7 +99,7 @@ render () { return (
- +
) diff --git a/askomics/react/src/routes/admin/ontologies.jsx b/askomics/react/src/routes/admin/ontologies.jsx new file mode 100644 index 00000000..d7b97511 --- /dev/null +++ b/askomics/react/src/routes/admin/ontologies.jsx @@ -0,0 +1,365 @@ +import React, { Component } from 'react' +import axios from 'axios' +import {Button, Form, FormGroup, Label, Input, Alert, Row, Col, CustomInput } from 'reactstrap' +import BootstrapTable from 'react-bootstrap-table-next' +import paginationFactory from 'react-bootstrap-table2-paginator' +import update from 'react-addons-update' +import PropTypes from 'prop-types' +import Utils from '../../classes/utils' +import { Redirect } from 'react-router-dom' +import WaitingDiv from '../../components/waiting' +import ErrorDiv from '../error/error' + +export default class Ontologies extends Component { + constructor (props) { + super(props) + this.utils = new Utils() + this.state = { + error: false, + errorMessage: '', + ontologyError: false, + ontologyErrorMessage: '', + newontologyError: false, + newontologyErrorMessage: '', + ontologies: [], + datasets: [], + name: "", + uri: "", + shortName: "", + type: "local", + datasetId: "", + labelUri: "rdfs:label", + ontologiesSelected: [] + } + this.handleChangeValue = this.handleChangeValue.bind(this) + this.handleAddOntology = this.handleAddOntology.bind(this) + this.deleteSelectedOntologies = this.deleteSelectedOntologies.bind(this) + this.handleOntologySelection = this.handleOntologySelection.bind(this) + this.handleOntologySelectionAll = this.handleOntologySelectionAll.bind(this) + this.cancelRequest + } + + isOntologiesDisabled () { + return this.state.ontologiesSelected.length == 0 + } + + cleanupOntologies (newOntologies) { + let cleanOntologies = [] + newOntologies.map(onto => { + cleanOntologies.push({ + id:onto.id, + name:onto.name, + uri:onto.uri, + short_name: onto.short_name, + type: onto.type + }) + }) + return cleanOntologies + } + + deleteSelectedOntologies () { + let requestUrl = '/api/admin/delete_ontologies' + let data = { + ontologiesIdToDelete: this.state.ontologiesSelected + } + + axios.post(requestUrl, data, { baseURL: this.props.config.proxyPath, cancelToken: new axios.CancelToken((c) => { this.cancelRequest = c }) }) + .then(response => { + console.log(requestUrl, response.data) + this.setState({ + ontologies: response.data.ontologies, + ontologiesSelected: [], + }) + this.props.setStateNavbar({ + config: update(this.props.config, {ontologies: {$set: this.cleanupOntologies(response.data.ontologies)}}) + }) + }) + } + + handleChangeValue (event) { + let data = {} + data[event.target.id] = event.target.value + this.setState(data) + } + + validateOntologyForm () { + return ( + this.state.name.length > 0 && + this.state.uri.length > 0 && + this.state.shortName.length > 0 && + this.state.datasetId.length > 0 && + this.state.labelUri.length > 0 + ) + } + + handleOntologySelection (row, isSelect) { + if (isSelect) { + this.setState({ + ontologiesSelected: [...this.state.ontologiesSelected, row.id] + }) + } else { + this.setState({ + ontologiesSelected: this.state.ontologiesSelected.filter(x => x !== row.id) + }) + } + } + + handleOntologySelectionAll (isSelect, rows) { + const ontologies = rows.map(r => r.id) + if (isSelect) { + this.setState({ + ontologiesSelected: ontologies + }) + } else { + this.setState({ + ontologiesSelected: [] + }) + } + } + + handleAddOntology(event) { + + let requestUrl = "/api/admin/addontology" + let data = { + name: this.state.name, + uri: this.state.uri, + shortName: this.state.shortName, + type: this.state.type, + datasetId: this.state.datasetId, + labelUri: this.state.labelUri + } + + axios.post(requestUrl, data, { baseURL: this.props.config.proxyPath, cancelToken: new axios.CancelToken((c) => { this.cancelRequest = c }) }) + .then(response => { + this.setState({ + newontologyError: response.data.error, + newontologyErrorMessage: [response.data.errorMessage], + ontologies: response.data.ontologies, + newontologyStatus: response.status, + name: "", + uri: "", + shortName: "", + type: "local", + labelUri: "rdfs:label" + }) + this.props.setStateNavbar({ + config: update(this.props.config, {ontologies: {$set: this.cleanupOntologies(response.data.ontologies)}}) + }) + }) + .catch(error => { + console.log(error, error.response.data.errorMessage) + this.setState({ + newontologyError: true, + newontologyErrorMessage: [error.response.data.errorMessage], + newontologyStatus: error.response.status, + }) + }) + event.preventDefault() + } + + componentDidMount () { + if (!this.props.waitForStart) { + this.loadOntologies() + this.loadDatasets() + } + } + + loadOntologies() { + let requestUrl = '/api/admin/getontologies' + axios.get(requestUrl, { baseURL: this.props.config.proxyPath, cancelToken: new axios.CancelToken((c) => { this.cancelRequest = c }) }) + .then(response => { + this.setState({ + ontologiesLoading: false, + ontologies: response.data.ontologies + }) + }) + .catch(error => { + console.log(error, error.response.data.errorMessage) + this.setState({ + ontologyError: true, + ontologyErrorMessage: error.response.data.errorMessage, + ontologyStatus: error.response.status, + success: !error.response.data.error + }) + }) + } + + loadDatasets() { + let requestUrl = '/api/datasets' + axios.get(requestUrl, { baseURL: this.props.config.proxyPath, cancelToken: new axios.CancelToken((c) => { this.cancelRequest = c }) }) + .then(response => { + this.setState({ + datasets: response.data.datasets + }) + }) + .catch(error => { + console.log(error, error.response.data.errorMessage) + this.setState({ + success: !error.response.data.error + }) + }) + } + + componentWillUnmount () { + if (!this.props.waitForStart) { + this.cancelRequest() + } + } + + render () { + + if (!this.props.waitForStart && !this.props.config.logged) { + return + } + if (!this.props.waitForStart && this.props.config.user.admin != 1) { + return + } + + if (this.props.waitForStart) { + return + } + + let ontologiesColumns = [{ + editable: false, + dataField: 'name', + text: 'Name', + sort: true + }, { + editable: false, + dataField: 'short_name', + text: 'Short name', + sort: true + }, { + editable: false, + dataField: 'uri', + text: 'Uri', + sort: true + }, { + editable: false, + dataField: 'dataset_name', + text: 'Dataset', + sort: true + }, { + editable: false, + dataField: 'label_uri', + text: 'Label uri', + sort: true + }, { + editable: false, + dataField: 'type', + text: 'Autocomplete type', + sort: true + } + + ] + + let ontologiesDefaultSorted = [{ + dataField: 'short_name', + order: 'asc' + }] + + let ontologiesSelectRow = { + mode: 'checkbox', + clickToSelect: false, + selected: this.state.ontologiesSelected, + onSelect: this.handleOntologySelection, + onSelectAll: this.handleOntologySelectionAll + } + + let ontologiesNoDataIndication = 'No ontologies' + if (this.state.ontologiesLoading) { + ontologiesNoDataIndication = + } + + return ( +
+

Admin

+
+

Add a ontology

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + {this.state.datasets.map(dataset => { + if (dataset.public == 1 && dataset.status == "success"){ + return + } + })} + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+ +
+
+ + +
+ ) + } +} + +Ontologies.propTypes = { + setStateNavbar: PropTypes.func, + waitForStart: PropTypes.bool, + config: PropTypes.object +} diff --git a/askomics/react/src/routes/admin/prefixes.jsx b/askomics/react/src/routes/admin/prefixes.jsx new file mode 100644 index 00000000..8be17418 --- /dev/null +++ b/askomics/react/src/routes/admin/prefixes.jsx @@ -0,0 +1,257 @@ +import React, { Component } from 'react' +import axios from 'axios' +import {Button, Form, FormGroup, Label, Input, Alert, Row, Col, CustomInput } from 'reactstrap' +import BootstrapTable from 'react-bootstrap-table-next' +import paginationFactory from 'react-bootstrap-table2-paginator' +import PropTypes from 'prop-types' +import Utils from '../../classes/utils' +import { Redirect } from 'react-router-dom' +import WaitingDiv from '../../components/waiting' +import ErrorDiv from '../error/error' + +export default class Prefixes extends Component { + constructor (props) { + super(props) + this.utils = new Utils() + this.state = { + error: false, + errorMessage: '', + prefixError: false, + prefixErrorMessage: '', + newprefixError: false, + newprefixErrorMessage: '', + prefixes: [], + prefix: "", + namespace: "", + prefixesSelected: [] + } + this.handleChangePrefix = this.handleChangePrefix.bind(this) + this.handleChangeNamespace = this.handleChangeNamespace.bind(this) + this.handleAddPrefix = this.handleAddPrefix.bind(this) + this.deleteSelectedPrefixes = this.deleteSelectedPrefixes.bind(this) + this.handlePrefixSelection = this.handlePrefixSelection.bind(this) + this.handlePrefixSelectionAll = this.handlePrefixSelectionAll.bind(this) + this.cancelRequest + } + + isPrefixesDisabled () { + return this.state.prefixesSelected.length == 0 + } + + deleteSelectedPrefixes () { + let requestUrl = '/api/admin/delete_prefixes' + let data = { + prefixesIdToDelete: this.state.prefixesSelected + } + axios.post(requestUrl, data, { baseURL: this.props.config.proxyPath, cancelToken: new axios.CancelToken((c) => { this.cancelRequest = c }) }) + .then(response => { + console.log(requestUrl, response.data) + this.setState({ + prefixes: response.data.prefixes, + prefixesSelected: [], + }) + }) + } + + handleChangePrefix (event) { + this.setState({ + prefix: event.target.value + }) + } + + handleChangeNamespace (event) { + this.setState({ + namespace: event.target.value + }) + } + + validatePrefixForm () { + return ( + this.state.prefix.length > 0 && + this.state.namespace.length > 0 + ) + } + + handlePrefixSelection (row, isSelect) { + if (isSelect) { + this.setState({ + prefixesSelected: [...this.state.prefixesSelected, row.id] + }) + } else { + this.setState({ + prefixesSelected: this.state.prefixesSelected.filter(x => x !== row.id) + }) + } + } + + handlePrefixSelectionAll (isSelect, rows) { + const prefixes = rows.map(r => r.id) + if (isSelect) { + this.setState({ + prefixesSelected: prefixes + }) + } else { + this.setState({ + prefixesSelected: [] + }) + } + } + + handleAddPrefix(event) { + + let requestUrl = "/api/admin/addprefix" + let data = { + prefix: this.state.prefix, + namespace: this.state.namespace, + } + + axios.post(requestUrl, data, { baseURL: this.props.config.proxyPath, cancelToken: new axios.CancelToken((c) => { this.cancelRequest = c }) }) + .then(response => { + console.log(requestUrl, response.data) + this.setState({ + newprefixError: response.data.error, + newprefixErrorMessage: response.data.errorMessage, + prefixes: response.data.prefixes, + newprefixStatus: response.status, + }) + }) + .catch(error => { + console.log(error, error.response.data.errorMessage) + this.setState({ + newprefixError: true, + newprefixErrorMessage: error.response.data.errorMessage, + newprefixStatus: error.response.status, + }) + }) + event.preventDefault() + } + + componentDidMount () { + if (!this.props.waitForStart) { + this.loadPrefixes() + } + } + + loadPrefixes() { + let requestUrl = '/api/admin/getprefixes' + axios.get(requestUrl, { baseURL: this.props.config.proxyPath, cancelToken: new axios.CancelToken((c) => { this.cancelRequest = c }) }) + .then(response => { + this.setState({ + prefixesLoading: false, + prefixes: response.data.prefixes + }) + }) + .catch(error => { + console.log(error, error.response.data.errorMessage) + this.setState({ + prefixError: true, + prefixErrorMessage: error.response.data.errorMessage, + prefixStatus: error.response.status, + success: !error.response.data.error + }) + }) + } + + componentWillUnmount () { + if (!this.props.waitForStart) { + this.cancelRequest() + } + } + + render () { + + if (!this.props.waitForStart && !this.props.config.logged) { + return + } + if (!this.props.waitForStart && this.props.config.user.admin != 1) { + return + } + + if (this.props.waitForStart) { + return + } + + let prefixesColumns = [{ + editable: false, + dataField: 'prefix', + text: 'Prefix', + sort: true + }, { + editable: false, + dataField: 'namespace', + text: 'Namespace', + sort: true + }] + + let prefixesDefaultSorted = [{ + dataField: 'prefix', + order: 'asc' + }] + + let prefixesSelectRow = { + mode: 'checkbox', + clickToSelect: false, + selected: this.state.prefixesSelected, + onSelect: this.handlePrefixSelection, + onSelectAll: this.handlePrefixSelectionAll + } + + let prefixesNoDataIndication = 'No custom prefixes' + if (this.state.prefixesLoading) { + prefixesNoDataIndication = + } + + return ( +
+

Admin

+
+

Add a prefix

+
+
+ + + + + + + + + + + + + + + +
+ +
+
+
+
+ +
+
+ + +
+ ) + } +} + +Prefixes.propTypes = { + waitForStart: PropTypes.bool, + config: PropTypes.object +} diff --git a/askomics/react/src/routes/ask/ask.jsx b/askomics/react/src/routes/ask/ask.jsx index e788fef5..991ed46a 100644 --- a/askomics/react/src/routes/ask/ask.jsx +++ b/askomics/react/src/routes/ask/ask.jsx @@ -29,7 +29,8 @@ export default class Ask extends Component { dropdownOpen: false, selectedEndpoint: [], frontMessage: "", - redirectFormBuilder: false + redirectFormBuilder: false, + console_enabled: false } this.utils = new Utils() this.cancelRequest @@ -155,6 +156,7 @@ export default class Ask extends Component { graphs: response.data.graphs, endpoints_sparql: response.data.endpoints, diskSpace: response.data.diskSpace, + console_enabled: response.data.console_enabled }) } }) @@ -276,7 +278,8 @@ export default class Ask extends Component { graphs: this.state.graphs, endpoints: this.state.endpoints_sparql, diskSpace: this.state.diskSpace, - config: this.props.config + config: this.props.config, + console_enabled: this.state.console_enabled } }} /> } diff --git a/askomics/react/src/routes/data/data.jsx b/askomics/react/src/routes/data/data.jsx index 1b23cbc2..18b41092 100644 --- a/askomics/react/src/routes/data/data.jsx +++ b/askomics/react/src/routes/data/data.jsx @@ -16,7 +16,7 @@ class Data extends Component { constructor (props) { super(props) this.utils = new Utils() - this.state = { + this.state = { isLoading: true, error: false, errorMessage: '', @@ -32,7 +32,7 @@ class Data extends Component { loadData() { let uri = this.props.match.params.uri; - let requestUrl = '/api/data/' + uri + let requestUrl = '/api/data/' + uri axios.get(requestUrl, { baseURL: this.props.config.proxyPath, cancelToken: new axios.CancelToken((c) => { this.cancelRequest = c }) }) .then(response => { console.log(requestUrl, response.data) @@ -61,7 +61,7 @@ class Data extends Component { let uri = this.props.match.params.uri; let columns = [{ - dataField: 'predicat', + dataField: 'predicate', text: 'Property', sort: true, formatter: (cell, row) => { @@ -79,7 +79,7 @@ class Data extends Component { if (cell.startsWith(this.props.config.namespaceInternal)){ return this.utils.splitUrl(cell) } else { - return {this.utils.splitUrl(cell)} + return {this.utils.splitUrl(cell)} } } return cell @@ -90,7 +90,7 @@ class Data extends Component { return (

Information about uri {uri}

-
+
- +
) @@ -209,4 +209,4 @@ DatasetsTable.propTypes = { waiting: PropTypes.bool, datasets: PropTypes.object, config: PropTypes.object -} \ No newline at end of file +} diff --git a/askomics/react/src/routes/form/attribute.jsx b/askomics/react/src/routes/form/attribute.jsx index 7b59e403..7581a5da 100644 --- a/askomics/react/src/routes/form/attribute.jsx +++ b/askomics/react/src/routes/form/attribute.jsx @@ -32,6 +32,17 @@ export default class AttributeBox extends Component { this.handleDateFilter = this.props.handleDateFilter.bind(this) } + subNums (id) { + let newStr = "" + let oldStr = id.toString() + let arrayString = [...oldStr] + arrayString.forEach(char => { + let code = char.charCodeAt() + newStr += String.fromCharCode(code + 8272) + }) + return newStr + } + renderLinker () { let options = [] @@ -68,58 +79,6 @@ export default class AttributeBox extends Component { } } - renderUri () { - let eyeIcon = 'attr-icon fas fa-eye-slash inactive' - if (this.props.attribute.visible) { - eyeIcon = 'attr-icon fas fa-eye' - } - - let linkIcon = 'attr-icon fas fa-unlink inactive' - if (this.props.attribute.linked) { - linkIcon = 'attr-icon fas fa-link' - } - - let selected_sign = { - '=': !this.props.attribute.negative, - "≠": this.props.attribute.negative - } - - let form - - if (this.props.attribute.linked) { - form = this.renderLinker() - } else { - form = ( - - - - - -
- - {Object.keys(selected_sign).map(type => { - return - })} - - - - Please filter with a valid URI or CURIE -
- ) - } - - return ( -
- -
- - -
- {form} -
- ) - } - renderText () { let eyeIcon = 'attr-icon fas fa-eye-slash inactive' @@ -186,11 +145,10 @@ export default class AttributeBox extends Component { return (
- +
- - {this.props.attribute.uri == "rdf:type" || this.props.attribute.uri == "rdfs:label" ? : } - + {this.props.attribute.uri == "rdf:type" || this.props.attribute.uri == "rdfs:label" ? : } +
{form}
@@ -256,11 +214,10 @@ export default class AttributeBox extends Component { return (
- +
- - - + +
{form}
@@ -308,12 +265,11 @@ export default class AttributeBox extends Component { return (
- +
- - - - + + +
{form}
@@ -354,11 +310,10 @@ export default class AttributeBox extends Component { return (
- +
- - - + +
{form}
@@ -432,11 +387,10 @@ export default class AttributeBox extends Component { return (
- +
- - - + +
{form}
diff --git a/askomics/react/src/routes/form/query.jsx b/askomics/react/src/routes/form/query.jsx index 3b0fe52d..c3ce9c20 100644 --- a/askomics/react/src/routes/form/query.jsx +++ b/askomics/react/src/routes/form/query.jsx @@ -5,6 +5,7 @@ import { Redirect } from 'react-router-dom' import ErrorDiv from '../error/error' import WaitingDiv from '../../components/waiting' import update from 'react-addons-update' +import ReactTooltip from "react-tooltip"; import AttributeBox from './attribute' import Entity from './entity' import ResultsTable from '../sparql/resultstable' @@ -55,7 +56,7 @@ export default class FormQuery extends Component { this.handlePreview = this.handlePreview.bind(this) this.handleQuery = this.handleQuery.bind(this) - + } subNums (id) { @@ -275,6 +276,7 @@ export default class FormQuery extends Component { saveIcon: "play", waiting: waiting }) + ReactTooltip.rebuild(); } // Preview results and Launch query buttons ------- @@ -383,7 +385,6 @@ export default class FormQuery extends Component { }) }).then(response => { this.graphState = this.props.location.state.graphState - console.log(this.props.location.state.graphState) this.updateGraphState() this.setState({ waiting: false }) }) @@ -435,12 +436,21 @@ export default class FormQuery extends Component { let previewButton let launchQueryButton let entityMap = new Map() + let tooltips = ( +
+ Mark attribute as a form attribute + Link this attribute to another + Show all values, including empty values. + Exclude categories, instead of including + Display attribute value in the results +
+ ) if (!this.state.waiting) { this.state.graphState.attr.forEach(attribute => { if (attribute.form) { if (! entityMap.has(attribute.nodeId)){ - entityMap.set(attribute.nodeId, {entity_label: attribute.entityDisplayLabel, attributes:[]}) + entityMap.set(attribute.nodeId, {entity_label: attribute.entityDisplayLabel ? attribute.entityDisplayLabel : attribute.entityLabel, attributes:[]}) } entityMap.get(attribute.nodeId).attributes.push(
{Entities} + {tooltips}
diff --git a/askomics/react/src/routes/form_edit/attribute.jsx b/askomics/react/src/routes/form_edit/attribute.jsx index f7c95455..eb85d041 100644 --- a/askomics/react/src/routes/form_edit/attribute.jsx +++ b/askomics/react/src/routes/form_edit/attribute.jsx @@ -32,6 +32,17 @@ export default class AttributeBox extends Component { this.handleDateFilter = this.props.handleDateFilter.bind(this) } + subNums (id) { + let newStr = "" + let oldStr = id.toString() + let arrayString = [...oldStr] + arrayString.forEach(char => { + let code = char.charCodeAt() + newStr += String.fromCharCode(code + 8272) + }) + return newStr + } + renderLinker () { let options = [] @@ -68,58 +79,6 @@ export default class AttributeBox extends Component { } } - renderUri () { - let eyeIcon = 'attr-icon fas fa-eye-slash inactive' - if (this.props.attribute.visible) { - eyeIcon = 'attr-icon fas fa-eye' - } - - let linkIcon = 'attr-icon fas fa-unlink inactive' - if (this.props.attribute.linked) { - linkIcon = 'attr-icon fas fa-link' - } - - let selected_sign = { - '=': !this.props.attribute.negative, - "≠": this.props.attribute.negative - } - - let form - - if (this.props.attribute.linked) { - form = this.renderLinker() - } else { - form = ( - - - - - -
- - {Object.keys(selected_sign).map(type => { - return - })} - - - - Please filter with a valid URI or CURIE -
- ) - } - - return ( -
- -
- - -
- {form} -
- ) - } - renderText () { let eyeIcon = 'attr-icon fas fa-eye-slash inactive' @@ -188,11 +147,10 @@ export default class AttributeBox extends Component { return (
- +
- - {this.props.attribute.uri == "rdf:type" || this.props.attribute.uri == "rdfs:label" ? : } - + {this.props.attribute.uri == "rdf:type" || this.props.attribute.uri == "rdfs:label" ? : } +
{form}
@@ -258,11 +216,10 @@ export default class AttributeBox extends Component { return (
- +
- - - + +
{form}
@@ -310,12 +267,11 @@ export default class AttributeBox extends Component { return (
- +
- - - - + + +
{form}
@@ -356,11 +312,10 @@ export default class AttributeBox extends Component { return (
- +
- - - + +
{form}
@@ -434,11 +389,10 @@ export default class AttributeBox extends Component { return (
- +
- - - + +
{form}
diff --git a/askomics/react/src/routes/form_edit/query.jsx b/askomics/react/src/routes/form_edit/query.jsx index 88aeeb44..a77207ac 100644 --- a/askomics/react/src/routes/form_edit/query.jsx +++ b/askomics/react/src/routes/form_edit/query.jsx @@ -5,6 +5,7 @@ import { Redirect } from 'react-router-dom' import ErrorDiv from '../error/error' import WaitingDiv from '../../components/waiting' import update from 'react-addons-update' +import ReactTooltip from "react-tooltip"; import AttributeBox from './attribute' import Entity from './entity' import ResultsTable from '../sparql/resultstable' @@ -267,6 +268,7 @@ export default class FormEditQuery extends Component { saveIcon: "play", waiting: waiting }) + ReactTooltip.rebuild(); } // Preview results and Launch query buttons ------- @@ -385,12 +387,21 @@ export default class FormEditQuery extends Component { let Entities = [] let previewButton let entityMap = new Map() + let tooltips = ( +
+ Mark attribute as a form attribute + Link this attribute to another + Show all values, including empty values. + Exclude categories, instead of including + Display attribute value in the results +
+ ) if (!this.state.waiting) { this.state.graphState.attr.forEach(attribute => { if (attribute.form) { if (! entityMap.has(attribute.nodeId)){ - entityMap.set(attribute.nodeId, {entity_label: attribute.entityDisplayLabel, attributes:[]}) + entityMap.set(attribute.nodeId, {entity_label: attribute.entityDisplayLabel ? attribute.entityDisplayLabel : attribute.entityLabel, attributes:[]}) } entityMap.get(attribute.nodeId).attributes.push( Save // preview @@ -445,7 +456,7 @@ export default class FormEditQuery extends Component { return (
{redirectLogin} -

Query Builder

+

Form editor



@@ -453,6 +464,7 @@ export default class FormEditQuery extends Component {
{Entities} + {tooltips}
diff --git a/askomics/react/src/routes/integration/advancedoptions.jsx b/askomics/react/src/routes/integration/advancedoptions.jsx index 4a6c8988..d54375bf 100644 --- a/askomics/react/src/routes/integration/advancedoptions.jsx +++ b/askomics/react/src/routes/integration/advancedoptions.jsx @@ -41,6 +41,12 @@ export default class AdvancedOptions extends Component { +
@@ -55,5 +61,7 @@ AdvancedOptions.propTypes = { hideCustomUri: PropTypes.bool, customUri: PropTypes.string, hideDistantEndpoint: PropTypes.bool, - externalEndpoint: PropTypes.string + externalEndpoint: PropTypes.string, + handleChangeExternalGraph: PropTypes.function, + externalGraph: PropTypes.string } diff --git a/askomics/react/src/routes/integration/bedpreview.jsx b/askomics/react/src/routes/integration/bedpreview.jsx index 803ba86c..ad3f7269 100644 --- a/askomics/react/src/routes/integration/bedpreview.jsx +++ b/askomics/react/src/routes/integration/bedpreview.jsx @@ -21,7 +21,8 @@ export default class BedPreview extends Component { externalEndpoint: "", error: false, errorMessage: null, - status: null + status: null, + externalGraph: "" } this.cancelRequest this.integrate = this.integrate.bind(this) @@ -81,6 +82,14 @@ export default class BedPreview extends Component { }) } + handleChangeExternalGraph (event) { + this.setState({ + externalGraph: event.target.value, + publicTick: false, + privateTick: false + }) + } + render () { let privateIcon = @@ -91,9 +100,12 @@ export default class BedPreview extends Component { if (this.state.publicTick) { publicIcon = } - + let privateButton + if (this.props.config.user.admin || !this.props.config.singleTenant){ + privateButton = + } let publicButton - if (this.props.config.user.admin) { + if (this.props.config.user.admin || this.props.config.singleTenant) { publicButton = } @@ -116,14 +128,17 @@ export default class BedPreview extends Component {
this.handleChangeUri(p)} handleChangeEndpoint={p => this.handleChangeEndpoint(p)} + handleChangeExternalGraph={p => this.handleChangeExternalGraph(p)} + externalGraph={this.state.externalGraph} customUri={this.state.customUri} />
- + {privateButton} {publicButton}
diff --git a/askomics/react/src/routes/integration/csvtable.jsx b/askomics/react/src/routes/integration/csvtable.jsx index f8c0547e..dddd55ba 100644 --- a/askomics/react/src/routes/integration/csvtable.jsx +++ b/askomics/react/src/routes/integration/csvtable.jsx @@ -26,7 +26,8 @@ export default class CsvTable extends Component { externalEndpoint: "", error: false, errorMessage: null, - status: null + status: null, + externalGraph: "" } this.cancelRequest this.headerFormatter = this.headerFormatter.bind(this) @@ -91,6 +92,51 @@ export default class CsvTable extends Component { ) } + let ontoInput + + if (this.props.ontologies.length > 0){ + ontoInput = ( + + {this.props.ontologies.map(onto => { + return + })} + + ) + } + + if (colIndex == 1) { + return ( +
+ + {colInput} + + + + + + + + + + + + + + + + + + + + + + {ontoInput} + + +
+ ) + } + return (
@@ -113,6 +159,7 @@ export default class CsvTable extends Component { + {ontoInput}
@@ -167,6 +214,14 @@ export default class CsvTable extends Component { }) } + handleChangeExternalGraph (event) { + this.setState({ + externalGraph: event.target.value, + publicTick: false, + privateTick: false + }) + } + toggleHeaderForm(event) { this.setState({ header: update(this.state.header, { [event.target.id]: { input: { $set: true } } }) @@ -192,7 +247,7 @@ export default class CsvTable extends Component { formatter: (cell, row) => { let text = row[this.state.header[index]["name"]] if (this.utils.isUrl(text)) { - return {this.utils.truncate(this.utils.splitUrl(text), 25)} + return {this.utils.truncate(this.utils.splitUrl(text), 25)} } else { return this.utils.truncate(text, 25) } @@ -208,9 +263,12 @@ export default class CsvTable extends Component { if (this.state.publicTick) { publicIcon = } - + let privateButton + if (this.props.config.user.admin || !this.props.config.singleTenant){ + privateButton = + } let publicButton - if (this.props.config.user.admin) { + if (this.props.config.user.admin || this.props.config.singleTenant) { publicButton = } @@ -236,14 +294,17 @@ export default class CsvTable extends Component {
this.handleChangeUri(p)} handleChangeEndpoint={p => this.handleChangeEndpoint(p)} + handleChangeExternalGraph={p => this.handleChangeExternalGraph(p)} + externalGraph={this.state.externalGraph} customUri={this.state.customUri} />
- + {privateButton} {publicButton}
@@ -264,5 +325,6 @@ export default class CsvTable extends Component { CsvTable.propTypes = { file: PropTypes.object, - config: PropTypes.object + config: PropTypes.object, + ontologies: PropTypes.array } diff --git a/askomics/react/src/routes/integration/gffpreview.jsx b/askomics/react/src/routes/integration/gffpreview.jsx index 077ccf90..ecff25c9 100644 --- a/askomics/react/src/routes/integration/gffpreview.jsx +++ b/askomics/react/src/routes/integration/gffpreview.jsx @@ -18,7 +18,8 @@ export default class GffPreview extends Component { publicTick: false, privateTick: false, customUri: "", - externalEndpoint: "" + externalEndpoint: "", + externalGraph: "" } this.cancelRequest this.integrate = this.integrate.bind(this) @@ -90,6 +91,22 @@ export default class GffPreview extends Component { }) } + handleChangeRemoteGraph (event) { + this.setState({ + remoteGraph: event.target.value, + publicTick: false, + privateTick: false + }) + } + + handleChangeExternalGraph (event) { + this.setState({ + externalGraph: event.target.value, + publicTick: false, + privateTick: false + }) + } + render () { let privateIcon = @@ -100,8 +117,12 @@ export default class GffPreview extends Component { if (this.state.publicTick) { publicIcon = } + let privateButton + if (this.props.config.user.admin || !this.props.config.singleTenant){ + privateButton = + } let publicButton - if (this.props.config.user.admin) { + if (this.props.config.user.admin || this.props.config.singleTenant) { publicButton = } @@ -122,14 +143,17 @@ export default class GffPreview extends Component {
this.handleChangeUri(p)} handleChangeEndpoint={p => this.handleChangeEndpoint(p)} + handleChangeExternalGraph={p => this.handleChangeExternalGraph(p)} + externalGraph={this.state.externalGraph} customUri={this.state.customUri} />
- + {privateButton} {publicButton}
diff --git a/askomics/react/src/routes/integration/integration.jsx b/askomics/react/src/routes/integration/integration.jsx index ada6f4af..7d3f50f7 100644 --- a/askomics/react/src/routes/integration/integration.jsx +++ b/askomics/react/src/routes/integration/integration.jsx @@ -19,7 +19,8 @@ export default class Integration extends Component { errorMessage: null, config: this.props.location.state.config, filesId: this.props.location.state.filesId, - previewFiles: [] + previewFiles: [], + ontologies: this.props.location.state.config.ontologies } this.cancelRequest } @@ -74,7 +75,7 @@ export default class Integration extends Component { this.state.previewFiles.map(file => { console.log(file) if (file.type == 'csv/tsv') { - return + return } if (["rdf/ttl", "rdf/xml", "rdf/nt"].includes(file.type)) { return diff --git a/askomics/react/src/routes/integration/rdfpreview.jsx b/askomics/react/src/routes/integration/rdfpreview.jsx index 4d62c6e5..654747b4 100644 --- a/askomics/react/src/routes/integration/rdfpreview.jsx +++ b/askomics/react/src/routes/integration/rdfpreview.jsx @@ -24,6 +24,7 @@ export default class RdfPreview extends Component { privateTick: false, customUri: "", externalEndpoint: props.file.data.location ? props.file.data.location : "", + externalGraph: props.file.data.remote_graph ? props.file.data.remote_graph : "", error: false, errorMessage: null, status: null @@ -49,7 +50,8 @@ export default class RdfPreview extends Component { public: event.target.value == 'public', type: this.props.file.type, customUri: this.state.customUri, - externalEndpoint: this.state.externalEndpoint + externalEndpoint: this.state.externalEndpoint, + externalGraph: this.state.externalGraph } axios.post(requestUrl, data, { baseURL: this.props.config.proxyPath, cancelToken: new axios.CancelToken((c) => { this.cancelRequest = c }) }) .then(response => { @@ -85,6 +87,14 @@ export default class RdfPreview extends Component { }) } + handleChangeExternalGraph (event) { + this.setState({ + externalGraph: event.target.value, + publicTick: false, + privateTick: false + }) + } + guess_mode(type) { if (type == "rdf/ttl") { return "turtle" @@ -107,9 +117,12 @@ export default class RdfPreview extends Component { if (this.state.publicTick) { publicIcon = } - + let privateButton + if (this.props.config.user.admin || !this.props.config.singleTenant){ + privateButton = + } let publicButton - if (this.props.config.user.admin) { + if (this.props.config.user.admin || this.props.config.singleTenant) { publicButton = } @@ -139,12 +152,14 @@ export default class RdfPreview extends Component { config={this.props.config} handleChangeEndpoint={p => this.handleChangeEndpoint(p)} externalEndpoint={this.state.externalEndpoint} + handleChangeExternalGraph={p => this.handleChangeExternalGraph(p)} + externalGraph={this.state.externalGraph} handleChangeUri={p => this.handleChangeUri(p)} />
- + {privateButton} {publicButton}
diff --git a/askomics/react/src/routes/query/attribute.jsx b/askomics/react/src/routes/query/attribute.jsx index c26e8d4a..7f37204f 100644 --- a/askomics/react/src/routes/query/attribute.jsx +++ b/askomics/react/src/routes/query/attribute.jsx @@ -3,12 +3,14 @@ import axios from 'axios' import { Input, FormGroup, CustomInput, FormFeedback } from 'reactstrap' import { Redirect } from 'react-router-dom' import DatePicker from "react-datepicker"; +import ReactTooltip from "react-tooltip"; import ErrorDiv from '../error/error' import WaitingDiv from '../../components/waiting' import update from 'react-addons-update' import Visualization from './visualization' import PropTypes from 'prop-types' import Utils from '../../classes/utils' +import Autocomplete from '../../components/autocomplete' export default class AttributeBox extends Component { constructor (props) { @@ -32,6 +34,7 @@ export default class AttributeBox extends Component { this.toggleAddNumFilter = this.props.toggleAddNumFilter.bind(this) this.toggleAddDateFilter = this.props.toggleAddDateFilter.bind(this) this.handleDateFilter = this.props.handleDateFilter.bind(this) + this.cancelRequest } subNums (id) { @@ -45,6 +48,13 @@ export default class AttributeBox extends Component { return newStr } + + isRegisteredOnto () { + return this.props.config.ontologies.some(onto => { + return (onto.uri == this.props.entityUri && onto.type != "none") + }) + } + renderLinker () { let options = [] @@ -81,65 +91,6 @@ export default class AttributeBox extends Component { } } - renderUri () { - - let formIcon = 'attr-icon fas fa-bookmark inactive' - if (this.props.attribute.form) { - formIcon = 'attr-icon fas fa-bookmark ' - } - - let eyeIcon = 'attr-icon fas fa-eye-slash inactive' - if (this.props.attribute.visible) { - eyeIcon = 'attr-icon fas fa-eye' - } - - let linkIcon = 'attr-icon fas fa-unlink inactive' - if (this.props.attribute.linked) { - linkIcon = 'attr-icon fas fa-link' - } - - let selected_sign = { - '=': !this.props.attribute.negative, - "≠": this.props.attribute.negative - } - - let form - - if (this.props.attribute.linked) { - form = this.renderLinker() - } else { - form = ( - - - - - -
- - {Object.keys(selected_sign).map(type => { - return - })} - - - - Please filter with a valid URI or CURIE -
- ) - } - - return ( -
- -
- {this.props.config.user.admin ? : } : } - - -
- {form} -
- ) - } - renderText () { let formIcon = 'attr-icon fas fa-bookmark inactive' @@ -181,6 +132,36 @@ export default class AttributeBox extends Component { let form + let input + let attrIcons + + if (this.props.isOnto){ + attrIcons = ( +
+ +
+ ) + if (this.isRegisteredOnto() && this.props.attribute.uri == "rdfs:label"){ + input = ( + this.handleFilterValue(p)}/> + ) + } else { + input = () + } + + } else { + attrIcons = ( +
+ {this.props.config.user.admin ? : } + + {this.props.attribute.uri == "rdf:type" || this.props.attribute.uri == "rdfs:label" ? : } + +
+ ) + input = () + } + + if (this.props.attribute.linked) { form = this.renderLinker() } else { @@ -202,7 +183,7 @@ export default class AttributeBox extends Component { - + {input} @@ -212,12 +193,7 @@ export default class AttributeBox extends Component { return (
-
- {this.props.config.user.admin ? : } - - {this.props.attribute.uri == "rdf:type" || this.props.attribute.uri == "rdfs:label" ? : } - -
+ {attrIcons} {form}
) @@ -289,10 +265,10 @@ export default class AttributeBox extends Component {
- {this.props.config.user.admin ? : } - - - + {this.props.config.user.admin ? : } + + +
{form}
@@ -347,11 +323,11 @@ export default class AttributeBox extends Component {
- {this.props.config.user.admin ? : } - - - - + {this.props.config.user.admin ? : } + + + +
{form}
@@ -399,10 +375,10 @@ export default class AttributeBox extends Component {
- {this.props.config.user.admin ? : } - - - + {this.props.config.user.admin ? : } + + +
{form}
@@ -485,8 +461,8 @@ export default class AttributeBox extends Component {
{this.props.config.user.admin ? : } - - + +
{form}
@@ -534,5 +510,7 @@ AttributeBox.propTypes = { handleDateFilter: PropTypes.func, attribute: PropTypes.object, graph: PropTypes.object, - config: PropTypes.object + config: PropTypes.object, + isOnto: PropTypes.bool, + entityUri: PropTypes.string } diff --git a/askomics/react/src/routes/query/graphfilters.js b/askomics/react/src/routes/query/graphfilters.js index 2750c8d7..8dd4f4e0 100644 --- a/askomics/react/src/routes/query/graphfilters.js +++ b/askomics/react/src/routes/query/graphfilters.js @@ -47,7 +47,7 @@ export default class GraphFilters extends Component {
-
+
) @@ -57,6 +57,8 @@ export default class GraphFilters extends Component { GraphFilters.propTypes = { graph: PropTypes.object, current: PropTypes.object, + showFaldo: PropTypes.bool, handleFilterLinks: PropTypes.func, - handleFilterNodes: PropTypes.func -} \ No newline at end of file + handleFilterNodes: PropTypes.func, + handleFilterFaldo: PropTypes.func +} diff --git a/askomics/react/src/routes/query/ontolinkview.jsx b/askomics/react/src/routes/query/ontolinkview.jsx new file mode 100644 index 00000000..99e5e435 --- /dev/null +++ b/askomics/react/src/routes/query/ontolinkview.jsx @@ -0,0 +1,46 @@ +import React, { Component } from 'react' +import axios from 'axios' +import { Input, FormGroup, CustomInput, Col, Row, Button } from 'reactstrap' +import { Redirect } from 'react-router-dom' +import ErrorDiv from '../error/error' +import WaitingDiv from '../../components/waiting' +import update from 'react-addons-update' +import Visualization from './visualization' +import PropTypes from 'prop-types' + +export default class OntoLinkView extends Component { + constructor (props) { + super(props) + this.handleChangeOntologyType = this.props.handleChangeOntologyType.bind(this) + } + + + render () { + return ( +
+
Ontological Relation
+
+

Search on ...

+ + + + + +
+ + + + + + +  a term
+
+
+ ) + } +} + +OntoLinkView.propTypes = { + link: PropTypes.object, + handleChangeOntologyType: PropTypes.func, +} diff --git a/askomics/react/src/routes/query/query.jsx b/askomics/react/src/routes/query/query.jsx index 66624e0b..ac4000de 100644 --- a/askomics/react/src/routes/query/query.jsx +++ b/askomics/react/src/routes/query/query.jsx @@ -1,13 +1,15 @@ import React, { Component } from 'react' import axios from 'axios' -import { Alert, Button, Row, Col, ButtonGroup, Input, Spinner } from 'reactstrap' +import { Alert, Button, CustomInput, Row, Col, ButtonGroup, Input, Spinner } from 'reactstrap' import { Redirect } from 'react-router-dom' import ErrorDiv from '../error/error' import WaitingDiv from '../../components/waiting' import update from 'react-addons-update' +import ReactTooltip from "react-tooltip"; import Visualization from './visualization' import AttributeBox from './attribute' import LinkView from './linkview' +import OntoLinkView from './ontolinkview' import GraphFilters from './graphfilters' import ResultsTable from '../sparql/resultstable' import PropTypes from 'prop-types' @@ -40,7 +42,8 @@ export default class Query extends Component { // Preview icons disablePreview: false, - previewIcon: "table" + previewIcon: "table", + ontologies: this.props.location.state.config.ontologies } this.graphState = { @@ -50,6 +53,8 @@ export default class Query extends Component { } this.divHeight = 650 + this.showFaldo = true; + this.idNumber = 0 this.specialNodeIdNumber = 0 @@ -62,6 +67,7 @@ export default class Query extends Component { this.handleRemoveNode = this.handleRemoveNode.bind(this) this.handleFilterNodes = this.handleFilterNodes.bind(this) this.handleFilterLinks = this.handleFilterLinks.bind(this) + this.handleFilterFaldo = this.handleFilterFaldo.bind(this) } resetIcons() { @@ -208,6 +214,33 @@ export default class Query extends Component { }) } + isRemoteOnto (currentUri, targetUri) { + + let node = this.state.abstraction.entities.find(entity => { + return entity.uri == targetUri + }) + + if (! node){ + return false + } + + return node.ontology ? currentUri == targetUri ? "endNode" : "node" : false + } + + isOntoNode (currentId) { + + return this.graphState.nodes.some(node => { + return (node.id == currentId && node.ontology) + }) + } + + isOntoEndNode (currentId) { + + return this.graphState.nodes.some(node => { + return (node.id == currentId && node.ontology == "endNode") + }) + } + attributeExist (attrUri, nodeId) { return this.graphState.attr.some(attr => { return (attr.uri == attrUri && attr.nodeId == nodeId) @@ -240,6 +273,8 @@ export default class Query extends Component { let nodeAttributes = [] let isBnode = this.isBnode(nodeId) + let isOnto = this.isOntoNode(nodeId) + // if bnode without uri, first attribute is visible let firstAttrVisibleForBnode = isBnode @@ -255,7 +290,9 @@ export default class Query extends Component { humanNodeId: this.getHumanIdFromId(nodeId), uri: 'rdf:type', label: 'Uri', + displayLabel: 'Uri', entityLabel: this.getLabel(nodeUri), + entityDisplayLabel: this.getLabel(nodeUri), entityUris: [nodeUri, ], type: 'uri', faldo: false, @@ -265,7 +302,8 @@ export default class Query extends Component { form: false, negative: false, linked: false, - linkedWith: null + linkedWith: null, + ontology: isOnto }) } @@ -278,7 +316,9 @@ export default class Query extends Component { humanNodeId: this.getHumanIdFromId(nodeId), uri: 'rdfs:label', label: 'Label', + displayLabel: 'Label', entityLabel: this.getLabel(nodeUri), + entityDisplayLabel: this.getLabel(nodeUri), entityUris: [nodeUri, ], type: 'text', faldo: false, @@ -474,7 +514,12 @@ export default class Query extends Component { let specialNodeGroupId = incrementSpecialNodeGroupId ? incrementSpecialNodeGroupId : node.specialNodeGroupId + if (this.isOntoEndNode(node.id)){ + return + } + this.state.abstraction.relations.map(relation => { + let isOnto = this.isRemoteOnto(relation.source, relation.target) if (relation.source == node.uri) { if (this.entityExist(relation.target)) { targetId = this.getId() @@ -498,29 +543,30 @@ export default class Query extends Component { label: label, faldo: this.isFaldoEntity(relation.target), selected: false, - suggested: true + suggested: true, + ontology: isOnto }) // push suggested link this.graphState.links.push({ uri: relation.uri, - type: "link", + type: isOnto == "endNode" ? "ontoLink" : "link", sameStrand: this.nodeHaveStrand(node.uri) && this.nodeHaveStrand(relation.target), sameRef: this.nodeHaveRef(node.uri) && this.nodeHaveRef(relation.target), strict: true, id: linkId, - label: relation.label, + label: isOnto == "endNode" ? this.getOntoLabel(relation.uri) : relation.label, source: node.id, target: targetId, selected: false, suggested: true, - directed: true + directed: true, }) incrementSpecialNodeGroupId ? specialNodeGroupId += 1 : specialNodeGroupId = specialNodeGroupId } } } - if (relation.target == node.uri) { + if (relation.target == node.uri && ! isOnto) { if (this.entityExist(relation.source)) { sourceId = this.getId() linkId = this.getId() @@ -557,7 +603,7 @@ export default class Query extends Component { target: node.id, selected: false, suggested: true, - directed: true + directed: true, }) incrementSpecialNodeGroupId ? specialNodeGroupId += 1 : specialNodeGroupId = specialNodeGroupId } @@ -566,7 +612,7 @@ export default class Query extends Component { }) // Position - if (node.faldo) { + if (node.faldo && this.showFaldo) { this.state.abstraction.entities.map(entity => { if (entity.faldo) { let new_id = this.getId() @@ -585,7 +631,7 @@ export default class Query extends Component { label: entity.label, faldo: entity.faldo, selected: false, - suggested: true + suggested: true, }) // push suggested link this.graphState.links.push({ @@ -600,7 +646,7 @@ export default class Query extends Component { target: new_id, selected: false, suggested: true, - directed: true + directed: true, }) incrementSpecialNodeGroupId ? specialNodeGroupId += 1 : specialNodeGroupId = specialNodeGroupId } @@ -626,7 +672,9 @@ export default class Query extends Component { if (link.source.id == node1.id && link.target.id == node2.id) { newLink = { uri: link.uri, - type: ["included_in", "overlap_with"].includes(link.uri) ? "posLink" : "link", + // What's the point of this? + // type: ["included_in", "overlap_with"].includes(link.uri) ? "posLink" : "link", + type: link.type, sameStrand: this.nodeHaveStrand(node1.uri) && this.nodeHaveStrand(node2.uri), sameRef: this.nodeHaveRef(node1.uri) && this.nodeHaveRef(node2.uri), strict: true, @@ -636,14 +684,16 @@ export default class Query extends Component { target: node2.id, selected: false, suggested: false, - directed: true + directed: link.directed, } } if (link.source.id == node2.id && link.target.id == node1.id) { newLink = { uri: link.uri, - type: ["included_in", "overlap_with"].includes(link.uri) ? "posLink" : "link", + // What's the point of this? + // type: ["included_in", "overlap_with"].includes(link.uri) ? "posLink" : "link", + type: link.type, sameStrand: this.nodeHaveStrand(node1.uri) && this.nodeHaveStrand(node2.uri), sameRef: this.nodeHaveRef(node1.uri) && this.nodeHaveRef(node2.uri), strict: true, @@ -653,7 +703,7 @@ export default class Query extends Component { target: node1.id, selected: false, suggested: false, - directed: true + directed: link.directed, } } }) @@ -720,7 +770,7 @@ export default class Query extends Component { handleLinkSelection (clickedLink) { // Only position link are clickabl - if (clickedLink.type == "posLink") { + if (clickedLink.type == "posLink" || clickedLink.type == "ontoLink") { // case 1: link is selected, so deselect it if (clickedLink.selected) { // Update current and previous @@ -859,6 +909,7 @@ export default class Query extends Component { waiting: waiting }) console.log(this.graphState) + ReactTooltip.rebuild(); } initGraph () { @@ -983,6 +1034,17 @@ export default class Query extends Component { this.updateGraphState() } + // Filter Faldo -------------------------- + handleFilterFaldo (event) { + // Toggle filter + + this.showFaldo = !this.showFaldo + // Reset suggestion + this.removeAllSuggestion() + this.insertSuggestion(this.currentSelected) + this.updateGraphState() + } + // Attributes managment ----------------------- toggleVisibility (event) { this.graphState.attr.map(attr => { @@ -1269,6 +1331,27 @@ export default class Query extends Component { return result } + // Ontology link methods ----------------------------- + + handleChangeOntologyType (event) { + this.graphState.links.map(link => { + if (link.id == event.target.id) { + link.uri = event.target.value + link.label = this.getOntoLabel(event.target.value) + } + }) + this.updateGraphState() + } + + getOntoLabel (uri) { + let labels = {} + labels["http://www.w3.org/2000/01/rdf-schema#subClassOf"] = "is children of" + labels["http://www.w3.org/2000/01/rdf-schema#subClassOf*"] = "is descendant of" + labels["^http://www.w3.org/2000/01/rdf-schema#subClassOf"] = "is parents of" + labels["^http://www.w3.org/2000/01/rdf-schema#subClassOf*"] = "is ancestor of" + return labels[uri] + } + // ------------------------------------------------ // Preview results and Launch query buttons ------- @@ -1438,15 +1521,27 @@ export default class Query extends Component { let visualizationDiv let uriLabelBoxes let AttributeBoxes + let isOnto let linkView let previewButton + let faldoButton let launchQueryButton let removeButton let graphFilters + let tooltips = ( +
+ Mark attribute as a form attribute + Link this attribute to another + Show all values, including empty values. + Exclude categories, instead of including + Display attribute value in the results +
+ ) if (!this.state.waiting) { // attribute boxes (right view) only for node if (this.currentSelected) { + isOnto = this.isOntoNode(this.currentSelected.id) AttributeBoxes = this.state.graphState.attr.map(attribute => { if (attribute.nodeId == this.currentSelected.id && this.currentSelected.type == "node") { return ( @@ -1470,6 +1565,8 @@ export default class Query extends Component { handleFilterDateValue={p => this.handleFilterDateValue(p)} handleDateFilter={p => this.handleDateFilter(p)} config={this.state.config} + isOnto={isOnto} + entityUri={this.currentSelected.uri} /> ) } @@ -1498,6 +1595,24 @@ export default class Query extends Component { nodesHaveStrands={p => this.nodesHaveStrands(p)} /> } + + if (this.currentSelected.type == "ontoLink") { + + let link = Object.assign(this.currentSelected) + this.state.graphState.nodes.map(node => { + if (node.id == this.currentSelected.target) { + link.target = node + } + if (node.id == this.currentSelected.source) { + link.source = node + } + }) + + linkView = this.handleChangeOntologyType(p)} + /> + } } // visualization (left view) @@ -1531,6 +1646,12 @@ export default class Query extends Component { ) } + faldoButton = ( +
+ +
+ ) + // Filters graphFilters = ( Query Builder
- + {graphFilters} - + + {faldoButton} + + {removeButton} @@ -1578,6 +1702,7 @@ export default class Query extends Component { {uriLabelBoxes} {AttributeBoxes} {linkView} + {tooltips}
diff --git a/askomics/react/src/routes/query/visualization.jsx b/askomics/react/src/routes/query/visualization.jsx index 90ee0ef0..c2a62360 100644 --- a/askomics/react/src/routes/query/visualization.jsx +++ b/askomics/react/src/routes/query/visualization.jsx @@ -169,7 +169,7 @@ export default class Visualization extends Component { link.suggested ? ctx.setLineDash([this.lineWidth, this.lineWidth]) : ctx.setLineDash([]) let greenArray = ["included_in", "overlap_with"] - let unselectedColor = greenArray.indexOf(link.uri) >= 0 ? this.colorGreen : this.colorGrey + let unselectedColor = greenArray.indexOf(link.uri) >= 0 || link.type == "ontoLink" ? this.colorGreen : this.colorGrey let unselectedColorText = greenArray.indexOf(link.uri) >= 0 ? this.colorGreen : this.colorDarkGrey ctx.strokeStyle = link.selected ? this.colorFirebrick : unselectedColor diff --git a/askomics/react/src/routes/results/resultsfilestable.jsx b/askomics/react/src/routes/results/resultsfilestable.jsx index 3bde0dd2..d51aa5b9 100644 --- a/askomics/react/src/routes/results/resultsfilestable.jsx +++ b/askomics/react/src/routes/results/resultsfilestable.jsx @@ -28,7 +28,8 @@ export default class ResultsFilesTable extends Component { status: null, modalTracebackTitle: "", modalTracebackContent: "", - modalTraceback: false + modalTraceback: false, + console_enabled: false } this.utils = new Utils() this.handleSelection = this.handleSelection.bind(this) diff --git a/askomics/react/src/routes/sparql/resultstable.jsx b/askomics/react/src/routes/sparql/resultstable.jsx index f2592ee1..be61dde4 100644 --- a/askomics/react/src/routes/sparql/resultstable.jsx +++ b/askomics/react/src/routes/sparql/resultstable.jsx @@ -59,7 +59,7 @@ export default class ResultsTable extends Component { index: index, formatter: (cell, row) => { if (this.utils.isUrl(cell)) { - return {this.utils.splitUrl(cell)} + return {this.utils.splitUrl(cell)} } return cell }, diff --git a/askomics/react/src/routes/upload/filestable.jsx b/askomics/react/src/routes/upload/filestable.jsx index 7b399c19..2864fcb9 100644 --- a/askomics/react/src/routes/upload/filestable.jsx +++ b/askomics/react/src/routes/upload/filestable.jsx @@ -3,6 +3,7 @@ import axios from 'axios' import BootstrapTable from 'react-bootstrap-table-next' import paginationFactory from 'react-bootstrap-table2-paginator' import cellEditFactory from 'react-bootstrap-table2-editor' +import {Badge} from 'reactstrap' import WaitingDiv from '../../components/waiting' import Utils from '../../classes/utils' import PropTypes from 'prop-types' @@ -88,6 +89,20 @@ export default class FilesTable extends Component { formatter: (cell, row) => { return this.utils.humanFileSize(cell, true) }, sort: true, editable: false + }, { + dataField: 'status', + text: 'File status', + formatter: (cell, row) => { + if (cell == 'downloading') { + return Downloading + } + if (cell == 'available') { + return Available + } + return Error + }, + sort: true, + editable: false }] let defaultSorted = [{ diff --git a/askomics/react/src/routes/upload/uploadurlform.jsx b/askomics/react/src/routes/upload/uploadurlform.jsx index 28646b68..ce631744 100644 --- a/askomics/react/src/routes/upload/uploadurlform.jsx +++ b/askomics/react/src/routes/upload/uploadurlform.jsx @@ -45,8 +45,8 @@ export default class UploadUrlForm extends Component { this.setState({ disabled: true, progressAnimated: true, - progressValue: 99, - progressDisplay: "99 %", + progressValue: 0, + progressDisplay: "0 %", progressColor: "success" }) @@ -96,7 +96,7 @@ export default class UploadUrlForm extends Component { {this.state.progressDisplay}
- +
diff --git a/askomics/static/about.html b/askomics/static/about.html index 4b1fc22e..8c8b1402 100644 --- a/askomics/static/about.html +++ b/askomics/static/about.html @@ -12,7 +12,7 @@

What is AskOmics?

Visit askomics.org to learn how to use and deploy AskOmics.

-

Usefull links

+

Useful links

Docs diff --git a/askomics/static/css/askomics.css b/askomics/static/css/askomics.css index 7f7bb842..2d6a4065 100644 --- a/askomics/static/css/askomics.css +++ b/askomics/static/css/askomics.css @@ -276,4 +276,37 @@ button.input-with-icon { display: block; } -/***********************************************************************/ \ No newline at end of file +/***********************************************************************/ + + +.react-autosuggest__suggestions-container--open { + background-clip: padding-box; + background-color: #fff; + border: 1px solid rgba(0,0,0,0.15); + bottom: auto; + box-shadow: 0 6px 12px rgba(0,0,0,0.175); + display: block; + font-size: 14px; + list-style: none; + padding: 1px; + position: absolute; + text-align: left; + z-index: 20000; +} + +.react-autosuggest__suggestions-list { + margin: 0; + padding: 0; + list-style-type: none; +} + +.react-autosuggest__suggestion { + cursor: pointer; + padding: 10px; + min-width: 100px; +} + +.react-autosuggest__suggestion--highlighted { + background-color: #0356fc; + color: #fff; +} diff --git a/askomics/tasks.py b/askomics/tasks.py index e0059151..ee048d3e 100644 --- a/askomics/tasks.py +++ b/askomics/tasks.py @@ -44,10 +44,10 @@ def integrate(self, session, data, host_url): error: True if error, else False errorMessage: the error message of error, else an empty string """ - files_handler = FilesHandler(app, session, host_url=host_url, external_endpoint=data["externalEndpoint"], custom_uri=data["customUri"]) + files_handler = FilesHandler(app, session, host_url=host_url, external_endpoint=data["externalEndpoint"], custom_uri=data["customUri"], external_graph=data['externalGraph']) files_handler.handle_files([data["fileId"], ]) - public = data.get("public", False) if session["user"]["admin"] else False + public = (data.get("public", False) if session["user"]["admin"] else False) or app.iniconfig.getboolean("askomics", "single_tenant", fallback=False) for file in files_handler.files: @@ -151,20 +151,28 @@ def query(self, session, info): info["celery_id"] = self.request.id result = Result(app, session, info, force_no_db=True) + query = SparqlQuery(app, session, info["graph_state"]) + query.build_query_from_json(preview=False, for_editor=False) + federated = query.is_federated() + result.populate_db(query.graphs, query.endpoints) + + info["query"] = query.sparql + info["graphs"] = query.graphs + info["endpoints"] = query.endpoints + info["federated"] = federated + info["selects"] = query.selects + # Save job in database database result.set_celery_id(self.request.id) result.update_db_status("started", update_celery=True, update_date=True) # launch query - query = SparqlQuery(app, session, info["graph_state"]) - query.build_query_from_json(for_editor=False) - - headers = query.selects + headers = info["selects"] results = [] - if query.graphs: - query_launcher = SparqlQueryLauncher(app, session, get_result_query=True, federated=query.federated, endpoints=query.endpoints) - headers, results = query_launcher.process_query(query.sparql, isql_api=True) + if info["graphs"] or app.iniconfig.getboolean("askomics", "single_tenant", fallback=False): + query_launcher = SparqlQueryLauncher(app, session, get_result_query=True, federated=info["federated"], endpoints=info["endpoints"]) + headers, results = query_launcher.process_query(info["query"], isql_api=True) # write result to a file file_size = result.save_result_in_file(headers, results) @@ -288,3 +296,18 @@ def send_mail_new_user(self, session, user): """ local_auth = LocalAuth(app, session) local_auth.send_mail_to_new_user(user) + + +@celery.task(bind=True, name="download_file") +def download_file(self, session, url): + """Send a mail to the new user + + Parameters + ---------- + session : dict + AskOmics session + user : dict + New user + """ + files = FilesHandler(app, session) + files.download_url(url, download_file.request.id) diff --git a/config/askomics.ini.template b/config/askomics.ini.template index e22d88a2..5e75e378 100644 --- a/config/askomics.ini.template +++ b/config/askomics.ini.template @@ -12,9 +12,9 @@ debug = false debug_ttl = false # If Askomics is running under a sub path (like http://example.org/askomics, subpath is /askomics) -#reverse_proxy_path = +#reverse_proxy_path = -# subtitle = +# subtitle = footer_message = Welcome to AskOmics! #front_message= @@ -61,12 +61,12 @@ instance_url = http://localhost:5000 # If set, host, port and sender are mandatory. # user and password are optional # connection: starttls or nothing -#smtp_host = -#smtp_port = -#smtp_sender = -#smtp_user = -#smtp_password = -#smtp_connection = +#smtp_host = +#smtp_port = +#smtp_sender = +#smtp_user = +#smtp_password = +#smtp_connection = # LDAP ldap_auth = false @@ -80,16 +80,20 @@ ldap_username_attribute = uid ldap_first_name_attribute = givenName ldap_surname_attribute = sn ldap_mail_attribute = mail -#ldap_password_reset_link = -#ldap_account_link = +#ldap_password_reset_link = +#ldap_account_link = + +# Max results returned for autocompletion +autocomplete_max_results = 10 + [triplestore] # name of the triplestore, can be virtuoso or fuseki triplestore = virtuoso # Sparql endpoint -endpoint = http://localhost:8890/sparql +endpoint = http://localhost:8890/sparql-auth # Sparql updatepoint -updatepoint = http://localhost:8890/sparql +updatepoint = http://localhost:8890/sparql-auth # Isql API # If triplestore is virtuoso, set the (optional) isql api for fastest graph deletion #isqlapi = http://localhost:5050 @@ -98,8 +102,10 @@ updatepoint = http://localhost:8890/sparql # Triplestore credentials username = dba password = dba +# Http auth method for sparqlwrapper: basic or digest (virtuoso require digest) +http_auth = digest # If the triplesotre and askomics are on different network, the loadurl is askomics url accessible by the triplesotre -# load_url = +# load_url = upload_method = load # Number of triple to integrate in one request chunk_size = 60000 @@ -122,6 +128,10 @@ preview_limit = 25 # Triplestore max rows limit # result_set_max_rows = 10000 +# Single tenant means all graphs are public +# All queries are launched on all graphes (speedup queries) +single_tenant=False + [federation] # Query engine can be corese or fedx #query_engine = corese diff --git a/config/askomics.test.ini b/config/askomics.test.ini index 5609a185..6d9bd17c 100644 --- a/config/askomics.test.ini +++ b/config/askomics.test.ini @@ -11,7 +11,7 @@ result_backend = redis://localhost:6380 debug = false debug_ttl = false -# subtitle = +# subtitle = footer_message = Test #front_message= @@ -55,12 +55,12 @@ instance_url = http://localhost:5000 # If set, host, port and sender are mandatory. # user and password are optional # connection: starttls or nothing -#smtp_host = -#smtp_port = -#smtp_sender = -#smtp_user = -#smtp_password = -#smtp_connection = +#smtp_host = +#smtp_port = +#smtp_sender = +#smtp_user = +#smtp_password = +#smtp_connection = # LDAP ldap_auth = false @@ -74,16 +74,17 @@ ldap_username_attribute = uid ldap_first_name_attribute = givenName ldap_surname_attribute = sn ldap_mail_attribute = mail -#ldap_password_reset_link = -#ldap_account_link = +#ldap_password_reset_link = +#ldap_account_link = +autocomplete_max_results = 20 [triplestore] # name of the triplestore, can be virtuoso or fuseki triplestore = virtuoso # Sparql endpoint -endpoint = http://localhost:8891/sparql +endpoint = http://localhost:8891/sparql-auth # Sparql updatepoint -updatepoint = http://localhost:8891/sparql +updatepoint = http://localhost:8891/sparql-auth # Isql API # If triplestore is virtuoso, set the (optional) isql api for fastest graph deletion isqlapi = http://localhost:5051 @@ -92,8 +93,10 @@ isqlapi = http://localhost:5051 # Triplestore credentials username = dba password = dba -# If the triplesotre and askomics are on different network, the loadurl is askomics url accessible by the triplesotre -# load_url = +# Http auth method for sparqlwrapper: basic or digest (virtuoso require digest) +http_auth = digest +# If the triplestore and askomics are on different network, the loadurl is askomics url accessible by the triplesotre +# load_url = upload_method = insert # Number of triple to integrate in one request chunk_size = 60000 @@ -116,6 +119,8 @@ preview_limit = 25 # Triplestore max rows limit result_set_max_rows = 10000 +single_tenant=False + [federation] # Query engine can be corese or fedx query_engine = corese @@ -128,3 +133,5 @@ local_endpoint=http://askomics-host:8891/sparql # Sentry dsn to report python and js errors in a sentry instance # server_dsn = https://00000000000000000000000000000000@exemple.org/1 # frontend_dsn = https://00000000000000000000000000000000@exemple.org/2 + +# Max results returned for autocompletion diff --git a/docker/Dockerfile b/docker/Dockerfile index c8b7ce9f..10c4902e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM askomics/flaskomics-base:4.0.0-alpine3.9 AS builder +FROM quay.io/askomics/flaskomics-base:4.0.0-alpine3.13 AS builder MAINTAINER "Xavier Garnier " COPY . /askomics @@ -7,10 +7,10 @@ WORKDIR /askomics RUN make clean-config fast-install build # Final image -FROM alpine:3.9 +FROM alpine:3.13 WORKDIR /askomics -RUN apk add --no-cache make python3 bash git libc-dev libstdc++ nodejs nodejs-npm openldap-dev +RUN apk add --no-cache make python3 bash git libc-dev libstdc++ nodejs-current npm openldap-dev COPY --from=builder /askomics . EXPOSE 5000 diff --git a/docker/DockerfileAll b/docker/DockerfileAll index fb9709cc..65224511 100644 --- a/docker/DockerfileAll +++ b/docker/DockerfileAll @@ -1,5 +1,5 @@ # Build AskOmics -FROM askomics/flaskomics-base:4.0.0-alpine3.9 AS askomics_builder +FROM quay.io/askomics/flaskomics-base:4.0.0-alpine3.13 AS askomics_builder MAINTAINER "Xavier Garnier " COPY . /askomics @@ -14,7 +14,7 @@ FROM xgaia/corese:20.6.11 AS corese_builder FROM askomics/virtuoso:7.2.5.1 AS virtuoso_builder # Final image -FROM alpine:3.8 +FROM alpine:3.13 ENV MODE="prod" \ NTASKS="5" \ @@ -35,7 +35,7 @@ RUN apk add --no-cache openssl py-pip && \ apk --no-cache add --update openjdk11 --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community && \ mkdir /corese && \ apk add --no-cache redis sqlite && \ - apk add --no-cache make python3 bash git libc-dev libstdc++ nodejs nodejs-npm openldap-dev + apk add --no-cache make python3 bash git libc-dev libstdc++ nodejs-current nodejs openldap-dev COPY --from=virtuoso_builder /usr/local/virtuoso-opensource /usr/local/virtuoso-opensource COPY --from=virtuoso_builder /virtuoso /virtuoso diff --git a/docker/DockerfileCelery b/docker/DockerfileCelery index d2df8601..db08157a 100644 --- a/docker/DockerfileCelery +++ b/docker/DockerfileCelery @@ -1,4 +1,4 @@ -FROM askomics/flaskomics-base:4.0.0-alpine3.9 AS builder +FROM quay.io/askomics/flaskomics-base:4.0.0-alpine3.13 AS builder MAINTAINER "Xavier Garnier " COPY . /askomics @@ -7,7 +7,7 @@ WORKDIR /askomics RUN make clean-config fast-install # Final image -FROM alpine:3.9 +FROM alpine:3.13 WORKDIR /askomics RUN apk add --no-cache make python3 bash git libc-dev libstdc++ openldap-dev diff --git a/docs/abstraction.md b/docs/abstraction.md index dec0278b..208ff7ad 100644 --- a/docs/abstraction.md +++ b/docs/abstraction.md @@ -1,6 +1,10 @@ During integration of TSV/CSV, GFF and BED files, AskOmics create RDF triples that describe the data. This set of triple are called *Abstraction*. *Abstraction* is a set of RDF triples who describes the data. This triples define *Entities*, *Attributes* and *Relations*. Abstraction is used to build the *Query builder*. -Raw RDF can be integrated into AskOmics. In this case, abstraction have to be built manually. The following documentation explain how to write an AskOmics abstraction in turtle format. +Raw RDF can be integrated into AskOmics. In this case, abstraction have to be built manually. The following documentation explain how to write manually write an AskOmics abstraction in turtle format. + +!!! warning + Starting from 4.4, attributes & relations are defined using blank nodes, to avoid overriding information + They are linked to the correct node using askomics:uri # Namespaces @@ -10,16 +14,19 @@ AskOmics use the following namespaces. PREFIX : PREFIX askomics: PREFIX dc: +PREFIX dcat: PREFIX faldo: PREFIX owl: PREFIX prov: PREFIX rdf: PREFIX rdfs: +PREFIX skos: PREFIX xsd: +PREFIX dcat: ```
-!!! info +!!! note "Info" Namespaces `:` and `askomics:` are defined in the AskOmics config file (`config/askomics.ini`) # Entity @@ -31,12 +38,17 @@ The entity is a class. In the query builder, it is represented with a graph node :EntityName rdf:type owl:Class . :EntityName rdf:type askomics:startPoint . :EntityName rdfs:label "EntityName" . +# Optional (use if no label) +:EntityName askomics:instancesHaveNoLabels true . ```
-!!! info +!!! note "Info" `:EntityName rdf:type :startPoint` is not mandatory. If the entity have this triple, a query can be started with this this node. +!!! note "Info" + `:EntityName rdfs:label "EntityName"` is optional. If your entity has no label, you can use `:EntityName askomics:instancesHaveNoLabels true` instead. In the query view, the label tab will not be displayed. + # Attributes Attributes are linked to an entity. 3 types of attributes are used in AskOmics: *numeric*, *text* and *category*. @@ -44,19 +56,21 @@ Attributes are linked to an entity. 3 types of attributes are used in AskOmics: ## Numeric ```turtle -:numeric_attribute rdf:type owl:DatatypeProperty . -:numeric_attribute rdfs:label "numeric_attribute" . -:numeric_attribute rdfs:domain :EntityName . -:numeric_attribute rdfs:range xsd:decimal . +_:blank rdf:type owl:DatatypeProperty . +_:blank rdfs:label "numeric_attribute" . +_:blank rdfs:domain :EntityName . +_:blank rdfs:range xsd:decimal . +_:blank askomics:uri :numeric_attribute_uri ``` ## Text ```turtle -:text_attribute rdf:type owl:DatatypeProperty . -:text_attribute rdfs:label "text_attribute" . -:text_attribute rdfs:domain :EntityName . -:text_attribute rdfs:range xsd:string . +_:blank rdf:type owl:DatatypeProperty . +_:blank rdfs:label "text_attribute" . +_:blank rdfs:domain :EntityName . +_:blank rdfs:range xsd:string . +_:blank askomics:uri :text_attribute_uri ``` ## Category @@ -64,11 +78,13 @@ Attributes are linked to an entity. 3 types of attributes are used in AskOmics: Category is an attribute that have a limited number of values. All values of the category are stored in the abstraction. The ttl below represent a category `category_attribute` who can takes 2 values: `value_1` and `value_2`. ```turtle -:category_attribute rdf:type owl:ObjectProperty . -:category_attribute rdf:type askomics:AskomicsCategory . -:category_attribute rdfs:label "category_attribute" . -:category_attribute rdfs:domain :EntityName . -:category_attribute rdfs:range :category_attributeCategory . +_:blank rdf:type owl:ObjectProperty . +_:blank rdf:type askomics:AskomicsCategory . +_:blank rdfs:label "category_attribute" . +_:blank rdfs:domain :EntityName . +_:blank rdfs:range :category_attributeCategory . +_:blank askomics:uri :category_attribute_uri + :category_attributeCategory askomics:category :value_1 . :category_attributeCategory askomics:category :value_2 . @@ -101,12 +117,13 @@ Four FALDO attributes are supported by AskOmics: reference, strand, start and en A faldo:reference attribute derive from a Category attribute. ```turtle -:reference_attribute rdf:type askomics:faldoReference . -:reference_attribute rdf:type askomics:AskomicsCategory . -:reference_attribute rdf:type owl:ObjectProperty . -:reference_attribute rdfs:label "reference_attribute" . -:reference_attribute rdfs:domain :EntityName . -:reference_attribute rdfs:range :reference_attributeCategory. +_:blank rdf:type askomics:faldoReference . +_:blank rdf:type askomics:AskomicsCategory . +_:blank rdf:type owl:ObjectProperty . +_:blank rdfs:label "reference_attribute" . +_:blank rdfs:domain :EntityName . +_:blank rdfs:range :reference_attributeCategory. +_:blank askomics:uri :reference_attribute ``` ### faldo:strand @@ -114,12 +131,13 @@ A faldo:reference attribute derive from a Category attribute. faldo:strand is also a category. ```turtle -:strand_attribute rdf:type askomics:faldoStrand . -:strand_attribute rdf:type askomics:AskomicsCategory . -:strand_attribute rdf:type owl:ObjectProperty . -:strand_attribute rdfs:label "strand_attribute" . -:strand_attribute rdfs:domain :EntityName . -:strand_attribute rdfs:range :strand_attributeCategory. +_:blank rdf:type askomics:faldoStrand . +_:blank rdf:type askomics:AskomicsCategory . +_:blank rdf:type owl:ObjectProperty . +_:blank rdfs:label "strand_attribute" . +_:blank rdfs:domain :EntityName . +_:blank rdfs:range :strand_attributeCategory. +_:blank askomics:uri :strand_attribute ``` ### faldo:start and faldo:end @@ -127,29 +145,102 @@ faldo:strand is also a category. faldo:start and faldo:end are numeric attributes. ```turtle -:start_attribute rdf:type askomics:faldoStart . -:start_attribute rdf:type owl:DatatypeProperty . -:start_attribute rdfs:label "start_attribute" . -:start_attribute rdfs:domain :EntityName . -:start_attribute rdfs:range xsd:decimal . +_:blank rdf:type askomics:faldoStart . +_:blank rdf:type owl:DatatypeProperty . +_:blank rdfs:label "start_attribute" . +_:blank rdfs:domain :EntityName . +_:blank rdfs:range xsd:decimal . +_:blank askomics_uri :start_attribute ``` ```turtle -:end_attribute rdf:type askomics:faldoEnd . -:end_attribute rdf:type owl:DatatypeProperty . -:end_attribute rdfs:label "end_attribute" . -:end_attribute rdfs:domain :EntityName . -:end_attribute rdfs:range xsd:decimal . +_:blank rdf:type askomics:faldoEnd . +_:blank rdf:type owl:DatatypeProperty . +_:blank rdfs:label "end_attribute" . +_:blank rdfs:domain :EntityName . +_:blank rdfs:range xsd:decimal . +_:blank askomics:uri :end_attribute ``` # Relations -Entities are linked between them with relations. Relations are displayed with arrows between nodes on the query builder. The following turtle explain how relations are described. +Entities are linked between them with relations. Relations are displayed with arrows between nodes on the query builder. The following turtle explain how relations are described. To avoid overwriting information, relations are described using a blank node. The relation `:RelationExample`, linking `EntitySource` to `EntityTarget`, with the label *relation_example*, will be defined as follows: + +```turtle +_:blank askomics:uri :RelationExample . +_:blank a askomics:AskomicsRelation . +_:blank a owl:ObjectProperty . +_:blank rdfs:label "relation_example" . +_:blank rdfs:domain :EntitySource . +_:blank rdfs:range :EntityTarget . +# Optional information for future-proofing +_:blank dcat:endpointURL . +_:blank dcat:dataset . +``` + +# Federation + +To describe a remote dataset, you can either fill out the "Distant endpoint" and optionally the "Distant graph" fields when integrating an RDF dataset, or you could add description triples in your dataset, as follows: + +```turtle +_:blank ns1:atLocation "https://my_remote_endpoint/sparql" . +_:blank dcat:Dataset . +``` + +# Ontologies + +Ontologies needs to be are defined as follows: + +```turtle + rdf:type askomics:ontology . + rdf:type owl:Ontology . +:EntityName rdfs:label "OntologyLabel" . +``` + +!!! note "Info" + Make sure to use `rdfs:label`, even if your classes use another type of label. + +You will then need to add any relations and attributes using blank nodes: + +```turtle +# SubCLassOf relation +_:blank1 a askomics:AskomicsRelation . +_:blank1 askomics:uri rdfs:subClassOf . +_:blank1 rdfs:label "subClassOf" . +_:blank1 rdfs:domain . +_:blank1 rdfs:range . + +# Ontology attribute 'taxon rank' +_:blank2 a owl:DatatypeProperty . +_:blank2 askomics:uri . +_:blank2 rdfs:label "Taxon rank" . +_:blank2 rdfs:domain . +_:blank2 rdfs:range xsd:string . +``` + +With these triples, your ontology will appears in the graph view. +You can then either add your classes directly, or refer to an external endpoint / graph + +## Adding the classes directly + +Here is an example of an ontological class: + +```turtle + rdf:type owl:Class . + rdfs:subClassOf . + "order" . + skos:prefLabel "OntologyLabel" . +``` + +!!! note "Info" + The label does not need to be `rdfs:label`, but you will need to specify the correct label in the UI. + +## Using federated queries + +If instead you have access to a remote SPARQL endpoint, you can indicate it here: ```turtle -:relation_example a askomics:AskomicsRelation . -:relation_example a owl:ObjectProperty . -:relation_example rdfs:label "relation_example" . -:relation_example rdfs:domain :EntityName . -:relation_example rdfs:range :EntityName_2 . +_:blank ns1:atLocation "https://my_remote_endpoint/sparql" . +# Optional: Set a specific graph for remote queries +_:blank dcat:Dataset . ``` diff --git a/docs/ci.md b/docs/ci.md index 7fe6b072..1b201d19 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -1,4 +1,4 @@ -AskOmics continuous integration is composed of code linting and unit tests on the Python API. CI is launched automaticaly on the [askomics](https://github.com/askomics/flaskomics) repository on every pull requests. No PR will be merged if the CI fail. +AskOmics continuous integration includes code linting and unit tests on the Python API. CI is launched automaticaly on the [askomics](https://github.com/askomics/flaskomics) repository on every pull requests. No PR will be merged if the CI fail. # Setup CI environment diff --git a/docs/cli.md b/docs/cli.md new file mode 100644 index 00000000..3fffd0bb --- /dev/null +++ b/docs/cli.md @@ -0,0 +1,13 @@ +Starting from release 4.3.0, a CLI is available with the [askoclics](https://github.com/askomics/askoclics) python package. +This CLI relies on the AskOmics **API Key**, found in your Account management tab. + +The main goal of the CLI is to help automatize data upload and integration into an existing AskOmics instance. + +Both the python package and the bash command line currently include the following features: + +- File management (Upload, list, preview, integrate, delete) +- Dataset management (List and delete) +- Results management (List, preview results, download results, get sparql query, and delete) +- SPARQL management (Send SPARQL query) + +This library is currently a work in progress. diff --git a/docs/configure.md b/docs/configure.md index cc138e92..31132d21 100644 --- a/docs/configure.md +++ b/docs/configure.md @@ -29,7 +29,7 @@ All AskOmics configuration is set in `config/askomics.ini` files. When AskOmics - `disable_integration` (`true` or `false`): Disable integration to non admin users - `protect_public` (`true` or `false`): Public datasets and queries are visible only for logged users - `enable_sparql_console`(`true` or `false`): Allow non-admin logged users to use the sparql console. **This is unsafe.** - - `quota` (size): Default quota for new users + - `quota` (size): Default quota for new users (can be customized individually later) - `github` (url): Github repository URL - `instance_url` (url): Instance URL. Used to send link by email when user reset his password - `smtp_host` (url): SMTP host url @@ -51,7 +51,7 @@ All AskOmics configuration is set in `config/askomics.ini` files. When AskOmics - `ldap_mail_attribute` (string): Mail attribute - `ldap_password_reset_link` (url): Link to manage the LDAP password - `ldap_account_link` (url): Link to the LDAP account manager - + - `autocomplete_max_results` (int): Max results queries by autocompletion - `virtuoso` @@ -73,6 +73,7 @@ All AskOmics configuration is set in `config/askomics.ini` files. When AskOmics - `namespace_internal` (url): AskOmics namespace for internal triples. Correspond to the `askomics:` prefix. You should change this to your instance url if you want your URIs to be resolved. - `preview_limit` (int): Number of line to be previewed in the results page - `result_set_max_rows` (int): Triplestore max row. Must be the same as SPARQL[ResultSetMaxRows] in virtuoso.ini config + - `single_tenant` (bool): Enable [single tenant mode](/manage/#single-tenant-mode) - `federation` diff --git a/docs/console.md b/docs/console.md new file mode 100644 index 00000000..59993c7e --- /dev/null +++ b/docs/console.md @@ -0,0 +1,51 @@ +A SPARQL console is available through AskOmics, allowing you to send direct SPARQL queries to the endpoint. + +!!! warning + The console access is restricted to **logged users** + +!!! warning + The default AskOmics configuration restrict SPARQL edition and query to the administrators. + This can be disabled with the *enable_sparql_console* configuration option. + +![SPARQL query generated by AskOmics](img/sparql.png){: .center} + +You can reach this console in two ways: + +# Console access + +- By clicking SPARQL of an existing result in the *Results* page + - The console will be pre-filled with the generated SPARQL query of the result +- Simply heading to the "/sparql" URL + - The console will be pre-filled with a default SPARQL query + +# Editing your query + +You can edit the SPARQL query through the console to customize your query. + +## Advanced options + +The **Advanced options** tab allows you to customize *how* the query will be sent. +Namely, you will be able to select which endpoints and datasets the query will use, allowing you to fine-tune the query + +- For example, you can exclude some datasets to restrict the results. + +!!! note "Info" + When accessing the console through the "Results" page, the datasets of interest (relevant to the query) will already be selected. Make sure to customize the selection if you modify the query. + +!!! note "Info" + When accessing the console directly, all datasets will be selected (which can increase query time) + +# Launching query + +If you have **editing privileges** (either as an administrator, or through the configuration key), you will be able to either preview or save the query, much like a "normal" query. + +If you save the query, it will appears as a normal result in the "Results" tab. The basic functionalities (templates, download) will be available. + +!!! warning + The Redo button will be disabled for results created from the console + +!!! warning + The generated *template* will redirect to the SPARQL console. It means + + - Non-logged users will not be able to use it + - Only logged users with **editing privileges** will be able to launch the query diff --git a/docs/contribute.md b/docs/contribute.md index 4e8ec20c..82b9a446 100644 --- a/docs/contribute.md +++ b/docs/contribute.md @@ -14,7 +14,7 @@ git checkout -b my_new_feature Commit and push your modification to your [fork](https://help.github.com/articles/pushing-to-a-remote/). If your changes modify code, please ensure that is conform to [AskOmics style](#coding-style-guidlines) -Write tests for your changes, and make sure that they [passes](dev-deployment.md#launch-continuous-integration-locally). +Write tests for your changes, and make sure that they [passe](dev-deployment.md#launch-continuous-integration-locally). Open a pull request against the `dev` branch of flaskomics. The message of your pull request should describe your modifications (why and how). @@ -29,10 +29,10 @@ Ensure all user-enterable strings are unicode capable. Use only English language ### Python -We follow [PEP-8](https://www.python.org/dev/peps/pep-0008/), with particular emphasis on the parts about knowing when to be inconsistent, and readability being the ultimate goal. +We follow the [PEP-8](https://www.python.org/dev/peps/pep-0008/) coding convention. - Whitespace around operators and inside parentheses -- 4 spaces per indent, spaces, not tabs +- 4 spaces per indent (not tabs) - Include docstrings on your modules, class and methods - Avoid from module import \*. It can cause name collisions that are tedious to track down. - Class should be in `CamelCase`, methods and variables in `lowercase_with_underscore` diff --git a/docs/data.md b/docs/data.md index 655bfd3a..88d8253d 100644 --- a/docs/data.md +++ b/docs/data.md @@ -1,5 +1,182 @@ -In this tutorial, we will learn how to build CSV/TSV file for AskOmics. +# Uploading files +You can head to the *Files* tab to manage your files. From there, you will be able to upload new files (from your local computer, or a remote endpoint), and delete them. +!!! warning + Deleting files does not delete related datasets. -*-- Work in progress --* \ No newline at end of file + +# Data visibility + +By default, all your uploaded files and datasets are private. +If you have administrator privileges, you can select the Integrate (Public dataset) button during integration to make the dataset **Public** + +!!! note "Info" + *Public* datasets will be queriable by any user, including non-logged users. They will not be able to directly access the file, but generated entities will appear on the query graph (and on the starting screen for starting entities). + +!!! warning + Make sure your public datasets do not contain sensitive information. + + +# CSV/TSV files + +AskOmics will integrate a CSV/TSV file using its header. The *type* of each column will be predicted, but you will be able to modify it before integration. + +![CSV/TSV integration](img/csv_convert.png){: .center} + + +## Entity (first column) + +### Entity URI + +The first column of the file will manage the entity itself : the column name will become the entity name, and the values will become the entity's instances **URIs**. +**URIs** will be created as follows : + +* If the value is an **URL**, it will be integrated as it is. +* If the value is a [CURIE](https://www.w3.org/TR/2010/NOTE-curie-20101216/), it will be transformed into an URL before integration. The list of managed CURIE formats is available [here](https://github.com/askomics/flaskomics/blob/master/askomics/libaskomics/prefix.cc.json). +* Else, the value will be added to either AskOmics *namespace_data* value, or a custom base URI if specified in the integration form. + +!!! Warning + Unless you are trying to merge entities, make sure your URIs are unique across **both your personal and public datasets**. + +### Entity type + +The entity type can either be "starting entity", or "entity". If "starting entity", it may be used to start a query on the AskOmics homepage. Both types will appear as a node in the AskOmics interface. + +### Inheritance + +The entity can inherit the attributes and relations of a 'mother' entity. Meaning, you will be able to query the sub-entity on both its own, and its 'mother' attributes and relations. The 'mother' entity however will not have access to any 'daughter' attributes or relations. + +To setup inheritance, the **column name** needs to be formated as follows: +- *daughter_entity_name* < *mother_entity_name* (with the < symbol) + ie: *Custom_population* < *General population* + +!!! Warning + The values of this column must be an URI of the *mother* entity + +## Entity label (first and second column) + +To manually set an entity label, you can set the second column as a *Label* column. +The values of this column will be used as labels for the generated entities. + +!!! Warning + If a value is missing in the column, the label will be created based on the entity *URI*. (See below) + +If there is no *Label* column, the labels will be generated based on the URIs (The first column). + +* If the value is an **URL**, the last non-empty value after a "/" or "#" will be the label. +* If the value is a **CURIE**, the value after ":" will be the label +* Else, the raw value is the label + +!!! node "Info" + For example, a one-column CSV file with the column name "Gene", and the values "gene1", "rdfs:gene2" and "http://myurl/gene3/" will create the entity *Gene*, with two instances labelled *gene1*, *gene2* and *gene3*. + +## Attributes + +Each column after the first one will be integrated as an *attribute* of the entity. The column name will be set as the name of the attribute. +Several attribute types are available. The type of an attribute will dictate the way it will be managed in the query form (eg: text field, value selector...) + +!!! note 'Info' + AskOmics will try to guess the type of a column based on its name and its values. You will be able to set it manually if the auto-detected type doesn't fit. + +Attributes can be of the following types : + +### Base types + +- Numeric: if the values are numeric +- Text: if all values are strings +- Date: if all values are dates (using *dateutil.parser*) + - *Auto-detected terms are 'date', 'time', 'birthday', 'day'* +- Category: if there is a limited number of repeated values +- Boolean: if the values are binary ("True" and "False", or "0" and "1") + +!!! Warning + If the date format is ambiguous (eg: 01/01/2020), AskOmics will interpret it as *day/month/year* + +### FALDO types + +If the entity describe a locatable element on a genome (based on the FALDO ontology): + +- [Reference](http://biohackathon.org/resource/faldo#reference): chromosome *(Auto-detected terms : 'chr', 'ref', 'scaff')* +- [Strand](http://biohackathon.org/resource/faldo#StrandedPosition): strand *(Auto-detected terms : 'strand')* +- Start: start position *(Auto-detected term : 'start', 'begin')* +- End: end position *(Auto-detected terms : 'end', 'stop')* + +!!! Warning + To mark an entity as a *FALDO entity*, you need to provide **at least** a *Start* and *End* columns. + *Reference* and/or *Strand* are optional, but will enable more specific queries (eg: *Same reference* or *Same strand*) + +### Relations + +A column can also symbolize a relation to another entity. In this case, the column name must be of the form : + +- *relationName@RelatedEntityName* (with the @ symbol) + - ie: *Derives_from@Gene* + +Two types are available : + +- Directed: Relation from this entity to the targeted one *(e.g. A is B’s father, but B is not A’s father)* +- Symetric: Relation that works in both directions *(e.g. A loves B, and B loves A)* + +!!! Warning + The content of the column must be URIs of the related entity. + *(The related entity and its URIs may be created afterwards)* + +Linked URIs must match one of these three formats : + +- Full URI +- CURIE +- Simple value (the value will transformed into an URI with AskOmics *namespace_data* value) + +This link between entities will show up in the query screen, allowing users to query related entities. + +!!! note "Info" + **All** FALDO entities will be automatically linked with the *included_in* relation, without needing an explicit link. + You can still specify your own relations. + +!!! Warning + For federated queries, the syntax is slightly different. Please refer to [this page](abstraction.md#linking-your-own-data) for more information. + + +# GFF files + +!!! Warning + Only the *GFF3* format is managed by AskOmics. + +Each GFF file can be integrated into several entities. You will be able to select the entities you wish to integrate beforehand. Available entities are the values of the 'type' column of the GFF file. The relations between entities (eg: *Parents* or *Derives_from*) will also be integrated. + +![Integration interface for GFF files](img/gff_preview.png){: .center} + +Extracted attributes are the following : + +- Reference +- Strand +- Start +- End +- Any attribute in the *attributes* column + - *Parents* and *Derives_from* will be converted in relations + +!!! note "Info" + All entities extracted from GFF files are *FALDO entities*, and will be linked implicitly with the *included_in* relation. + +# BED files + +Each BED file will be integrated into one entity (the default entity name will be the file name, but it can be customized). + +Extracted attributes are the following : + +- Reference +- Strand +- Start +- End +- Score + +!!! note "Info" + All entities extracted from BED files are *FALDO entities*, and will be linked implicitly with the *included_in* relation. + +# TTL Files + +You can integrate TTL files in AskOmics, either to integrate your own data, or to enable [federated queries](federation.md) to remote endpoints. +In both case, you will need to generate or convert your data in AskOmics's format. + +This can be done either [manually](abstraction.md) or [automatically](federation.md#auto-generate-external-abstraction-with-abstractor) diff --git a/docs/dev-deployment.md b/docs/dev-deployment.md index da82a868..047ed4cf 100644 --- a/docs/dev-deployment.md +++ b/docs/dev-deployment.md @@ -1,8 +1,8 @@ -In development mode, AskOmics dependencies can be deployed with docker-compose, but AskOmics have to be running locally, on your dev machine. +In development mode, you can deploy AskOmics dependencies with docker-compose, but AskOmics itself should be running locally, on your development machine. # Prerequisites -Install dev dependencies +Install AskOmics dependencies ```bash @@ -28,7 +28,7 @@ apt install -y docker-compose dnf install -y docker-compose ``` -# Deploy dependencies +# Deploying dependencies We provide a `docker-compose` template to run external services used by AskOmics. Clone the [flaskomics-docker-compose](https://github.com/askomics/flaskomics-docker-compose) repository to use it. diff --git a/docs/docs.md b/docs/docs.md index ef0ea300..fe752ab6 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -1,6 +1,6 @@ -all the documentation (including what you are reading) can be found [here](https://flaskomics.readthedocs.io). Files are on the [AskOmics repository](https://github.com/askomics/flaskomics/tree/master/docs). +All the documentation (including what you are reading) can be found [here](https://flaskomics.readthedocs.io). Files are on the [AskOmics repository](https://github.com/askomics/flaskomics/tree/master/docs). -# Serve doc locally +# Serve the documentation locally First, [install askomics in dev mode](/dev-deployment/#install-askomics). @@ -9,6 +9,6 @@ Then, run ```bash make serve-doc ``` -Doc will be available at [localhost:8000](localhost:8000) +The documentation will be available at [localhost:8000](localhost:8000) -To change port, use `make serve-doc DOCPORT=8001` +To change the port, use `make serve-doc DOCPORT=8001` diff --git a/docs/federation.md b/docs/federation.md index 78478230..a33f294a 100644 --- a/docs/federation.md +++ b/docs/federation.md @@ -1,9 +1,11 @@ -A federated query is a query who involve several SPARQL endpoints. AskOmics have his dedicated endpoint for the integrated data, but it is also possible to query external resources. +A federated query is a query who involve several SPARQL endpoints. AskOmics uses its own dedicated endpoint for the integrated data, but it is also possible to query external resources. # Define an external endpoint -The first step is to define an external endpoint. External endpoint have their own description. To Display external entities, AskOmics need the *Abstraction* of the distant endpoint. This external abstraction can be build [automatically](#auto-generate-external-abstraction-with-abstractor) or [manually](abstraction.md). +The first step is to define an external endpoint. External endpoint have their own description. To display external entities, AskOmics need the *Abstraction* of the distant endpoint. + +This external abstraction can be build [automatically](#auto-generate-external-abstraction-with-abstractor) or [manually](abstraction.md). ## Auto-generate external abstraction with abstractor @@ -15,39 +17,35 @@ abstractor -e -p -o ``` !!! Warning - Abstractor scan all things in the SPARQL endpoint. You may review the generated file to delete unwanted things. + Abstractor scan all things in the SPARQL endpoint. You may wish to review the generated file to delete unwanted things. ## Integrate external abstraction into AskOmics -Once external endpoint's abstraction is generated, its time to add it into AskOmis. Upload it and integrate it. -![integrate_external](img/integrate_external.png) +Once external endpoint's abstraction is generated, its time to add it into AskOmics. Upload it and integrate it. +![Integrating an external abstraction](img/integrate_external.png){: .center} !!! Warning Check that `advanced options` > `Distant endpoint` contain URL of the external endpoint - # Query external endpoint -## Simple query - -If AskOmics contain local data, external startpoint are not displayed by default on the start page. Use the `Source` dropdown button to display external entities. - -![external_startpoint](img/external_startpoint.png) - +## Starting entities -## Federated query +If AskOmics already contains local data, external startpoint are not displayed by default on the start page. Use the `Source` dropdown button to display external entities. +![External startpoint](img/external_startpoint.png){: .center} -External entities can be interrogate just as local entities. But to link a local dataset to the external endpoint, the file must be structured in a certain way. +## Linking to your own data -### Build file +To link a local dataset to the external endpoint, the file must be structured in a certain way. -The input file must describe the relation with the external entity. It goes through the header, who must contain the URI of the targeted entity. Content of the file must also be the exact uri of the targeted entity. +The input file must describe the relation with the external entity. Much like a 'normal' relation, it goes through the header. +In this case however, instead of simply the entity name, the column name must contain either the full URI or the CURIE of the external entity (e.g *http://nextprot.org/rdf#Gene*). The values of the column must also be the exact uri (full URI or CURIE) of the targeted entity, instead of a raw value. -For example, the file below describe en entity *gene* who is linked to an external entity *Gene*. The external one is prefixed with the full uri used in the external endpoint. In the content of the file, full URI have to be used to. +For example, the file below describe en entity *gene* who is linked to an external entity *Gene*. The external one is prefixed with the full uri used in the external endpoint. In the values of the column, you will need to also use the full URI / CURIE. gene|value|concern@http://nextprot.org/rdf#Gene @@ -56,6 +54,6 @@ gene_1|0|http://nextprot.org/rdf/gene/ENSG00000169594 gene_2|1|http://nextprot.org/rdf/gene/ENSG00000156603 -### Perform a federated query +## Perform a federated query -Once the relations are well described, link between local and distant entities are automatically done by AskOmics. The Query is distributed to the concerned endpoint and results are returned like a classic query. +Once the relations are described, links between local and distant entities are automatically created by AskOmics. The query is distributed to the external endpoint and results are returned like a classic query. diff --git a/docs/galaxy.md b/docs/galaxy.md index d47a062e..9b6fd1f6 100644 --- a/docs/galaxy.md +++ b/docs/galaxy.md @@ -1,5 +1,7 @@ Galaxy is a scientific workflow, data integration, and data and analysis persistence and publishing platform that aims to make computational biology accessible to research scientists that do not have computer programming or systems administration experience. +A Galaxy Training tutorial is available [here](https://training.galaxyproject.org/training-material/topics/transcriptomics/tutorials/rna-seq-analysis-with-askomics-it/tutorial.html) + AskOmics can be used with a Galaxy instance in two way: - With a dedicated AskOmics, import Galaxy datasets into AskOmics and export AskOmics results into Galaxy. @@ -17,7 +19,7 @@ On your Galaxy account, go to the top menu *User* → *API Keys* and copy your A On AskOmics, got to Your Name → Account management → **Connect a Galaxy account** and enter the Galaxy URL and API Key. -![askogalaxy](img/askogalaxy.png) +![](img/askogalaxy.png){: .center} Once a Galaxy account is added to AskOmics, you can access to all your Galaxy Datasets from AskOmics. @@ -51,30 +53,30 @@ Galaxy Interactive Tools (GxITs) are a method to run containerized tools that ar Search for the AskOmics Interactive tool using the search bar. -![Search a Galaxy Tool](img/galaxy_search_tool.png) +![](img/galaxy_search_tool.png){: .center} Choose input files to automatically upload them into AskOmics -![Input files](img/galaxy_input_data.png) +![](img/galaxy_input_data.png){: .center} !!! Tip You will able to add more input files later A dedicated AskOmics instance will be deployed into the Cluster. Wait few minutes and go to the instance using the `click here to display` link. -![Galaxy](img/galaxy_execute_it.png) +![](img/galaxy_execute_it.png){: .center} Once you are into your AskOmics instance, you can see your uploaded files into the Files tab. -![Galaxy](img/galaxy_askomics_files.png) +![](img/galaxy_askomics_files.png){: .center} ## Upload additional files in addition to the Computer and URL buttons, you can now use the galaxy button to import datasets from your galaxy histories -![Galaxy](img/galaxy_import_from_galaxy.png) +![](img/galaxy_import_from_galaxy.png){: .center} ## Integrate and Query @@ -84,7 +86,4 @@ follow the [tutorial](/tutorial#data-integration) to integrate and query your da Once you have your result, Use the `Send result to Galaxy` to export a TSV file into your last recently used Galaxy history. -![Galaxy](img/galaxy_history_result.png) - - - +![](img/galaxy_history_result.png){: .center} diff --git a/docs/img/askogalaxy.png b/docs/img/askogalaxy.png index 44dcaa72619fabfe2646f2797600231506f809f5..5dd6e0379e50191323aa06bb58b16b8f03e55c8b 100644 GIT binary patch literal 15318 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 Ie*X490F#JdEdT%j literal 15352 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 diff --git a/docs/img/askograph.png b/docs/img/askograph.png new file mode 100644 index 0000000000000000000000000000000000000000..a898d77c6bd0ad7fc8ee6cbcdb0f0d0a7673f2a0 GIT binary patch literal 34589 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≈vxa6B0XR3}>@*U|0r>~@oZHP~3SDad zd7G@m)+duONqPn*mwB$(81~<7nkyTRwoU?!dL_UKe=z3~%*jx<3_8weksBBA)&xn{ z1PS0vfQ50ycLwA*jk6-U>F{4%O7f>OX>U1!tx&)dC{9P}VIWz5>-T66J0pt*BTc5x zm0gg;srC&5_78hs97q;QcIC88s=5vV^V@MD@#z^ehKvLBcus~*j|kLT7U|K+F1rm96KE`YdxOX(*{{u~vkss`$pEWzWgDIr>uR*pDBgUhfmjKE zQKDKGtpYYUI+LFc;P6US+mzg7 zVCE7MwQhQQ4d0BL_W^)kr3h0`O9WHwEL6_N`ztN@aAxy2PbTgC+ZVWgoD*T{IX60m z^MJ}~bbEMzb*ATgKEdEKEiMDl__ev4fTou0*~o3?&0$|Qli!fp=d(qE63`t`xVO6m zAaz`QvH@sXdINHH{Uu0Xl?~QMIMl8e8rv4?$rK`iSf5|m&aK?EYR4HDPv(@()uXN` zxf+E@ZJgDxR%VEcbrIZQ=m+pw%1r$3_qL>5Mhj72UY#Uf z>9aXR&+_yD>GlXsJ$)q_WM#6ms)Qj+ph_3r+P`2r)6@A~0k}OK02vq8j$LznxK+^w zC>HB9z0L?TpJQMv_&D6o@A*BZwvD)Q3^*5;rrlb3*ijZ00hRHqB2z3?j2!)zLXEe# zP(O1*jup*JvFqaZ%I!NW`PF3wB!?StAC83hlw9Ctq?!ewYC*to3*uXtA4?G!2@mBc zt=5chQEqGaz@k${nyC{=ay}>T20BvN84RtK@KEJ~M1In4#d!`NQ6=1{0-txVA~J>x zVI8B)yCUz!0fGz-ko2$N{blc=3$M%G-B(G(3!K{}6vbS$XY`k`Xojm^6&{F{S3 zc-3MW0L28EWqGzO16?ZySMF>3E~(Q2YnNZy3Tq@X6DNKdae{(3;Jm5Q{_=fixaoe1Uh`ot!)GS$?t3kL#vA(CK)` z_CUGGgl8iJbx{E8Z~LwOm9m<|$fJ=!A^l=p#cD56%V+5|;;v=8x@c>Lj^)a1pJd$L zcZA;@6CbKH1El9i_FQ6tAZ$mpRk$Fx~?NgVGi;=$S_^Q*EXS)eo+CgZ=PA zMJ1n54(LjYUtXr#+XCm`;-wziKA0h^`p%$zsH%Dwcr_s=e1coQXvd_~zYZ=&P`CDN zIm~yy8xH)Kj@10cV0&+Yxs~a~>eJkttX1_L&WSeZuj6lhysdJ#uX?RD?8HEZItB_{ zmL&+>05e7-S>KT(2YO5bsV$?B#29(#PT8)4^cf2i@U;{pvpnZjU$f%6zP#ZTPqkl;l&oxR9hNB*RhotEP+?;5)hWyqt@5T zUZ8yKPL34yw-jBkFa#rW!8gAaJiNK~zJ@)hOVgL|5Da}0
BfA^{LOFc8SVUMQv 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≷+ONvF&zP5)Syos+jtlyVa_L~{b8~YWko%{t zs}UgRIB5!CbV;DMz|y`p^GQf>EFQdIqFtiir^sCAAKI_aJ9LC*^lV+8v z6aic*(|R*U04`s;qoyDT| zQnRSCIPAU|)V!FE+G}iTMx!q_e~N?`4y@S;)!sqXJoIQbK>CHcRBC%OaJZe?{!UXq zyV4wrgbFU64X!#eI#@qn*T~8ADzOTl#Q_QHOe`=zq=B#>*wyU<3D?Kr*ESc$59(bv z5?f8$Xy%DUZ85_o1QurQq@NB4YR-Iv240mPM1+NsH<_Q+c$z$P(``P*%U5Na*)bv; z*P2Rtg5Sa+P(gMv_4FK`ur6L%<0`48xioZDr6jd4?gvD9c4S0Dmv$Fj}2pAR`kb%yD1Wi2)LL!USBGC^vfak^gyP zxqi+M6uhpVrhpr;a^Dj!4fp@{-HZR};j9}7K>si%{VV+655LU!Q^=^h3pDeOTX+BV zj-5FSCdxpvI|nEc+}wYQMt^Ee3_uSpg8mj6hKIEqW;KG2=zwDT%XGy*C8j!Gtf!Nc zAT7~O?0-reWd`mrUJsI`JqBJ6+$sd*j}%gZ0N@58&^_Q*BY7yg0tfWnlk<1}r^_^n z87X98IA52Lkg%NOgb9$Pr`)*==nvm|h8E;?{C7TfiVd$`94$i)2mT F{x8wH(A@w4 literal 0 HcmV?d00001 diff --git a/docs/img/csv_convert.png b/docs/img/csv_convert.png new file mode 100644 index 0000000000000000000000000000000000000000..d27ecb489dc613d7f5d8e906401311bbc74067d9 GIT binary patch literal 251893 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 literal 0 HcmV?d00001 diff --git a/docs/img/custom_nodes.png b/docs/img/custom_nodes.png new file mode 100644 index 0000000000000000000000000000000000000000..65429b9f4d17ebb7983a0b8833664376f534b21d GIT binary patch literal 5745 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 literal 11895 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 DJ|O$! diff --git a/docs/img/faldo.png b/docs/img/faldo.png new file mode 100644 index 0000000000000000000000000000000000000000..791f9076c26211e504af8fa0c9eb0dad3750ecb2 GIT binary patch literal 18666 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

RiG$ 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 literal 0 HcmV?d00001 diff --git a/docs/img/form_edit.png b/docs/img/form_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..c3c8cf67410eb46c873a92f1d62473d4e867c86d GIT binary patch literal 12392 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�(Am7p;+g=K^nb;UL`r5psLp>9iwYjlP6hiqIn# zqwBtuTH4yaU}KB3mcFJe0IJKxB%|GQ;?HQH{zJyYQEusH~g} z<#iFFQqF(qKDx|V2(&3G+Po&)NJD}Evh9`H@8x}f|I$=f z=it7%A^k(T{79<6u>8VD)X?Q477aEa3Lw7z#rt6w5lC5E7vvUC-DtN{L$v8NP&0Ze z7joEOi3+cTKCoZxmtuhThn$LdA9k;!Mn*Mf_kc^fQO z!w)aJWazjDx^KD%-2;*nw8CSd|Mi8O+Ow-WEMlT9R(K=m`x&xQiju|RM*jZ`&Yx6- literal 0 HcmV?d00001 diff --git a/docs/img/form_example.png b/docs/img/form_example.png new file mode 100644 index 0000000000000000000000000000000000000000..76bf4709858c9f0ded3a0e63c8c347a425a88408 GIT binary patch literal 12575 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 WUNF=!_zvAfKtfbjq)1rD^S=RIY^GiS literal 0 HcmV?d00001 diff --git a/docs/img/gff.png b/docs/img/gff.png index a12eac4915caf4bd57e99d2429549bd075a989b6..22872e7fc55e9b29d1c124160aed60e9719ba5e3 100644 GIT binary patch literal 2275 zcmb_eXEYlO7Y;Fkio|?TD@I%6MQl})P_=8stkqJhYP@!16|ovg6(v=pwohBMXuVd^ zCR(Gd-Ikh-5kb*Vgg4)>@6Y$|`|dgSKIb|2p6Aa!_c=Gq*5(Q?w-`470N^z@GqGo4 z1T#HB9Lx#{R{}GEEdphZ1~DTZ2IX?1#}KYK zRaoihr$ZZqR58RI1Uui6}#MRr8ux642tN+S?lr0h(f- zmzA}#_M*6AozOFr>T0Dhvl`P~5QQQP+0iY8u=4Qm1ZWc2&XFPM^E}e{B?JhH*2Pmb zJWc(yeLcI2))b80QT#93Xvu`0(ek;hyjqC15$lM?ECjB4w!qPU@3!HI#j&2Oz=f?& z9vz~Hfk8r3NWX%?+WMkIDhJ!3pyG>;JyPjR!gOA7# zFM~9k20<~~16w{zyf;itRbb5xQ`>kXFeStqki3N3|Fyz6$_WSwM7pfHryg=Gkr#Hx zre2|W1A>oLQN}B%hKco~SWMian@36F(Fz#Mp&oqO3lS0VviuKOiC%aXv}Z6RD2Nq+ z6V<4hGMq*6=S{-Y1D_#_yBO1kOED{l4mWUe9MUiM?}fU05sZZp|BTuc-S$QP@6l&m|@n;N!$3#pNb@6ZK1kVYz<*yy`0quMR6c?72&) z)1^Y>xs6icZ=`r&ec?Z-4TpxIjV|DNlav_-XPERU#54XgnAvJpkSUG%PRdlDf$jxs ztA^_M!r2w9ia-vfWm;~}g!eaR`wNsrAOgD`k~9ek2{jFkR3ees9kM2_uBM|y?(Qnv zw$5R>t1TKUVs!l-MN^6*UFziiK`$1lvVXcpf*_ zUp_f8kf~Rf4)bekZCzNO7__Yq`I$JWSYV+Z_d>vLcqch0$C?n`>XuU?wb@ty@oHst ztB^yQ>L!KQ~nJb!NPPhiDO(H9frCXNBZo@NB_?eEO7LV!ddf1mAWirN1&*uslY=y}Ng zV5(+eX%@qK7!?(@(8asfxfC58T~SfNuU`WGan43ekJ{^F(g>8xHG`b3GYKo_|M$`& zFxvSn5%)Vndyq!WE;t?$)dd$j^~To)j!79cmB5q4mv-*jYnRpz!F zL%k3A+IF(-+}*g_hk%2g1XAnYR9U|`B2yOx0E-Cr&3zPM&)|c}Ux1Rcv!Rf)tbO4J z)P?xqZ;$S-?`jPUec047ax?}qFQAG)3(275P=7M^3Awq%iIszglTPtbn+6mt_Dxco zDs#l*1AhOMbOy*FohNR)c5hA@_x6?@&w}nv?uT8HygJSzX4Uppp)MJL4keJYf|<_! zE0s0$lwMtY*rx#f^3Rd;i9WJmiWDl`T(qK4dA*sBGb1aL;E`3Cq|}GKS9oW*y7O4B z#Z9FTW$Yaif-gtNTUZdpe{G$nzPtY%IG$5bP|({}QlcWq&t(G3?H(bKIIK@!DP~zr z07PQi6R*kf%TR`InweX~Zzg`vjuWW9Np5CZ=i~EAcS6b*N8ztO{?)IG!2l300iX{b zuFfx34{oCe$}al7R#UcliJ~)xK>2nH#Eo9}??lO@VzKPmmKmqmPffbR;CwqHadxab2i84(u3HF5 zzTnWLg}GAZvkd3!6mEqi{a*E%X~#^JKU=PE+Mwx$g%|d}^8jOCN$Fp_7`}sMFExmR zpC?~eHXR?@;1LiIkW+a3q=sIm>+CV+Ki4uYXr`=^o3xsVObB$zqn0e+Uhjw?Rj}2z74cqjc z@zBD2$&A)ktv(cmzIyA%jg&fU?!k_ff81;>Sje~=4C#+O^IIQrW=Y1ZrlH}YF24U4 zb&9PKxV)}^3&90H=$~Y%0MRXh{~u@gFV=Fxi9v(IxEy;a%&!Gte%Z$4Im$cbAJ;A~ AJpcdz literal 2854 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 Kok$mcNd7l2yGyeG diff --git a/docs/img/gff_preview.png b/docs/img/gff_preview.png index 90653374da51d7627430bda5a19fac5b90021748..eb8a8127aad707256be4ac68dc0d5e4074dd83ce 100644 GIT binary patch literal 11892 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 literal 11601 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 LSxBL%&X@lNRrN5* diff --git a/docs/img/minus.png b/docs/img/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..84030a3cc6377535025656df77e37e7d2043f37d GIT binary patch literal 13218 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 j%=G_=6UCC1JNJy6?%TkUeFq0#)q|wO_ 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 literal 0 HcmV?d00001 diff --git a/docs/img/sparql.png b/docs/img/sparql.png new file mode 100644 index 0000000000000000000000000000000000000000..b77f36259929cbfe95523cb9984619c9f19ef133 GIT binary patch literal 119634 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

&O8# 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 BnC<`o literal 0 HcmV?d00001 diff --git a/docs/img/startpoint.png b/docs/img/startpoint.png index 455d1bf1f6b1663ea4b1d58e273c2fc91a5d12a9..8cf932580a8c75161e8eb17744c91b320b79ec03 100644 GIT binary patch literal 15434 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 Y{2lL{WnN#OIKQ!yyqa9evo|093r@5pn*aa+ diff --git a/docs/img/template.png b/docs/img/template.png new file mode 100644 index 0000000000000000000000000000000000000000..73ce81e107027d5ac9dd6140e391057ac71a154f GIT binary patch literal 3700 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 a@gDAJ`Q9wx_;Hr`la!deXr-`W!2bYbZ%%js literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md index 1ad07ce3..3a0de9a0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,22 +1,34 @@ -AskOmics is a visual SPARQL query interface supporting both intuitive data integration and querying while shielding the user from most of the technical difficulties underlying RDF and SPARQL +AskOmics is a visual SPARQL query interface supporting both intuitive data integration and querying while shielding the user from most of the technical difficulties underlying RDF and SPARQL. + +AskOmics helps loading heterogeneous data (formatted as tabular files, GFF, BED or native RDF files) into an RDF triplestore, to be transparently and interactively queried through a user-friendly interface. + +AskOmics also support federated queries to external SPARQL endpoints. + +![AskOmics](img/askograph.png){: .center} - AskOmics Tutorials - [Overview tutorial](tutorial.md): How to use AskOmics with example data - [Prepare your data](data.md): How to format your own data for AskOmics + - [Building a query](query.md): Learn how the query building interface works + - [Results interface](results.md): In-depth guide of the results interface + - [Template & forms](template.md): An overview of the templates & forms functionalities + - [SPARQL console](console.md): How to interact with the provided SPARQL console + - [Command-line interface](cli.md): A python-based CLI for interacting with AskOmics - [Build an RDF abstraction](abstraction.md): Learn how to build an RDF abstraction for RDF data - [Perform federated queries](federation.md): How to query your own data with external resources - [Use AskOmics with Galaxy](galaxy.md): How to connect AskOmics with your Galaxy history - - [Contribute as a user](issues.md): How to contribute to the development of AskOmics as a user + - [Link your data to ontologies](ontologies.md): How to add ontologies to AskOmics, and connect your own data

- Administration - [Deploy an instance](production-deployment.md): Deploy an AskOmics instance on your server - [Configuration](configure.md): Configure your instance - [Manage](manage.md): Manage your instance + - [Add custom prefixes](prefixes.md): How to add custom prefixes for your users

- Developer documentation - [Deploy a development instance locally](dev-deployment.md) - [Contribute to AskOmics](contribute.md) - - [CI](ci.md): Test code with continuous integration + - [CI](ci.md): Test your code with continuous integration - [Contribute to doc](docs.md): Write documentation diff --git a/docs/issues.md b/docs/issues.md deleted file mode 100644 index 942e038f..00000000 --- a/docs/issues.md +++ /dev/null @@ -1 +0,0 @@ -If you have an idea for a feature to add, or an approach for a bugfix, the best way to communicate with AskOmics developers is [Github issues](https://github.com/askomics/flaskomics/issues). Browse through existing issues to see if one seems related, or open a new one. diff --git a/docs/manage.md b/docs/manage.md index 9bec4562..3751ff61 100644 --- a/docs/manage.md +++ b/docs/manage.md @@ -1,4 +1,4 @@ -# Command line interface +# Make commands Several commands are available to help manage your instance. These commands are available through `make` when launched from the same directory as the *Makefile*. (If you are running Askomics in a docker container, you will need to connect to it to launch these commands) @@ -19,3 +19,46 @@ In the latter case, you will need to run the command twice (once for each namesp - `make clear-cache` This will clear the abstraction cache, making sure your data is synchronized with the new namespaces. + +# Single tenant mode + +Starting from release 4.4, the *Single tenant mode* is available through a configuration option. +In Virtuoso, aggregating multiples graphs (using several FROM clauses) can be very costly for big/numerous graphs. + +Single tenant mode send all queries on all stored graphs, thus speeding up the queries. This means that **all graphs are public, and can be queried by any user**. This affect starting points, abstractions, and query. + +!!! warning + If you are storing sensitive data on AskOmics, make sure to disable anonymous access and account creation when using *Single tenant mode*. + +!!! warning + *Single tenant mode* has no effect on federated queries + +# Administrator panel + +Administrators have access to a specific panel in AskOmics. +This Admin tab can be found after clicking on *Your Name ▾*. + +## User management + +From the Admin tab, administrators are able to: + +- Create a new user account +- Manage existing user accounts + - Blocking an user account + - Setting an user as an administrator + - Updating an user's individual storage quota + - Deleting an user + +They will also be able to check the last time of activity of an user. + +## Files + +A list of all uploaded files is available. Administrators can delete a file at any time. + +## Datasets + +All currently stored datasets are available. Administrators can publish, unpublish, and delete them. + +## Forms / Templates + +A list of **public** forms and templates is available. Administator can unpublish them if need be. diff --git a/docs/ontologies.md b/docs/ontologies.md new file mode 100644 index 00000000..fe06432b --- /dev/null +++ b/docs/ontologies.md @@ -0,0 +1,60 @@ +Starting for the 4.4 release, hierarchical ontologies (such as the NCBITAXON ontology) can be integrated in AskOmics. +This will allow users to query on an entity, or on its ancestors and descendants + +# Registering an ontology (admin-only) + +!!! warning + While not required for basic queries (and subClassOf queries), registering an ontology is required for enabling auto-completion, using non-default labels (ie: *skos:prefLabel*), and enable an integration shortcut for users. + + +First, make sure to have the [abstraction file](/abstraction/#ontologies) ready. Upload it to AskOmics, and integrate it. +Make sure *to set it public*. + +You can then head to Ontologies in the user tab. There, you will be able to create and delete ontologies. + +## Creating an ontology + +Parameters to create an ontology are as follows: + +* Ontology name: the full name of the ontology: will be displayed when as a column type when integrating CSV files. +* Ontology short name: the shortname of the ontology (ex: NCBITAXON). /!\ When using ols autocompleting, this needs to match an existing ols ontology +* Ontology uri: The ontology uri in your abstraction file +* Linked public dataset: The *public* dataset containing your classes (not necessarily your abstraction) +* Label uri: The label predicated your classes are using. Default to rdfs:label +* Autocomplete type: If local, autocomplete will work with a SPARQL query (local or federated). If OLS, it will be sent on the OLS endpoint. + +# Linking your data to an ontology + +This functionality will only work with CSV files. You will need to fill out a column with the terms uris. +If the ontology has been registered, you can directly select the ontology's column type. + +![Ontology selection](img/ontology_integration.png){: .center} + +Else, you will need to set the header as you would for a relation, using the ontology uri as the remote entity. + +Ex: `is organism@http://purl.bioontology.org/ontology/NCBITAXON` + +# Querying data using ontological terms + +If your entity is linked to an ontology, the ontology will appears as a related entity on the graph view. +From there, you will be able to directly print the linked term's attributes (label, or other) + +![Ontology graph](img/ontology_graph.png){: .center} + +If the ontology was registered (and an autocompletion type was selected), the label field will have autocompletion (starting after 3 characters). + +![Ontology autocompletion](img/ontology_autocomplete.png){: .center} + +## Querying on hierarchical relations + +You can also query on a related term, to build queries such as : + +* Give me all entities related to the children of this term +* Give me all entities related any ancestor of this term + +To do so, simply click on the linked ontology circle, fill out the required label (or other attribute), and click on the link between both ontologies to select the type of query (either *children of*, *descendants of*, *parents of*, *ancestors of*) + +![Ontology search](img/ontology_link.png){: .center} + +!!! warning + The relation goes from the second ontology circle to the first. Thus, to get the *children of* a specific term, you will need to select the *children of* relation, and select the label on the **second** circle diff --git a/docs/prefixes.md b/docs/prefixes.md new file mode 100644 index 00000000..acec6b54 --- /dev/null +++ b/docs/prefixes.md @@ -0,0 +1,11 @@ +Starting for the 4.4 release, custom prefixes can be added in the administration UI. +These prefixes can be used by non-admin users when integrating CSV files (for specifying URIs, for instance) + +# Registering a prefix (admin-only) + +You can head to Prefixes in the user tab. There, you will be able to create and delete custom prefixes. + +## Creating a custom prefix + +Simply fill out the desired prefix (ex: *wikibase*), and namespace: (ex: *http://wikiba.se/ontology#*). +Users will be able to fill out data using the wikibase:XXX format. diff --git a/docs/production-deployment.md b/docs/production-deployment.md index adae676d..843e0f30 100644 --- a/docs/production-deployment.md +++ b/docs/production-deployment.md @@ -1,4 +1,4 @@ -In production, AskOmics is deployed with docker and docker-compose. We provide `docker-compose.yml` templates to deploy your instance. +In production, AskOmics is deployed using docker and docker-compose. `docker-compose.yml` templates are provided to deploy your own instance. # Prerequisites @@ -81,11 +81,11 @@ All properties defined in `askomics.ini` can be configured via the environment v !!! warning Change `ASKO_flask_secret_key` and `ASKO_askomics_password_salt` to random string -For more information about AskOmics configuration, see [configuration](configure.md) section. +For more information about AskOmics configuration, see the [configuration](configure.md) section. #### First user -environment variables can also be used to create a user into AskOmics at first start. For this, use `CREATE_USER=true` User information can be configured with the following environment variables: +Environment variables can also be used to create a user into AskOmics at first start. For this, use `CREATE_USER=true` User information can be configured with the following environment variables: - `USER_FIRST_NAME`: User first name (default: Ad) - `USER_LAST_NAME`: User last name (default: Min) @@ -96,4 +96,4 @@ environment variables can also be used to create a user into AskOmics at first s - `GALAXY_API_KEY`: Galaxy URL linked to the user (optional) - `GALAXY_URL`: User Galaxy API Key (optional) -The user will be created only if the users table of the database is empty. \ No newline at end of file +The user will be created only if the users table of the database is empty. diff --git a/docs/query.md b/docs/query.md new file mode 100644 index 00000000..3da6233d --- /dev/null +++ b/docs/query.md @@ -0,0 +1,299 @@ +AskOmics aims to provide a simple interface able to create complex queries on linked entities. +The query interface is customized based on available (both personal and public) integrated data. + + +# Starting point + +Any entity integrated with the *starting entity* type can be used to start a query. Other entities can still be queried through a linked entity. +The starting entity will start with its label already set to 'visible'. + +![Startpoints](img/startpoint.png){: .center} +Once the start entity is chosen, the query builder is displayed. + +On the left-side of the query builder is the entity graph. Nodes (circles) represent *entities* and links represent *relations* between entities. +The currently selected entity is surrounded by a red circle. Dotted links and entities are not yet instantiated. + +![Query builder: Differential Expression is the *selected* entity, GeneLink is a *suggested* entity](img/query_builder.png){: .center} + + +# Filtering on attributes + +The selected entity's attributes are shown as attribute boxes on the right of the graph. + +!!! note "Info" + By default, every instantiated entity (directly or through a relation) has its **label** attribute set to visible (though it can be toggled off). + +Various filters are available to further refine the query, with each attribute type having its own filter: + +- Entity URI, entity label, and String attribute type: exact match or regular expression (equal or not equal) +- Numeric attribute type, FALDO start, FALDO end: comparison operators +- Category attribute type, FALDO reference, FALDO strand: Value selection among a list +- Date attribute type: comparison operators with a date picker +- Boolean attribute type: "True" or "False" selector + +![Attribute boxes for an entity](img/attributes.png){: .center} + +!!! note "Info" + Due to the way SPARQL works, any result row with an empty value for **any** of its column will not be shown. You can force the display of these rows by using the button. + +!!! tip + For the Category type, you can Ctrl+Click to either deselect a value, or select multiple values. + +!!! tip + For the Numeric and Date types, you can add filters by clicking on the "+" button. + + +## Additional customization + +In addition to the filter, several customization options are available for each attribute box. Depending on the attribute type, not all options will be available. + +![Additional customization](img/attribute_box.png){: .center} + +From left to right : + +- : Mark the attribute as a **form** attribute. More information [here](template.md#forms). +- : Link this attribute to another (on a different entity or the same one). + - *This will only show rows where both attributes have the same value*. +- : Show all values for this attribute, including empty values. +- : Exclude one or more categories, instead of including. + - *Select where the attribute is not XXX*. +- : Display the attribute value in the results. + +# Filtering on related entities + +To query on a linked entity, simple click on a suggested node. The linked node will be surrounded in a red circle, and the list of attributes on the right-hand side will change to show the new node's attributes. + +!!! note "Info" + Linking entity A (after filtering on parameter A1) to entity B (filtering on parameter B1) in the interface create the following query : + + - *List all entities A who match parameter A1 , AND are linked to any entity B matching parameter B1* + +## Explicit relations + +Explicit relations between entities (defined by the "@" symbol in CSV files, and the *"Parents"/"Derives_from"* relations from GFF files) will appears between related entities. If the relation is a *symetric* relation, it will appear twice between entities. + +## FALDO relations + +All *FALDO* entities will be linked by an implicit *Included_in* relation. This relation is slightly different than *explicit* relations: it relies on the *FALDO* attributes of both entities for the query, instead of a direct link. + + FALDO entities are represented with a green circle and FALDO relations have a green arrow. + +!!! Tip + You can customize the relation by clicking on the *Included in* relation. + + ![Customizing the 'Included in' relation](img/faldo.png){: .center} + +!!! note "Info" + Entity A is *Included_in* Entity B means: + + - **Entity A Start > Entity B Start** *AND* **Entity B End < Entity B End.** + + By default, the inequalities are **Strict**, but it can be changed from the interface. + +!!! Tip + If both entities have a defined *Reference* and/or *Strand* attribute, you will be able to select the **Same reference** and/or **Same strand** options. (Both are selected by default if available) + +!!! Tip + You can **reverse** the relation (Entity B *Included_in* Entity A instead of the opposite) from the interface. + +!!! Warning + *Included_in* queries are **ressource-intensive**, especially if you have a lot of instances for each entity. + +## Filtering displayed relations + +If there are too many related entities displayed, it can be difficult to select the entity you wish to link to. It is possible to filter the displayed relations on either the name of the entity, or the name of the link. + +Simply type out the name you want to filter in either the "Filter links" or the "Filter nodes" fields on the top of the graph. + +![Filtering displayed relations](img/filters.png){: .center} + +!!! Tip + You can stop the *Included_in* relations from being displayed by toggling the *Show FALDO relations* button. + +## Removing instanciated relations + +At any point, you can remove an instanciated node **(and any node linked to it)**, by selecting the node you wish to remove, and using the **Remove Node** button at the top of the interface. + + +# MINUS and UNION subqueries + +**Minus** and **Union** nodes are an additional way of querying on relations. Both nodes are applied to an entity as an additional filter. + +- Minus nodes remove results based on a subquery + - *Show all genes except those that match XXX* +- Union nodes act as a "OR" between multiple subqueries + - *Show all genes that match either XXX or YYY* + +Both type of nodes can be integrated in a bigger query + +- *List genes linked to a mRNA, except mRNA linked to another entity* +- *List genes linked to a mRNA with either attribute A set to XXX, or attribute B set to YYY* + +!!! note "Info" + *Right-click* on any **non-instanciated** node, and select the type of node you wish to use. + + ![Creating a minus or union node](img/custom_nodes.png){: .center} + +!!! note "Info" + The entity affected by the special node is linked with the *Union* or *Minus* relation. + +!!! warning + To avoid displaying empty columns or duplicates in the results, you should disable the *label* display for entities in the sub-queries. + + +## MINUS nodes + +*Minus* nodes **remove** from the results any instance that match a specific subquery. + +- **Display all genes that are not linked to an mRNA** +- **Display all genes that are not linked to an mRNA whose reference is XXX** + +![List all genes, except those linked to a mRNA](img/minus.png){: .center} + + +!!! tip + It's currently the only way to query on the **lack** of relation between entities. + Such as: *List all instances of entity A who are not linked with any instance of entity B* + +!!! note "Info" + To add a minus node on the relation between entities A and B + + - Entity A is currently selected + - Right-clicking on entity B and selecting "MINUS" add a new node to the graph + - Entity B is automatically instanciated and linked to the new minus node + - The query is now: *List all instances of entity A, without instances linked to entity B* + - *Optional*: Disable the display of the label for entity B + +The generated SPARQL query will look like this: + +```turtle +# Listing all genes NOT related to an mRNA by the 'Parent' relation. + +SELECT DISTINCT ?gene1_Label +WHERE { + ?gene1_uri rdf:type . + ?gene1_uri rdfs:label ?gene1_Label . + { + MINUS { + ?mRNA31_uri ?gene1_uri . + ?mRNA31_uri rdf:type . + } + } +} +``` + +!!! tip + You can customize the sub-query further: instead of simply removing any instance linked to a specific entity, you can remove all instances linked to a specific entity whose attribute A is XXX. + + - I want to list all instances of Entity A with the attribute A1 + - But I want to exclude all instances of Entity A that are linked to any instance of Entity B with the attribute B1 + + To create this query: + + 1) Instantiate Entity A with attribute A1 + 2) Right-click on Entity B and select "Convert to MINUS node" + 3) Select entity B + 4) Select attribute B1 for entity B + +!!! note "Info" + You can create multiple *minus* nodes starting from the same entity. Instances that match **any** of the sub-queries will be removed. + + - I want to remove instances that match *condition A* + - I also want to remove instances that match *condition B* + + This is not the same as removing instances that match *condition A* **and** *condition B* + To do so, you will need to add conditions to an existing *minus* node instead of creating a new one. + +!!! Warning + While nested MINUS nodes are possible, the generated query might not be what you would expect. Make sure to check the generated SPARQL query in the results page if the results are not what you expected. + +## UNION node + +UNION nodes implement the conditional **OR**. + +- Display transcripts that are either + - Linked to a 3′-UTR + - Linked to a 5′-UTR + +![List all transcripts linked to either a 3′-UTR or a 5′-UTR](img/union.png){: .center} + +!!! note "Info" + Due to the way UNION nodes works, entities will appear once for each matching sub-query. This can lead to a duplication of results. + This can be solved by setting the label of the entities in the subquery to **Not visible** () + ![Duplicated results](img/union_duplicated.png){: .center} + +!!! Warning + UNION nodes will only behave as a UNION if there is more than one entity linked to it + +!!! note "Info" + To add an union node on the relations between entities A, B and C + + - Entity A is currently selected + - Right-clicking on entity B and selecting "UNION" add a new node to the graph + - Entity B is instanciated and linked to the new union node + - Click on Entity B and set the label to "Not visible" + - For now, the *union* node has no effect + - Click on the *union* node, and then click on entity C to instanciate it + - Set the label to "Not visible" + - The sparql query is now: *List all instances of entity A that are either linked to entity B or entity C* + + +The generated SPARQL query will look like this: + +```turtle +# List all genes with an ortholog who has either the attribute "organism" set to "Arabidopsis thaliana", or the "reference" attribute set to "Chra01" +# Two sub-queries linked with an UNION + +SELECT DISTINCT ?gene1_Label ?gene3_Label ?gene4_Label +WHERE { + ?gene1_uri rdf:type . + ?gene1_uri rdfs:label ?gene1_Label . + { + { + ?gene1_uri ?gene26_uri . + ?gene26_uri rdf:type . + ?gene26_uri rdfs:label ?gene3_Label . + ?gene26_uri faldo:location/faldo:begin/faldo:reference ?gene26_chromosomeCategory . + VALUES ?gene26_chromosomeCategory { } + } + UNION { + ?gene1_uri ?gene64_uri . + ?gene64_uri rdf:type . + ?gene64_uri rdfs:label ?gene4_Label . + ?gene64_uri ?gene64_organismCategory . + VALUES ?gene64_organismCategory { } + } + } +} +``` + +!!! tip + You can customize the sub-query further. + I want to list all instances of Entity A that are either: + + - Linked to entity B with attribute B1 + - Linked to entity C, itself linked to entity D + + +!!! note "Info" + Sub-sub-queries (entities linked to the UNION node) can be as complex as you want : + + - *I want instances of entity A either linked to entities B with attribute B1, or linked entities C linked with entity D* + +!!! Warning + Just as MINUS node, nested UNION nodes might not behave as you want. Make sure to check the generated SPARQL query in the results page if the results appear to be strange. + + +## Removing special nodes + +Much like a "normal" node, you can remove special nodes (and any node linked to it) at any time by selecting it, and using the **Remove Node** button. + + +# Launching queries + +Once you are satisfied with your query, you can either: + +- Preview the results (*at most 30 rows*) with Run & Preview +- Send a full query with Run & save + +In the case of a full query, you will be able to access the query results (and more) on the [results page](results.md) diff --git a/docs/requirements.txt b/docs/requirements.txt index 591f7c09..100e7c46 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,2 @@ -mkdocs==1.0.4 +mkdocs==1.2.3 +markdown-captions==2 diff --git a/docs/results.md b/docs/results.md new file mode 100644 index 00000000..438ce8fe --- /dev/null +++ b/docs/results.md @@ -0,0 +1,79 @@ +On the Results page, you will be able to see all your saved results (after using the Run & save button). Each row stores both the query and its results. + +# General information + +Result information can be found for each row : + +- Creation data: The creation time of this result +- Exec time: The running time of the linked query +- Status: Current status of the query + - Possible values are 'Success', 'Queued', 'Started', 'Failure' and 'Deleting' +- Rows: Number of rows in the result +- Size: Size of the result file + +## Description + +Each description can be customized by clicking on the field, and entering the desired value. You can use this to identify the query related to this result. + +!!! Warning + Don't forget to save your new description using **Enter** + +!!! note "Info" + The description will be displayed on the main page if you transform this query in a [template or form](template.md). + +# Templates and forms + +You can use the available toggle buttons if you wish to create a [template or form](template.md). + +!!! Warning + Form creation is restricted to administrators. The related query must also be a [form-able query](template.md#Forms). + +# Publication + +The 'Public' toggle is available if you are an administrator. If will automatically create a public form (if the result is form-able), or a template. They will be accessible to **all users** from the main page. + +!!! Tip + Make sure to set a custom description (and [customize your form](template.md#editing-the-form-display), if relevant) to help users understand your template/form. + +# Actions + +Several actions are also available for each result : + +## Preview + +Preview directly re-launch the related query, and print a preview of the results. +The preview will be shown under the results table. + +## Download + +Clicking on Download will let you download a CSV file containing the results. + +## Form + +Clicking on Form will let you customize the related form display. + +!!! Warning + Only available for administator and form-able results. + +## Redo + +Clicking on Redo will let you directly replay the query from the query interface. It will be in the exact same state as when you clicked on Run & save. + +!!! Warning + Only available results generated from the query interface. + +## Sparql + +Clicking on Sparql will redirect you to the [SPARQL console](console.md). You will be able to browse the SPARQL code generated by your query. + +!!! note "Info" + Depending on your AskOmics configuration, you might be able to directly customize the query and launch it from the console. + +![SPARQL query generated by AskOmics](img/sparql.png){: .center} + +# Deletion + +To delete one or more results, simply select them in the table, and use the "Delete" button at the bottom of the table. + +!!! Warning + This will delete any template or form generated from the result. diff --git a/docs/style.css b/docs/style.css index 686c23c6..7b96bac7 100644 --- a/docs/style.css +++ b/docs/style.css @@ -19,11 +19,15 @@ btn { } btn.white { + border: 2px solid #6c757d; background-color: white; - color: #5a6268; - padding-right: 5px; - padding-left: 5px; - border-radius: 5px; + color: #6c757d; + cursor: pointer; +} + +btn.white:hover { + color:white; + background: #6c757d; } badge { @@ -70,3 +74,14 @@ div.admonition.quote > p.admonition-title { color: #007bff; } +.center { + display: block; + max-width: 100%; + height: auto; + margin: auto; + float: none!important; + text-align: center; + font-style: italic; +} + +.fa { display:inline; } diff --git a/docs/template.md b/docs/template.md new file mode 100644 index 00000000..e9692bcb --- /dev/null +++ b/docs/template.md @@ -0,0 +1,98 @@ +One of the goal of AskOmics is to enable re-use and customization of complex queries shared by other users. +This functionality is available in two different ways. + +# Templates + +Templates are a simple way for yourself or another user to replay your queries. They will access a **copy** of the query graph, and be able to customize all parameters and relations (this includes linking to additional entities). + +Templates will appears on the right-side of the homepage. The description of the template can be customized to include more information regarding the query. + +!!! Warning + By default, your templates are private. To publicize them, you need administrator privileges. + +## Creating a template + +To create a template, first create the query you want, and Run & save. +Then, in the result page, you can toggle the 'template' attribute to create the template. + +## Editing the template description + +You can modify the template description the same way you would edit the result description. Simple click on the value of the 'Description' column, and enter your own description. + +!!! Warning + Don't forget to save with the **Enter** key. + +## Using the template + +On the AskOmics homepage, simply click on the template of interest to access the query interface. From there, you can simply interact with it as you would with a normal query, including saving the results. + +![Template display on the home page](img/template.png){: .center} + +!!! note "Info" + Any change to the query will not affect the template. + +## Removing the template + +To remove the template, you can either toggle the 'template' attribute back to *off*, or delete the result as a whole. + +# Forms + +Whereas templates allow users to completely replay your queries (including modifying the query graphs), forms aim to be a much simpler way to share your queries for users not familiar with the way AskOmics works. + +!!! Warning + Forms are restricted to administrators. + +When using a form, other users will only able to change the values for a set of parameters you will have selected beforehand. + +For instance, if your query is *List all users whose favorite color is red*, users will only be able to change the favorite color, before sending the query. + +![Example of a form: the user can only change the favorite color](img/form_example.png){: .center} + +In addition, you will be able to customize the form before sharing it, such as changing the description (much like templates), but also the name of each entity and attribute. + +Like templates, forms will appear on the right side of the homepage, with the chosen description. + +!!! Warning + Users will only be able to interact with *form attributes*. They will not be able to affect or change visibility for other attributes. + +!!! Warning + A given **Result** can be either a form or a template, but not both. + +## Creating a form + +To create a form, you will first to create a **form-ifiable** query. To do so, start with a regular query, and toggle the template ( ) button on all attributes of interest. Selected attributes will be modifiable in the form. + +After saving the query with Run & save, head to the *Results* page. +You will be able to toggle the 'Form' button, creating the form. + +!!! Warning + The form creation option is restricted to form-ifiable (meaning, with at least one selected attribute) queries. + +## Editing the form description + +You can modify the form description the same way you would edit the result (and template) description. Simple click on the value of the 'Description' column, and enter your own description. + +!!! Warning + Don't forget to save with the **Enter** key. + +## Editing the form display + +For each entity with a form attribute, the form will display both the entity name, and each attribute label (in addition to the input field). You can customize this display (for instance, changing the display entity name to something more readable, or changing an attribute label to make your query more explicit) + +To do so, simply click on Form to access the *form editing interface*. +You can then simply edit entities and attributes labels, and click on Save to save the new display. + +![Form editing interface](img/form_edit.png){: .center} + +!!! Warning + The query results will not be affected by these changes (the column name will still match the default attribute label). + +## Using the form + +On the AskOmics homepage, simply click on the form of interest to access the interface. + +![Form display on the home page](img/form.png){: .center} + +## Removing the form + +To remove the form, you can either toggle the 'form' attribute back to *off*, or delete the result as a whole. diff --git a/docs/tutorial.md b/docs/tutorial.md index 0f3f5e7c..0059027f 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -1,16 +1,20 @@ AskOmics is a web software for data integration and query using the Semantic Web technologies. It helps users to convert multiple data sources (CSV/TSV files, GFF and BED annotation) into RDF triples, and perform complex queries using a user-friendly interface. -In this tutorial, we will learn the basics of AskOmics by analyses RNA-seq results. The data comes from a differential expression analysis and are provided for you. 4 files will be used in this tutorial: +In this tutorial, we will learn the basics of AskOmics by analysing RNA-seq results. The provided datasets come from a differential expression analysis. + +4 files will be used in this tutorial: - [Differentially expressed results file](https://zenodo.org/record/2529117/files/limma-voom_luminalpregnant-luminallactate): genes in rows, and 4 required columns: identifier (ENTREZID), gene symbol (SYMBOL), log fold change (logFC) and adjusted P values (adj.P.Val) - [Reference genome annotation file](https://zenodo.org/record/3601076/files/Mus_musculus.GRCm38.98.subset.gff3) in GFF format -- [Correspondence file between gene symbol and Ensembl id](https://zenodo.org/record/3601076/files/symbol-ensembl.tsv): TSV of two columns: symbol and the corresponding Ensembl id +- [Correspondence file between gene symbol and Ensembl id](https://zenodo.org/record/3601076/files/symbol-ensembl.tsv): TSV with two columns: symbol and the corresponding Ensembl id - [QTL file](https://zenodo.org/record/3601076/files/MGIBatchReport_Qtl_Subset.txt): QTL in row, with 5 required columns: identifier, chromosome, start, end and name -Throughout the guide, you will find Hands-on containing tutorial instruction to perform in order to get started with AskOmics. +Throughout the guide, you will find Hands-on sections containing instructions to perform in order to get started with AskOmics. To complete the tutorial, you will need an AskOmics instance. You can [install your own](production-deployment.md) or use this [public instance](https://use.askomics.org). +A Galaxy Training tutorial is also available [here](https://training.galaxyproject.org/training-material/topics/transcriptomics/tutorials/rna-seq-analysis-with-askomics-it/tutorial.html) + # Account creation and management @@ -22,18 +26,18 @@ AskOmics is a multi-user platform. To use it, you will need an account on the in Create your AskOmics account (or login with your existing one) -Once your are logged, you can use all the functionalities of AskOmics. +Once you are logged, you can use all the functionalities of AskOmics. ## Manage your account -To manage your account, use the Account management tab by clicking on Your Name ▾ on the navigation bar. +To manage your account, use the Account management tab by clicking on *Your Name ▾* on the navigation bar. -Uses the forms to change your personal information. +You can use the forms to change your personal information. # Data integration -AskOmics convert project specific data into RDF triples automatically. It can convert CSV/TSV, GFF and BED files. +AskOmics will convert project specific data into RDF triples automatically. It can convert CSV/TSV, GFF and BED files. !!! Hands-on Download the files for the tutorial using the following links:
@@ -55,9 +59,9 @@ You can upload files from your computer, or distant files using an URL. !!! Tip You can also copy files URL and use the URL button. -Uploaded files are displayed into the files table. Filenames can be change by clicking on it. +Uploaded files are displayed into the files table. Filenames can be changed by clicking on it. -![files_table](img/files_table.png "files_table") +![Files table](img/files_table.png "files_table"){: .center} Next step is to convert this files into RDF triples. This step is called *Integration*. Integration will produce a RDF description of your data: the *Abstraction*. @@ -67,18 +71,22 @@ Next step is to convert this files into RDF triples. This step is called *Integr ## Integration +Detailed information regarding the *Integration* step can be found [here](data.md). + The *integration* convert input files into RDF triples, and load them into an RDF triplestore. AskOmics can convert CSV/TSV, GFF3 and BED files. During the step of integration, AskOmics show a preview of each files. We can choose how the file will be integrated at this step. +More information about data integration is available [here](data.md) + ### GFF -GFF files contain genetic coordinate of entities. Each entities contained in the GFF file are displayed on the preview page. We can Select the entities that will be integrated. +GFF files contain genetic coordinate of entities. Each entity contained in the GFF file is displayed on the preview page. We can Select the entities that will be integrated. !!! Hands-on 1. Search for `Mus_musculus.GRCm38.98.subset.gff3 (preview)` 2. Select `gene` and `mRNA` 3. Integrate (Private dataset) - ![De results preview](img/gff_preview.png) + ![Integration interface for GFF files](img/gff_preview.png){: .center} ### CSV/TSV @@ -86,7 +94,7 @@ GFF files contain genetic coordinate of entities. Each entities contained in the The TSV preview show an HTML table representing the TSV file. During integration, AskOmics will convert the file using the header. -The first column of a TSV file will be the *entity* name. Other columns of the file will be *attributes* of the *entity*. *Labels* of the *entity* and *attributes* will be set by the header. This *labels* can be edited by clicking on it. +The first column of a TSV file will be the *entity* name. Other columns of the file will be *attributes* of the *entity*. *Labels* of the *entity* and *attributes* will be set by the header. The column names can be edited by clicking on it. Entity and attributes can have special types. The types are defined with the select below the header. An *entity* can be a *start entity* or an *entity*. A *start entity* mean that the entity may be used to start a query. @@ -95,6 +103,7 @@ Attributes can take the following types: - Numeric: if all the values are numeric - Text: if all the values are strings +- Date: if all the values are dates - Category: if there is a limited number of repeated values If the entity describe a locatable element on a genome: @@ -116,7 +125,7 @@ A columns can also be a relation between the *entity* to another. In this case, - Keep the other column names and set their types to *numeric* 3. Integrate (Private dataset) - ![De results preview](img/de_results_preview.png) + ![Integration interface for CSV files](img/de_results_preview.png){: .center} !!! Hands-on 1. Search for `symbol-ensembl.tsv (preview)` @@ -125,7 +134,7 @@ A columns can also be a relation between the *entity* to another. In this case, - change `ensembl` to `linkedTo@gene` and set type to *Directed relation* 3. Integrate (Private dataset) - ![Symbol to Ensembl preview](img/symbol_to_ensembl_preview.png) + ![Modifying the name and type of a column](img/symbol_to_ensembl_preview.png){: .center} !!! Hands-on 1. Search for `MGIBatchReport_Qtl_Subset.txt (preview)` @@ -136,7 +145,7 @@ A columns can also be a relation between the *entity* to another. In this case, - set `End` type to *End* 3. Integrate (Private dataset) - ![QTL preview](img/qtl_preview.png) + ![Preview of the QTL file](img/qtl_preview.png){: .center} ### Manage integrated datasets @@ -148,11 +157,11 @@ Integration can take some times depending on the file size. The Datasets page 2. Wait for all datasets to be *success* - ![dataset](img/datasets.png "Datasets table") + ![Table of datasets](img/datasets.png "Datasets table"){: .center} -The table show all integrated datasets. The *status* column show if the datasets is fully integrated or in the process of being integrated. +The table show all integrated datasets. The *status* column show if the datasets are fully integrated or in the process of being integrated. @@ -160,13 +169,15 @@ The table show all integrated datasets. The *status* column show if the datasets Once all the data of interest is integrated (converted to RDF graphs), its time to query them. Querying RDF data is done by using the SPARQL language. Fortunately, AskOmics provides a user-friendly interface to build SPARQL queries without having to learn the SPARQL language. +More information about the query building process is available [here](query.md) + ## Query builder overview ### Simple query The first step to build a query is to choose a start point for the query. -![ask](img/startpoint.png) +![List of startpoints](img/startpoint.png){: .center} !!! Hands-on @@ -178,19 +189,19 @@ The first step to build a query is to choose a start point for the query. Once the start entity is chosen, the query builder is displayed. -The query builder is composed of a graph. Nodes represents *entities* and links represents *relations* between entities. The selected entity is surrounded by a red circle. links and other entities are dotted and lighter because there are not instantiated. +The query builder is composed of a graph. Nodes represents *entities* and links represents *relations* between entities. The selected entity is surrounded by a red circle. Links and other entities are dotted and lighter because there are not instantiated. -![query builder](img/query_builder.png "Query builder, Differential Expression is the selected entity, GeneLink is a suggested entity") +![The query builder](img/query_builder.png "Query builder, Differential Expression is the selected entity, GeneLink is a suggested entity"){: .center} On the right, attributes of the selected entity are displayed as attribute boxes. Each boxes have an eye icon. Open eye mean the attribute will be displayed on the results. !!! Hands-on 1. Display `logFC` and `adj.P.val` by clicking on the eye icon - 2. Run & Preview + 2. Run & preview -![preview results](img/preview_results.png "Results preview") +![Preview of results](img/preview_results.png "Results preview"){: .center} - Run & Preview launch the query with a limit of 30 rows returned. We use this button to get an idea of the results returned. + Run & preview launch the query with a limit of 30 rows returned. We use this button to get an idea of the results returned. ### Filter on attributes @@ -200,38 +211,39 @@ Next query will search for all over-expressed genes. Genes are considered over-e !!! Hands-on 1. Filter `logFC` with `>` `2` 2. Filter `adj.P.val` with `≤` `0.05` - 2. Run & Preview + 2. Run & preview Results show only significantly over-expressed genes. ### Filter on relations -Now that we have our genes if interest, we will link these genes to the reference genome to get information about location. +Now that we have our genes if interest, we will link these genes to the reference genome to get information about the location. -To constraint on relation, we have to click on suggested nodes, linked to our entity of interest. +To constraint on a relation, we have to click on any suggested nodes linked to our entity of interest. !!! Hands-on 1. First, hide `Label`, `logFC` and `adj.P.val` of `Differential Expression` 2. Instantiate `GeneLink`, and hide `Label` 3. Instantiate `gene` - 2. Run & Preview + 2. Run & preview -Results now show the Ensembl id of our over-expressed genes. We have now access to all the information about the `gene` entity containing on the GFF file. for example, we can filter on chromosome and display chromosome and strand to get information about gene location. +Results now show the Ensembl id of our over-expressed genes. We have now access to all the information about the `gene` entity containing on the GFF file. For example, we can filter on chromosome and display chromosome and strand to get information about the gene location. !!! Hands-on 1. Show `reference` and `strand` using the eye icon 2. Filter `reference` to select `X` and `Y` chromosomes (use `ctrl`+`click` to multiple selection) - 2. Run & Preview + 2. Run & preview ### Use FALDO ontology to query on the position of elements on the genome. -The [FALDO](https://bioportal.bioontology.org/ontologies/FALDO) ontology describe sequence feature positions and regions. AskOmics use FALDO ontology to represent entity positions. GFF are using FALDO, as well as TSV entities with chromosome, strand, start and end. +The [FALDO](https://bioportal.bioontology.org/ontologies/FALDO) ontology describe sequence features's positions and regions. AskOmics use the FALDO ontology to represent entity positions. +All entities extracted from GFF and BED files use this ontology, in addition to any entity extracted from a CSV/TSV file with a reference, strand, start and end columns. -The FALDO ontology are used in AskOmics to perform special queries between 2 FALDO entities. These queries are: +The FALDO ontology is used in AskOmics to perform special queries between 2 FALDO entities. These queries are: -- Entity included in another entity -- Entity overlapping another one +- Entity is included in another entity +- Entity is overlapping another entity On the query builder interface, FALDO entities are represented with a green circle and FALDO relations have a green arrow. @@ -241,19 +253,19 @@ On the query builder interface, FALDO entities are represented with a green circ 3. Instantiate `QTL` 4. Click on the link between `gene` and `QTL` to edit the relation 5. check that the relation is `gene` `included in` `QTL` `on the same reference` with `strict` ticked - 7. Run & Preview + 7. Run & preview To go further, we can filter on `QTL` to refine the results. !!! Hands-on - 1. got back to the `QTL` node + 1. Go back to the `QTL` node 2. Show the `Name` attribute using the eye icon 3. Filter the name with a `regexp` with `growth` - 4. Run & Preview + 4. Run & preview -From now, our query is "All Genes that are over-expressed (logFC > 2 and FDR ≤ 0.05) and located on a QTL that are related to growth" This is the results that we are looking for. So we can save it. +From now, our query is "All Genes that are over-expressed (logFC > 2 and FDR ≤ 0.05) and located on a QTL that are related to growth" This is the results that we are looking for. We can now save it. !!! Hands-on 1. Run & save @@ -266,21 +278,36 @@ The results page store the saved queries. A table show some useful information a !!! Hands-on 1. Click on the name and enter `Over-expressed genes on a growth QTL` - 2. press `enter` key + 2. Press the `Enter` key - ![results table](img/results_table.png) + ![Table of results](img/results_table.png){: .center} -The **Action** column contain button to perform certain action: +The **Action** column contain buttons to perform certain action: -- Preview: show a results preview on the bottom of the table +- Preview: Show a results preview on the bottom of the table - Download: Download the results (TSV file) - Edit: Edit the query with the query builder -- SPARQL: edit the query with a SPARQL editor for advanced users +- SPARQL: Access the generated SPARQL query for the result + +For more information about the Results page, please head [here](results.md) !!! Hands-on - 1. Download the results file on your computer using Download button + 1. Download the results file on your computer using the Download button. +The Edit button can be used to simply replay the query after changing some parameters. + +!!! Hands-on + 1. Edit the query, and replace "growth" with another term of interest (such as "anxiety"). + 2. Preview the results + + +## Advanced queries + +Advanced queries, including *UNION* and *MINUS* SPARQL queries are also available to further your queries. +Please head [here](query.md#minus-and-union-nodes) for more information. # Conclusion -In this tutorial we have seen how to use AskOmics Interactive Tool to Build a complex SPARQL query to interrogate 4 different datasets and answer a biological question. \ No newline at end of file +In this tutorial we have seen how to use the AskOmics Interactive Tool, building a complex SPARQL query to interrogate 4 different datasets and answer a biological question. + +This tutorial was a brief overview of AskOmics's functionalities. Please check the other categories on the left-side for more information. diff --git a/mkdocs.yml b/mkdocs.yml index 3d88af34..ae5b080b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,7 +3,7 @@ repo_url: https://github.com/askomics/flaskomics edit_uri: edit/master/docs/ site_author: Xavier Garnier -theme: +theme: name: readthedocs highlightjs: true hljs_languages: @@ -12,6 +12,8 @@ theme: - javascript markdown_extensions: - admonition + - attr_list + - markdown_captions - toc: permalink: true toc_depth: 1 @@ -21,20 +23,26 @@ nav: - Home: index.md - AskOmics tutorials: - Overview tutorial: tutorial.md - - Prepare data: data.md + - Preparing data: data.md + - Building a query: query.md + - Managing results: results.md + - Templates & forms: template.md + - SPARQL console: console.md + - Command-line interface: cli.md - Build RDF Abstraction: abstraction.md - Federated queries: federation.md - AskOmics and Galaxy: galaxy.md - - Contribute: issues.md - - Admin : + - AskOmics and ontologies: ontologies.md + - Administrator guide: - Deploy AskOmics: production-deployment.md - Configure: configure.md - Manage: manage.md + - Custom prefixes: prefixes.md - Developer guide: - Dev deployment: dev-deployment.md - Contribute: contribute.md - CI: ci.md - - Doc: docs.md + - Documentation: docs.md - Bug Tracker: https://github.com/askomics/flaskomics/issues - Project monitoring: https://github.com/askomics/flaskomics/projects diff --git a/package-lock.json b/package-lock.json index 4da746c6..a8d78062 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "AskOmics", - "version": "4.3.1", + "version": "4.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1416,19 +1416,18 @@ "dev": true }, "@npmcli/git": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.0.6.tgz", - "integrity": "sha512-a1MnTfeRPBaKbFY07fd+6HugY1WAkKJzdiJvlRub/9o5xz2F/JtPacZZapx5zRJUQFIzSL677vmTSxEcDMrDbg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.1.0.tgz", + "integrity": "sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==", "dev": true, "requires": { - "@npmcli/promise-spawn": "^1.1.0", + "@npmcli/promise-spawn": "^1.3.2", "lru-cache": "^6.0.0", - "mkdirp": "^1.0.3", - "npm-pick-manifest": "^6.0.0", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^6.1.1", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", - "semver": "^7.3.2", - "unique-filename": "^1.1.1", + "semver": "^7.3.5", "which": "^2.0.2" }, "dependencies": { @@ -2229,11 +2228,11 @@ "dev": true }, "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.2.tgz", + "integrity": "sha512-87otirqUw3e8CzHTMO+/9kh/FSgXt/eVDvipijwDtEuwbkySWZ9SBm6VEubmJ/kLKEoLQV/POhxXFb66bfekfg==", "requires": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" } }, "babel-code-frame": { @@ -4548,6 +4547,11 @@ "is-symbol": "^1.0.2" } }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -5342,9 +5346,9 @@ } }, "follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==" }, "for-in": { "version": "1.0.2", @@ -5514,6 +5518,11 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-input-selection": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/get-input-selection/-/get-input-selection-1.1.4.tgz", + "integrity": "sha512-o3rv95OOpoHznujIEwZljNhUM9efW/gZsIKCQtTrjRU4PkneVpDvxNBmC7kXC4519lZYT95DKcdj0A5f9GZkKg==" + }, "get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", @@ -7114,9 +7123,9 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "minipass": { "version": "3.1.3", @@ -7468,9 +7477,9 @@ "optional": true }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, "nosleep.js": { @@ -8116,9 +8125,9 @@ "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-to-regexp": { @@ -8204,9 +8213,9 @@ "dev": true }, "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -8327,12 +8336,9 @@ "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==" }, "prismjs": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz", - "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==", - "requires": { - "clipboard": "^2.0.0" - } + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==" }, "private": { "version": "0.1.8", @@ -8629,6 +8635,18 @@ "object-assign": "^4.1.0" } }, + "react-autosuggest": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-autosuggest/-/react-autosuggest-10.1.0.tgz", + "integrity": "sha512-/azBHmc6z/31s/lBf6irxPf/7eejQdR0IqnZUzjdSibtlS8+Rw/R79pgDAo6Ft5QqCUTyEQ+f0FhL+1olDQ8OA==", + "requires": { + "es6-promise": "^4.2.8", + "prop-types": "^15.7.2", + "react-themeable": "^1.1.0", + "section-iterator": "^2.0.0", + "shallow-equal": "^1.2.1" + } + }, "react-bootstrap-table-next": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/react-bootstrap-table-next/-/react-bootstrap-table-next-4.0.3.tgz", @@ -8821,6 +8839,37 @@ "refractor": "^3.2.0" } }, + "react-themeable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-themeable/-/react-themeable-1.1.0.tgz", + "integrity": "sha512-kl5tQ8K+r9IdQXZd8WLa+xxYN04lLnJXRVhHfdgwsUJr/SlKJxIejoc9z9obEkx1mdqbTw1ry43fxEUwyD9u7w==", + "requires": { + "object-assign": "^3.0.0" + }, + "dependencies": { + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==" + } + } + }, + "react-tooltip": { + "version": "4.2.21", + "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz", + "integrity": "sha512-zSLprMymBDowknr0KVDiJ05IjZn9mQhhg4PRsqln0OZtURAJ1snt1xi5daZfagsh6vfsziZrc9pErPTDY1ACig==", + "requires": { + "prop-types": "^15.7.2", + "uuid": "^7.0.3" + }, + "dependencies": { + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==" + } + } + }, "react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", @@ -8988,6 +9037,16 @@ "hastscript": "^6.0.0", "parse-entities": "^2.0.0", "prismjs": "~1.23.0" + }, + "dependencies": { + "prismjs": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz", + "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==", + "requires": { + "clipboard": "^2.0.0" + } + } } }, "regenerate": { @@ -9330,6 +9389,11 @@ "ajv-keywords": "^3.5.2" } }, + "section-iterator": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/section-iterator/-/section-iterator-2.0.0.tgz", + "integrity": "sha512-xvTNwcbeDayXotnV32zLb3duQsP+4XosHpb/F+tu6VzEZFmIjzPdNk6/O+QOOx5XTh08KL2ufdXeCO33p380pQ==" + }, "select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -9418,6 +9482,11 @@ "safe-buffer": "^5.0.1" } }, + "shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -9455,9 +9524,9 @@ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", "requires": { "decompress-response": "^3.3.0", "once": "^1.3.1", @@ -10013,9 +10082,9 @@ "dev": true }, "tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", "dev": true, "requires": { "chownr": "^2.0.0", @@ -10096,6 +10165,11 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "textarea-caret": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.1.0.tgz", + "integrity": "sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q==" + }, "three": { "version": "0.126.1", "resolved": "https://registry.npmjs.org/three/-/three-0.126.1.tgz", @@ -11080,9 +11154,9 @@ } }, "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", "dev": true, "requires": { "figgy-pudding": "^3.5.1" diff --git a/package.json b/package.json index 7f18fcc9..a22d4138 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "ontology" ], "name": "AskOmics", - "version": "4.3.1", + "version": "4.4.0", "description": "Visual SPARQL query builder", "author": "Xavier Garnier", "license": "AGPL-3.0", @@ -39,7 +39,7 @@ "@fortawesome/free-brands-svg-icons": "^5.14.0", "@fortawesome/free-regular-svg-icons": "^5.14.0", "@sentry/browser": "^5.24.2", - "axios": "^0.21.1", + "axios": "^0.21.2", "babel-preset-env": "^1.7.0", "bootstrap": "^4.5.2", "css-loader": "^4.3.0", @@ -50,10 +50,11 @@ "immutability-helper": "^3.1.1", "js-file-download": "^0.4.12", "pretty-time": "^1.1.0", - "prismjs": "^1.23.0", + "prismjs": "^1.27.0", "qs": "^6.9.4", "react": "^16.13.1", "react-ace": "^9.1.3", + "react-autosuggest": "^10.1.0", "react-addons-update": "^15.6.3", "react-bootstrap-table-next": "^4.0.3", "react-bootstrap-table2-editor": "^1.4.0", @@ -67,6 +68,7 @@ "react-router-dom": "^5.2.0", "react-simple-code-editor": "^0.11.0", "react-syntax-highlighter": "^15.4.3", + "react-tooltip": "^4.2.21", "reactstrap": "^8.6.0", "style-loader": "^1.2.1", "url-loader": "^4.1.0" diff --git a/setup.py b/setup.py index 158a2a43..85cf2122 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='askomics', - version='4.3.1', + version='4.4.0', description=''' AskOmics is a visual SPARQL query interface supporting both intuitive data integration and querying while shielding the user from most of the @@ -17,8 +17,8 @@ "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", ], - maintainer='Xavier Garnier', - maintainer_email='xavier.garnier@irisa.fr', + maintainer='Mateo Boudet', + maintainer_email='mateo.boudet@inrae.fr', url='https://github.com/askomics/flaskomics', keyword='rdf sparql query data integration', packages=find_packages(), diff --git a/test-data/agro_min.ttl b/test-data/agro_min.ttl new file mode 100644 index 00000000..4f895879 --- /dev/null +++ b/test-data/agro_min.ttl @@ -0,0 +1,70 @@ +@prefix askomics: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix xml: . +@prefix xsd: . +@prefix ns1: . + + + a askomics:ontology ; + a owl:ontology ; + rdfs:label "AGRO". + +[] a owl:ObjectProperty ; + a askomics:AskomicsRelation ; + askomics:uri rdfs:subClassOf ; + rdfs:label "subClassOf" ; + rdfs:domain ; + rdfs:range . + + + a owl:Class ; + rdfs:label "desuckering" ; + rdfs:subClassOf . + + a owl:Class ; + rdfs:label "irrigation water source role" ; + rdfs:subClassOf . + + a owl:Class ; + rdfs:label "irrigation water quantity" ; + rdfs:subClassOf , + . + + a owl:Class ; + rdfs:label "reduced tillage process" ; + rdfs:subClassOf . + + a owl:Class ; + rdfs:label "laser land levelling process" ; + rdfs:subClassOf . + + a owl:Class ; + rdfs:label "chemical pest control process" ; + rdfs:subClassOf . + + a owl:Class ; + rdfs:label "no-till" ; + rdfs:subClassOf , + . + + a owl:Class ; + rdfs:label "puddling process" ; + rdfs:subClassOf . + + a owl:Class ; + rdfs:label "mulch-till" ; + rdfs:subClassOf . + + a owl:Class ; + rdfs:label "ridge-till" ; + rdfs:subClassOf . + + a owl:Class ; + rdfs:label "strip-till" ; + rdfs:subClassOf . + + a owl:Class ; + rdfs:label "aerial application" ; + rdfs:subClassOf . diff --git a/test-data/gene.bed b/test-data/gene.bed index ebfc540a..ffd3c788 100644 --- a/test-data/gene.bed +++ b/test-data/gene.bed @@ -8,4 +8,4 @@ track name="TilingArray" description="TilingArray demonstration" visibility=2 us 7 127477031 127478198 Neg2 400 - 127477031 127478198 0,0,255 7 127478198 127479365 Neg3 300 - 127478198 127479365 0,0,255 7 127479365 127480532 Pos5 1000 + 127479365 127480532 255,0,0 -7 127480532 127481699 Neg4 0 - 127480532 127481699 0,0,255 +7 127480532 127481699 Neg4 0 . 127480532 127481699 0,0,255 diff --git a/test-data/gene.gff3 b/test-data/gene.gff3 index e4b799fb..23c36b1c 100644 --- a/test-data/gene.gff3 +++ b/test-data/gene.gff3 @@ -7,6 +7,8 @@ #!genebuild-last-updated 2010-09 1 tair gene 3631 5899 . + . ID=gene:AT1G01010;Name=NAC001;biotype=protein_coding;description=NAC domain-containing protein 1 [Source:UniProtKB/Swiss-Prot%3BAcc:Q0WV96];gene_id=AT1G01010;logic_name=tair 1 tair transcript 3631 5899 . + . ID=transcript:AT1G01010.1;Parent=gene:AT1G01010;Name=ANAC001;biotype=protein_coding;transcript_id=AT1G01010.1 +1 tair transcript 3632 5900 . - . ID=transcript:AT1G01010.2;Parent=gene:AT1G01010;Name=ANAC002;biotype=protein_coding;transcript_id=AT1G01010.2 +1 tair transcript 3633 5901 . . . ID=transcript:AT1G01010.3;Parent=gene:AT1G01010;Name=ANAC003;biotype=protein_coding;transcript_id=AT1G01010.3 1 tair five_prime_UTR 3631 3759 . + . Parent=transcript:AT1G01010.1 1 tair exon 3631 3913 . + . Parent=transcript:AT1G01010.1;Name=AT1G01010.1.exon1;constitutive=1;ensembl_end_phase=1;ensembl_phase=-1;exon_id=AT1G01010.1.exon1;rank=1 1 tair CDS 3760 3913 . + 0 ID=CDS:AT1G01010.1;Parent=transcript:AT1G01010.1;protein_id=AT1G01010.1 diff --git a/test-data/transcripts.tsv b/test-data/transcripts.tsv index 6117b805..f32ec275 100644 --- a/test-data/transcripts.tsv +++ b/test-data/transcripts.tsv @@ -1,11 +1,11 @@ -transcript taxon featureName chromosomeName start end featureType strand biotype description date -AT3G10490 Arabidopsis_thaliana ANAC052 At3 3267835 3270883 gene plus protein_coding NAC_domain_containing_protein_52_[Source:TAIR%3BAcc:AT3G10490] 01/01/2000 -AT3G13660 Arabidopsis_thaliana DIR22 At3 4464908 4465586 gene plus protein_coding Dirigent_protein_22_[Source:UniProtKB/Swiss-Prot%3BAcc:Q66GI2] 02/01/2000 -AT3G51470 Arabidopsis_thaliana na At3 19097787 19099275 gene minus protein_coding Probable_protein_phosphatase_2C_47_[Source:UniProtKB/Swiss-Prot%3BAcc:Q9SD02] 03/01/2000 -AT3G10460 Arabidopsis_thaliana na At3 3255800 3256439 gene plus protein_coding Plant_self-incompatibility_protein_S1_family_[Source:TAIR%3BAcc:AT3G10460] 04/01/2000 -AT3G22640 Arabidopsis_thaliana PAP85 At3 8011724 8013902 gene minus protein_coding cupin_family_protein_[Source:TAIR%3BAcc:AT3G22640] 05/01/2000 -AT1G33615 Arabidopsis_thaliana na At1 12193325 12194374 ncRNA_gene minus ncRNA other_RNA_[Source:TAIR%3BAcc:AT1G33615] 06/01/2000 -AT5G41905 Arabidopsis_thaliana MIR166E At5 16775524 16775658 miRNA_gene minus miRNA MIR166/MIR166E%3B_miRNA_[Source:TAIR%3BAcc:AT5G41905] 07/01/2000 -AT1G57800 Arabidopsis_thaliana ORTH3 At1 21408623 21412283 gene minus protein_coding E3_ubiquitin-protein_ligase_ORTHRUS_3_[Source:UniProtKB/Swiss-Prot%3BAcc:Q9FVS2] 08/01/2000 -AT1G49500 Arabidopsis_thaliana na At1 18321295 18322284 gene minus protein_coding unknown_protein%3B_FUNCTIONS_IN:_molecular_function_unknown%3B_INVOLVED_IN:_biological_process_unknown%3B_LOCATED_IN:_endomembrane_system%3B_EXPRESSED_IN:_19_plant_structures%3B_EXPRESSED_DURING:_10_growth_stages%3B_BEST_Arabidopsis_thaliana_protein_match_is:_u_/.../_protein_(TAIR:AT3G19030.1)%3B_Has_24_Blast_hits_to_24_proteins_in_2_species:_Archae_-_0%3B_Bacteria_-_0%3B_Metazoa_-_0%3B_Fungi_-_0%3B_Plants_-_24%3B_Viruses_-_0%3B_Other_Eukaryotes_-_0_(source:_NCBI_BLink)._[Source:TAIR%3BAcc:AT1G49500] 09/01/2000 -AT5G35334 Arabidopsis_thaliana na At5 13537917 13538984 gene plus transposable_element transposable_element_gene_[Source:TAIR%3BAcc:AT5G35334] 10/01/2000 +transcript label taxon featureName chromosomeName start end featureType strand biotype description date +AT3G10490 label_AT3G10490 Arabidopsis_thaliana ANAC052 At3 3267835 3270883 gene plus protein_coding NAC_domain_containing_protein_52_[Source:TAIR%3BAcc:AT3G10490] 01/01/2000 +AT3G13660 label_AT3G13660 Arabidopsis_thaliana DIR22 At3 4464908 4465586 gene plus protein_coding Dirigent_protein_22_[Source:UniProtKB/Swiss-Prot%3BAcc:Q66GI2] 02/01/2000 +AT3G51470 label_AT3G51470 Arabidopsis_thaliana na At3 19097787 19099275 gene minus protein_coding Probable_protein_phosphatase_2C_47_[Source:UniProtKB/Swiss-Prot%3BAcc:Q9SD02] 03/01/2000 +AT3G10460 label_AT3G10460 Arabidopsis_thaliana na At3 3255800 3256439 gene plus protein_coding Plant_self-incompatibility_protein_S1_family_[Source:TAIR%3BAcc:AT3G10460] 04/01/2000 +AT3G22640 label_AT3G22640 Arabidopsis_thaliana PAP85 At3 8011724 8013902 gene minus protein_coding cupin_family_protein_[Source:TAIR%3BAcc:AT3G22640] 05/01/2000 +AT1G33615 label_AT1G33615 Arabidopsis_thaliana na At1 12193325 12194374 ncRNA_gene minus ncRNA other_RNA_[Source:TAIR%3BAcc:AT1G33615] 06/01/2000 +AT5G41905 label_AT5G41905 Arabidopsis_thaliana MIR166E At5 16775524 16775658 miRNA_gene minus miRNA MIR166/MIR166E%3B_miRNA_[Source:TAIR%3BAcc:AT5G41905] 07/01/2000 +AT1G57800 label_AT1G57800 Arabidopsis_thaliana ORTH3 At1 21408623 21412283 gene minus protein_coding E3_ubiquitin-protein_ligase_ORTHRUS_3_[Source:UniProtKB/Swiss-Prot%3BAcc:Q9FVS2] 08/01/2000 +AT1G49500 label_AT1G49500 Arabidopsis_thaliana na At1 18321295 18322284 gene minus protein_coding unknown_protein%3B_FUNCTIONS_IN:_molecular_function_unknown%3B_INVOLVED_IN:_biological_process_unknown%3B_LOCATED_IN:_endomembrane_system%3B_EXPRESSED_IN:_19_plant_structures%3B_EXPRESSED_DURING:_10_growth_stages%3B_BEST_Arabidopsis_thaliana_protein_match_is:_u_/.../_protein_(TAIR:AT3G19030.1)%3B_Has_24_Blast_hits_to_24_proteins_in_2_species:_Archae_-_0%3B_Bacteria_-_0%3B_Metazoa_-_0%3B_Fungi_-_0%3B_Plants_-_24%3B_Viruses_-_0%3B_Other_Eukaryotes_-_0_(source:_NCBI_BLink)._[Source:TAIR%3BAcc:AT1G49500] 09/01/2000 +AT5G35334 label_AT5G35334 Arabidopsis_thaliana na At5 13537917 13538984 gene transposable_element transposable_element_gene_[Source:TAIR%3BAcc:AT5G35334] 10/01/2000 diff --git a/tests/__init__.py b/tests/__init__.py index 87a99a2f..7a75d2e3 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -8,4 +8,7 @@ class AskomicsTestCase(): def equal_objects(obj1, obj2): """Compare 2 objects""" ddiff = DeepDiff(obj1, obj2, ignore_order=True, report_repetition=True) + if not ddiff == {}: + print(ddiff) + return True if ddiff == {} else False diff --git a/tests/conftest.py b/tests/conftest.py index 0ddcb52b..999d0248 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,6 +14,8 @@ from askomics.libaskomics.FilesHandler import FilesHandler from askomics.libaskomics.FilesUtils import FilesUtils from askomics.libaskomics.LocalAuth import LocalAuth +from askomics.libaskomics.PrefixManager import PrefixManager +from askomics.libaskomics.OntologyManager import OntologyManager from askomics.libaskomics.SparqlQueryLauncher import SparqlQueryLauncher from askomics.libaskomics.Start import Start from askomics.libaskomics.Result import Result @@ -249,7 +251,8 @@ def upload_file(self, file_path): ".tsv": "text/tab-separated-values", ".csv": "text/tab-separated-values", ".gff3": "null", - ".bed": "null" + ".bed": "null", + ".ttl": "rdf/ttl" } with open(file_path, 'r') as file_content: @@ -273,7 +276,25 @@ def upload_file(self, file_path): "file_date": filedate } - def integrate_file(self, info, public=False): + def upload_file_url(self, file_url): + """Summary + + Parameters + ---------- + file_path : TYPE + Description + + Returns + ------- + TYPE + Description + """ + + files = FilesHandler(self.app, self.session) + files.download_url(file_url, "1") + return files.date + + def integrate_file(self, info, public=False, set_graph=False, endpoint=""): """Summary Parameters @@ -289,6 +310,9 @@ def integrate_file(self, info, public=False): files_handler = FilesHandler(self.app, self.session) files_handler.handle_files([info["id"], ]) + # TODO: Fix this. Why do we need the virtuoso url? + endpoint = endpoint or "http://virtuoso:8890/sparql" + for file in files_handler.files: dataset_info = { @@ -300,7 +324,7 @@ def integrate_file(self, info, public=False): } dataset = Dataset(self.app, self.session, dataset_info) - dataset.save_in_db() + dataset.save_in_db(endpoint, set_graph=set_graph) if file.type == "csv/tsv": file.integrate(dataset.id, info["columns_type"], public=public) @@ -308,7 +332,8 @@ def integrate_file(self, info, public=False): file.integrate(dataset.id, info["entities"], public=public) elif file.type == "bed": file.integrate(dataset.id, info["entity_name"], public=public) - + elif file.type in ('rdf/ttl', 'rdf/xml', 'rdf/nt'): + file.integrate(public=public) # done dataset.update_in_db("success") dataset.set_info_from_db() @@ -316,7 +341,9 @@ def integrate_file(self, info, public=False): return { "timestamp": file.timestamp, "start": dataset.start, - "end": dataset.end + "end": dataset.end, + "graph": dataset.graph_name, + "endpoint": dataset.endpoint } def upload(self): @@ -351,7 +378,7 @@ def upload(self): } } - def upload_and_integrate(self): + def upload_and_integrate(self, set_graph=False): """Summary Returns @@ -369,28 +396,28 @@ def upload_and_integrate(self): # integrate int_transcripts = self.integrate_file({ "id": 1, - "columns_type": ["start_entity", "category", "text", "reference", "start", "end", "category", "strand", "text", "text", "date"] - }) + "columns_type": ["start_entity", "label", "category", "text", "reference", "start", "end", "category", "strand", "text", "text", "date"] + }, set_graph=set_graph) int_de = self.integrate_file({ "id": 2, "columns_type": ["start_entity", "directed", "numeric", "numeric", "numeric", "text", "numeric", "numeric", "numeric", "numeric"] - }) + }, set_graph=set_graph) int_qtl = self.integrate_file({ "id": 3, "columns_type": ["start_entity", "ref", "start", "end"] - }) + }, set_graph=set_graph) int_gff = self.integrate_file({ "id": 4, "entities": ["gene", "transcript"] - }) + }, set_graph=set_graph) int_bed = self.integrate_file({ "id": 5, "entity_name": "gene" - }) + }, set_graph=set_graph) return { "transcripts": { @@ -425,6 +452,31 @@ def upload_and_integrate(self): } } + def upload_and_integrate_ontology(self): + """Summary + + Returns + ------- + TYPE + Description + """ + # upload + up_ontology = self.upload_file("test-data/agro_min.ttl") + + # integrate + int_ontology = self.integrate_file({ + "id": 1, + }, set_graph=True, endpoint="http://localhost:8891/sparql-auth") + + return { + "upload": up_ontology, + "timestamp": int_ontology["timestamp"], + "start": int_ontology["start"], + "end": int_ontology["end"], + "graph": int_ontology["graph"], + "endpoint": int_ontology["endpoint"] + } + def create_result(self, has_form=False): """Create a result entry in db @@ -478,6 +530,13 @@ def create_result(self, has_form=False): "size": file_size } + def publicize_dataset(self, dataset_id, public=True): + """Publicize a result""" + + dataset_info = {"id": dataset_id} + result = Dataset(self.app, self.session, dataset_info) + result.toggle_public(public) + def publicize_result(self, result_id, public=True): """Publicize a result""" @@ -556,6 +615,18 @@ def delete_galaxy_history(self): galaxy = GalaxyInstance(self.gurl, self.gkey) galaxy.histories.delete_history(self.galaxy_history["id"], purge=True) + def create_prefix(self): + """Create custom prefix""" + pm = PrefixManager(self.app, self.session) + pm.add_custom_prefix("OBO", "http://purl.obolibrary.org/obo/") + + def create_ontology(self): + """Create ontology""" + data = self.upload_and_integrate_ontology() + om = OntologyManager(self.app, self.session) + om.add_ontology("AgrO ontology", "http://purl.obolibrary.org/obo/agro.owl", "AGRO", 1, data["graph"], data['endpoint'], type="local") + return data["graph"], data["endpoint"] + @staticmethod def get_random_string(number): """return a random string of n character diff --git a/tests/results/abstraction.json b/tests/results/abstraction.json index e29df978..470c1c59 100644 --- a/tests/results/abstraction.json +++ b/tests/results/abstraction.json @@ -27,14 +27,6 @@ }, { "categories": [ - { - "label": "minus", - "uri": "http://askomics.org/test/data/minus" - }, - { - "label": "plus", - "uri": "http://askomics.org/test/data/plus" - }, { "label": "+", "uri": "http://askomics.org/test/data/%2B" @@ -51,7 +43,6 @@ "entityUri": "http://askomics.org/test/data/gene", "faldo": "http://askomics.org/test/internal/faldoStrand", "graphs": [ - "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", "urn:sparql:askomics_test:1_jdoe:gene.bed_###BED_TIMESTAMP###", "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###" ], @@ -68,6 +59,10 @@ { "label": "plus", "uri": "http://askomics.org/test/data/plus" + }, + { + "label": "unknown/both", + "uri": "http://askomics.org/test/data/unknown/both" }, { "label": "+", @@ -86,8 +81,7 @@ "faldo": "http://askomics.org/test/internal/faldoStrand", "graphs": [ "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.bed_###BED_TIMESTAMP###" + "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###" ], "label": "strand", "type": "http://askomics.org/test/internal/AskomicsCategory", @@ -119,17 +113,12 @@ { "label": "1", "uri": "http://askomics.org/test/data/1" - }, - { - "label": "7", - "uri": "http://askomics.org/test/data/7" } ], "entityUri": "http://askomics.org/test/data/transcript", "faldo": "http://askomics.org/test/internal/faldoReference", "graphs": [ - "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.bed_###BED_TIMESTAMP###" + "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###" ], "label": "reference", "type": "http://askomics.org/test/internal/AskomicsCategory", @@ -140,8 +129,6 @@ "entityUri": "http://askomics.org/test/data/gene", "faldo": "http://askomics.org/test/internal/faldoStart", "graphs": [ - "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:qtl.tsv_###QTL_TIMESTAMP###", "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###", "urn:sparql:askomics_test:1_jdoe:gene.bed_###BED_TIMESTAMP###" ], @@ -154,10 +141,7 @@ "entityUri": "http://askomics.org/test/data/QTL", "faldo": "http://askomics.org/test/internal/faldoStart", "graphs": [ - "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:qtl.tsv_###QTL_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.bed_###BED_TIMESTAMP###" + "urn:sparql:askomics_test:1_jdoe:qtl.tsv_###QTL_TIMESTAMP###" ], "label": "start", "type": "http://www.w3.org/2001/XMLSchema#decimal", @@ -169,9 +153,7 @@ "faldo": "http://askomics.org/test/internal/faldoStart", "graphs": [ "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:qtl.tsv_###QTL_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.bed_###BED_TIMESTAMP###" + "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###" ], "label": "start", "type": "http://www.w3.org/2001/XMLSchema#decimal", @@ -183,9 +165,7 @@ "faldo": "http://askomics.org/test/internal/faldoEnd", "graphs": [ "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:qtl.tsv_###QTL_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.bed_###BED_TIMESTAMP###" + "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###" ], "label": "end", "type": "http://www.w3.org/2001/XMLSchema#decimal", @@ -196,8 +176,6 @@ "entityUri": "http://askomics.org/test/data/gene", "faldo": "http://askomics.org/test/internal/faldoEnd", "graphs": [ - "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:qtl.tsv_###QTL_TIMESTAMP###", "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###", "urn:sparql:askomics_test:1_jdoe:gene.bed_###BED_TIMESTAMP###" ], @@ -210,10 +188,7 @@ "entityUri": "http://askomics.org/test/data/QTL", "faldo": "http://askomics.org/test/internal/faldoEnd", "graphs": [ - "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:qtl.tsv_###QTL_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.bed_###BED_TIMESTAMP###" + "urn:sparql:askomics_test:1_jdoe:qtl.tsv_###QTL_TIMESTAMP###" ], "label": "end", "type": "http://www.w3.org/2001/XMLSchema#decimal", @@ -276,7 +251,6 @@ "entityUri": "http://askomics.org/test/data/gene", "faldo": null, "graphs": [ - "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###" ], "label": "biotype", @@ -288,8 +262,7 @@ "entityUri": "http://askomics.org/test/data/transcript", "faldo": null, "graphs": [ - "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", - "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###" + "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###" ], "label": "description", "type": "http://www.w3.org/2001/XMLSchema#string", @@ -300,7 +273,6 @@ "entityUri": "http://askomics.org/test/data/gene", "faldo": null, "graphs": [ - "urn:sparql:askomics_test:1_jdoe:transcripts.tsv_###TRANSCRIPTS_TIMESTAMP###", "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###" ], "label": "description", @@ -553,7 +525,7 @@ "entities": [ { "endpoints": [ - "http://localhost:8891/sparql" + "http://localhost:8891/sparql-auth" ], "faldo": true, "graphs": [ @@ -563,11 +535,12 @@ "instancesHaveLabels": true, "label": "transcript", "type": "node", + "ontology": false, "uri": "http://askomics.org/test/data/transcript" }, { "endpoints": [ - "http://localhost:8891/sparql" + "http://localhost:8891/sparql-auth" ], "faldo": true, "graphs": [ @@ -577,11 +550,12 @@ "instancesHaveLabels": true, "label": "gene", "type": "node", + "ontology": false, "uri": "http://askomics.org/test/data/gene" }, { "endpoints": [ - "http://localhost:8891/sparql" + "http://localhost:8891/sparql-auth" ], "faldo": true, "graphs": [ @@ -590,11 +564,12 @@ "instancesHaveLabels": true, "label": "QTL", "type": "node", + "ontology": false, "uri": "http://askomics.org/test/data/QTL" }, { "endpoints": [ - "http://localhost:8891/sparql" + "http://localhost:8891/sparql-auth" ], "faldo": false, "graphs": [ @@ -603,6 +578,7 @@ "instancesHaveLabels": true, "label": "DifferentialExpression", "type": "node", + "ontology": false, "uri": "http://askomics.org/test/data/DifferentialExpression" } ], diff --git a/tests/results/data.json b/tests/results/data.json deleted file mode 100644 index 4d92ef58..00000000 --- a/tests/results/data.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "data": [ - { - "object": "http://askomics.org/test/data/transcript", - "predicat": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" - }, - { - "object": "AT3G10490", - "predicat": "http://www.w3.org/2000/01/rdf-schema#label" - }, - { - "object": "protein_coding", - "predicat": "http://askomics.org/test/data/biotype" - }, - { - "object": "NAC_domain_containing_protein_52_[Source:TAIR%3BAcc:AT3G10490]", - "predicat": "http://askomics.org/test/data/description" - }, - { - "object": "ANAC052", - "predicat": "http://askomics.org/test/data/featureName" - }, - { - "object": "http://askomics.org/test/data/gene", - "predicat": "http://askomics.org/test/data/featureType" - }, - { - "object": "http://askomics.org/test/data/Arabidopsis_thaliana", - "predicat": "http://askomics.org/test/data/taxon" - }, - { - "object": "326", - "predicat": "http://askomics.org/test/internal/includeIn" - }, - { - "object": "327", - "predicat": "http://askomics.org/test/internal/includeIn" - }, - { - "object": "http://askomics.org/test/data/At3_326", - "predicat": "http://askomics.org/test/internal/includeInReference" - }, - { - "object": "http://askomics.org/test/data/At3_327", - "predicat": "http://askomics.org/test/internal/includeInReference" - }, - { - "object": "2000-01-01", - "predicat": "http://askomics.org/test/data/date" - } - ], - "error": false, - "errorMessage": "" -} diff --git a/tests/results/data_full.json b/tests/results/data_full.json new file mode 100644 index 00000000..9b8b8473 --- /dev/null +++ b/tests/results/data_full.json @@ -0,0 +1,62 @@ +{ + "data":[ + { + "object":"3267835", + "predicate":"http://askomics.org/test/data/start" + }, + { + "object":"3270883", + "predicate":"http://askomics.org/test/data/end" + }, + { + "object":"At3", + "predicate":"http://askomics.org/test/data/chromosomeName" + }, + { + "object":"At3", + "predicate":"http://askomics.org/test/data/reference" + }, + { + "object":"plus", + "predicate":"http://askomics.org/test/data/strand" + }, + { + "object":"+", + "predicate":"http://askomics.org/test/data/strand" + }, + { + "object":"protein_coding", + "predicate":"http://askomics.org/test/data/biotype" + }, + { + "object":"http://askomics.org/test/data/gene", + "predicate":"http://askomics.org/test/data/featureType" + }, + { + "object":"label_AT3G10490", + "predicate":"http://www.w3.org/2000/01/rdf-schema#label" + }, + { + "object":"2000-01-01", + "predicate":"http://askomics.org/test/data/date" + }, + { + "object":"http://askomics.org/test/data/transcript", + "predicate":"http://www.w3.org/1999/02/22-rdf-syntax-ns#type" + }, + { + "object":"ANAC052", + "predicate":"http://askomics.org/test/data/featureName" + }, + { + "object":"http://askomics.org/test/data/Arabidopsis_thaliana", + "predicate":"http://askomics.org/test/data/taxon" + }, + { + "object":"NAC_domain_containing_protein_52_[Source:TAIR%3BAcc:AT3G10490]", + "predicate":"http://askomics.org/test/data/description" + } + ], + "error":false, + "errorMessage":"" +} diff --git a/tests/results/data_public.json b/tests/results/data_public.json new file mode 100644 index 00000000..fe294d76 --- /dev/null +++ b/tests/results/data_public.json @@ -0,0 +1,54 @@ +{ + "data":[ + { + "object":"3267835", + "predicate":"http://askomics.org/test/data/start" + }, + { + "object":"3270883", + "predicate":"http://askomics.org/test/data/end" + }, + { + "object":"At3", + "predicate":"http://askomics.org/test/data/chromosomeName" + }, + { + "object":"plus", + "predicate":"http://askomics.org/test/data/strand" + }, + { + "object":"protein_coding", + "predicate":"http://askomics.org/test/data/biotype" + }, + { + "object":"http://askomics.org/test/data/gene", + "predicate":"http://askomics.org/test/data/featureType" + }, + { + "object":"label_AT3G10490", + "predicate":"http://www.w3.org/2000/01/rdf-schema#label" + }, + { + "object":"2000-01-01", + "predicate":"http://askomics.org/test/data/date" + }, + { + "object":"http://askomics.org/test/data/transcript", + "predicate":"http://www.w3.org/1999/02/22-rdf-syntax-ns#type" + }, + { + "object":"ANAC052", + "predicate":"http://askomics.org/test/data/featureName" + }, + { + "object":"http://askomics.org/test/data/Arabidopsis_thaliana", + "predicate":"http://askomics.org/test/data/taxon" + }, + { + "object":"NAC_domain_containing_protein_52_[Source:TAIR%3BAcc:AT3G10490]", + "predicate":"http://askomics.org/test/data/description" + } + ], + "error":false, + "errorMessage":"" +} diff --git a/tests/results/init.json b/tests/results/init.json index d557420b..0f3054bf 100644 --- a/tests/results/init.json +++ b/tests/results/init.json @@ -1,5 +1,5 @@ { - "defaultQuery": "PREFIX : \nPREFIX askomics: \nPREFIX dc: \nPREFIX faldo: \nPREFIX owl: \nPREFIX prov: \nPREFIX rdf: \nPREFIX rdfs: \nPREFIX xsd: \n\nSELECT DISTINCT ?s ?p ?o\nWHERE {\n ?s ?p ?o\n}\n", + "defaultQuery": "PREFIX : \nPREFIX askomics: \nPREFIX dc: \nPREFIX dcat: \nPREFIX faldo: \nPREFIX owl: \nPREFIX prov: \nPREFIX rdf: \nPREFIX rdfs: \nPREFIX skos: \nPREFIX xsd: \n\nSELECT DISTINCT ?s ?p ?o\nWHERE {\n ?s ?p ?o\n}\n", "diskSpace": ###SIZE###, "console_enabled": true, "endpoints": { diff --git a/tests/results/preview.json b/tests/results/preview.json index a26074f0..8aaa4dc6 100644 --- a/tests/results/preview.json +++ b/tests/results/preview.json @@ -7,37 +7,43 @@ "id": 1, "preview": [ { - "transcript1_Label": "AT1G57800" + "transcript1_Label": "label_AT1G57800" }, { - "transcript1_Label": "AT5G35334" + "transcript1_Label": "label_AT5G35334" }, { - "transcript1_Label": "AT3G10460" + "transcript1_Label": "label_AT3G10460" }, { - "transcript1_Label": "AT1G49500" + "transcript1_Label": "label_AT1G49500" }, { - "transcript1_Label": "AT3G10490" + "transcript1_Label": "label_AT3G10490" }, { - "transcript1_Label": "AT3G51470" + "transcript1_Label": "label_AT3G51470" }, { - "transcript1_Label": "AT5G41905" + "transcript1_Label": "label_AT5G41905" }, { - "transcript1_Label": "AT1G33615" + "transcript1_Label": "label_AT1G33615" }, { - "transcript1_Label": "AT3G22640" + "transcript1_Label": "label_AT3G22640" }, { - "transcript1_Label": "AT3G13660" + "transcript1_Label": "label_AT3G13660" }, { "transcript1_Label": "AT1G01010.1" + }, + { + "transcript1_Label": "AT1G01010.2" + }, + { + "transcript1_Label": "AT1G01010.3" } ] -} \ No newline at end of file +} diff --git a/tests/results/preview_files.json b/tests/results/preview_files.json index e38881d1..6497c378 100644 --- a/tests/results/preview_files.json +++ b/tests/results/preview_files.json @@ -6,6 +6,7 @@ "data": { "columns_type": [ "start_entity", + "label", "text", "text", "reference", @@ -29,7 +30,8 @@ "strand": "plus", "taxon": "Arabidopsis_thaliana", "transcript": "AT3G10490", - "date": "01/01/2000" + "date": "01/01/2000", + "label": "label_AT3G10490" }, { "biotype": "protein_coding", @@ -42,7 +44,8 @@ "strand": "plus", "taxon": "Arabidopsis_thaliana", "transcript": "AT3G13660", - "date": "02/01/2000" + "date": "02/01/2000", + "label": "label_AT3G13660" }, { "biotype": "protein_coding", @@ -55,7 +58,8 @@ "strand": "minus", "taxon": "Arabidopsis_thaliana", "transcript": "AT3G51470", - "date": "03/01/2000" + "date": "03/01/2000", + "label": "label_AT3G51470" }, { "biotype": "protein_coding", @@ -68,7 +72,8 @@ "strand": "plus", "taxon": "Arabidopsis_thaliana", "transcript": "AT3G10460", - "date": "04/01/2000" + "date": "04/01/2000", + "label": "label_AT3G10460" }, { "biotype": "protein_coding", @@ -81,7 +86,8 @@ "strand": "minus", "taxon": "Arabidopsis_thaliana", "transcript": "AT3G22640", - "date": "05/01/2000" + "date": "05/01/2000", + "label": "label_AT3G22640" }, { "biotype": "ncRNA", @@ -94,7 +100,8 @@ "strand": "minus", "taxon": "Arabidopsis_thaliana", "transcript": "AT1G33615", - "date": "06/01/2000" + "date": "06/01/2000", + "label": "label_AT1G33615" }, { "biotype": "miRNA", @@ -107,7 +114,8 @@ "strand": "minus", "taxon": "Arabidopsis_thaliana", "transcript": "AT5G41905", - "date": "07/01/2000" + "date": "07/01/2000", + "label": "label_AT5G41905" }, { "biotype": "protein_coding", @@ -120,7 +128,8 @@ "strand": "minus", "taxon": "Arabidopsis_thaliana", "transcript": "AT1G57800", - "date": "08/01/2000" + "date": "08/01/2000", + "label": "label_AT1G57800" }, { "biotype": "protein_coding", @@ -133,7 +142,8 @@ "strand": "minus", "taxon": "Arabidopsis_thaliana", "transcript": "AT1G49500", - "date": "09/01/2000" + "date": "09/01/2000", + "label": "label_AT1G49500" }, { "biotype": "transposable_element", @@ -143,14 +153,16 @@ "featureName": "na", "featureType": "gene", "start": "13537917", - "strand": "plus", + "strand": "", "taxon": "Arabidopsis_thaliana", "transcript": "AT5G35334", - "date": "10/01/2000" + "date": "10/01/2000", + "label": "label_AT5G35334" } ], "header": [ "transcript", + "label", "taxon", "featureName", "chromosomeName", @@ -169,5 +181,5 @@ "error": false, "error_message": "" } - ] +] } diff --git a/tests/results/preview_malformed_files.json b/tests/results/preview_malformed_files.json index 2035e650..44312c87 100644 --- a/tests/results/preview_malformed_files.json +++ b/tests/results/preview_malformed_files.json @@ -22,5 +22,5 @@ "error": true, "error_message": "Malformated CSV/TSV (Empty column in header)" } - ] +] } diff --git a/tests/results/results.json b/tests/results/results.json index 978cd972..e561abd1 100644 --- a/tests/results/results.json +++ b/tests/results/results.json @@ -9,7 +9,7 @@ "execTime": ###EXECTIME###, "graphState": "{\"nodes\": [{\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, {\"uri\": \"http://askomics.org/test/data/gene\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", \"urn:sparql:askomics_test:1_jdoe:gene.bed_1590576352\", null], \"id\": 18, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"gene\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#d80002\", \"index\": 1, \"x\": -18.936663966428853, \"y\": 27.854539518654068, \"vx\": 3.0435888926329303e-10, \"vy\": 2.455944547131252e-10}, {\"uri\": \"http://askomics.org/test/data/DifferentialExpression\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, null, \"urn:sparql:askomics_test:1_jdoe:de.tsv_1590570405\"], \"id\": 20, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"DifferentialExpression\", \"faldo\": false, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#c40003\", \"index\": 2, \"x\": -5.504944105164966, \"y\": -30.053414398937772, \"vx\": 1.6289496823647462e-10, \"vy\": 1.9886120976258667e-10}, {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 23, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#b00004\", \"index\": 3, \"x\": 24.169971227492816, \"y\": 27.218300246800673, \"vx\": 3.366634402979017e-10, \"vy\": 1.1297513262220989e-10}, {\"uri\": \"http://askomics.org/test/data/QTL\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, \"urn:sparql:askomics_test:1_jdoe:qtl.tsv_1590570413\", null, null], \"id\": 25, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"QTL\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#9c0005\", \"index\": 4, \"x\": -29.503539254383465, \"y\": -7.095712074145055, \"vx\": 2.1843706072578676e-10, \"vy\": 2.560853024904153e-10}, {\"uri\": \"http://askomics.org/test/data/gene\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", \"urn:sparql:askomics_test:1_jdoe:gene.bed_1590576352\", null], \"id\": 27, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"gene\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#880006\", \"index\": 5, \"x\": 27.314123105593524, \"y\": -20.150587318393672, \"vx\": 1.8446839255154e-10, \"vy\": 1.1018030967605363e-10}], \"links\": [{\"uri\": \"http://askomics.org/test/data/Parent\", \"type\": \"link\", \"sameStrand\": true, \"sameRef\": true, \"id\": 19, \"label\": \"Parent\", \"source\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, \"target\": {\"uri\": \"http://askomics.org/test/data/gene\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", \"urn:sparql:askomics_test:1_jdoe:gene.bed_1590576352\", null], \"id\": 18, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"gene\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#d80002\", \"index\": 1, \"x\": -18.936663966428853, \"y\": 27.854539518654068, \"vx\": 3.0435888926329303e-10, \"vy\": 2.455944547131252e-10}, \"selected\": false, \"suggested\": true, \"directed\": true, \"__indexColor\": \"#740007\", \"__controlPoints\": null, \"index\": 0}, {\"uri\": \"http://askomics.org/test/data/concern\", \"type\": \"link\", \"sameStrand\": false, \"sameRef\": false, \"id\": 22, \"label\": \"concern\", \"source\": {\"uri\": \"http://askomics.org/test/data/DifferentialExpression\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, null, \"urn:sparql:askomics_test:1_jdoe:de.tsv_1590570405\"], \"id\": 20, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"DifferentialExpression\", \"faldo\": false, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#c40003\", \"index\": 2, \"x\": -5.504944105164966, \"y\": -30.053414398937772, \"vx\": 1.6289496823647462e-10, \"vy\": 1.9886120976258667e-10}, \"target\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, \"selected\": false, \"suggested\": true, \"directed\": true, \"__indexColor\": \"#600008\", \"__controlPoints\": null, \"index\": 1}, {\"uri\": \"included_in\", \"type\": \"posLink\", \"id\": 24, \"sameStrand\": true, \"sameRef\": true, \"strict\": true, \"label\": \"Included in\", \"source\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, \"target\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 23, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#b00004\", \"index\": 3, \"x\": 24.169971227492816, \"y\": 27.218300246800673, \"vx\": 3.366634402979017e-10, \"vy\": 1.1297513262220989e-10}, \"selected\": false, \"suggested\": true, \"directed\": true, \"__indexColor\": \"#4c0009\", \"__controlPoints\": null, \"index\": 2}, {\"uri\": \"included_in\", \"type\": \"posLink\", \"id\": 26, \"sameStrand\": false, \"sameRef\": true, \"strict\": true, \"label\": \"Included in\", \"source\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, \"target\": {\"uri\": \"http://askomics.org/test/data/QTL\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, \"urn:sparql:askomics_test:1_jdoe:qtl.tsv_1590570413\", null, null], \"id\": 25, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"QTL\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#9c0005\", \"index\": 4, \"x\": -29.503539254383465, \"y\": -7.095712074145055, \"vx\": 2.1843706072578676e-10, \"vy\": 2.560853024904153e-10}, \"selected\": false, \"suggested\": true, \"directed\": true, \"__indexColor\": \"#38000a\", \"__controlPoints\": null, \"index\": 3}, {\"uri\": \"included_in\", \"type\": \"posLink\", \"id\": 28, \"sameStrand\": true, \"sameRef\": true, \"strict\": true, \"label\": \"Included in\", \"source\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, \"target\": {\"uri\": \"http://askomics.org/test/data/gene\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", \"urn:sparql:askomics_test:1_jdoe:gene.bed_1590576352\", null], \"id\": 27, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"gene\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#880006\", \"index\": 5, \"x\": 27.314123105593524, \"y\": -20.150587318393672, \"vx\": 1.8446839255154e-10, \"vy\": 1.1018030967605363e-10}, \"selected\": false, \"suggested\": true, \"directed\": true, \"__indexColor\": \"#24000b\", \"__controlPoints\": null, \"index\": 4}], \"attr\": [{\"id\": 2, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"rdf:type\", \"label\": \"Uri\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"uri\", \"faldo\": false, \"filterType\": \"exact\", \"filterValue\": \"\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null}, {\"id\": 3, \"visible\": true, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"rdfs:label\", \"label\": \"Label\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": false, \"filterType\": \"exact\", \"filterValue\": \"\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null}, {\"id\": 4, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/strand\", \"label\": \"strand\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": \"http://askomics.org/internal/faldoStrand\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"plus\", \"uri\": \"http://askomics.org/test/data/plus\"}, {\"label\": \"minus\", \"uri\": \"http://askomics.org/test/data/minus\"}, {\"label\": \"-\", \"uri\": \"http://askomics.org/test/data/-\"}, {\"label\": \"+\", \"uri\": \"http://askomics.org/test/data/%2B\"}], \"filterSelectedValues\": []}, {\"id\": 5, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/reference\", \"label\": \"reference\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": \"http://askomics.org/internal/faldoReference\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"1\", \"uri\": \"http://askomics.org/test/data/1\"}], \"filterSelectedValues\": []}, {\"id\": 6, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/chromosomeName\", \"label\": \"chromosomeName\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": \"http://askomics.org/internal/faldoReference\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"At3\", \"uri\": \"http://askomics.org/test/data/At3\"}, {\"label\": \"At5\", \"uri\": \"http://askomics.org/test/data/At5\"}, {\"label\": \"At1\", \"uri\": \"http://askomics.org/test/data/At1\"}], \"filterSelectedValues\": []}, {\"id\": 7, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/taxon\", \"label\": \"taxon\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"Arabidopsis_thaliana\", \"uri\": \"http://askomics.org/test/data/Arabidopsis_thaliana\"}], \"filterSelectedValues\": []}, {\"id\": 8, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/featureType\", \"label\": \"featureType\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"gene\", \"uri\": \"http://askomics.org/test/data/gene\"}, {\"label\": \"miRNA_gene\", \"uri\": \"http://askomics.org/test/data/miRNA_gene\"}, {\"label\": \"ncRNA_gene\", \"uri\": \"http://askomics.org/test/data/ncRNA_gene\"}], \"filterSelectedValues\": []}, {\"id\": 9, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/biotype\", \"label\": \"biotype\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"miRNA\", \"uri\": \"http://askomics.org/test/data/miRNA\"}, {\"label\": \"ncRNA\", \"uri\": \"http://askomics.org/test/data/ncRNA\"}, {\"label\": \"protein_coding\", \"uri\": \"http://askomics.org/test/data/protein_coding\"}, {\"label\": \"transposable_element\", \"uri\": \"http://askomics.org/test/data/transposable_element\"}], \"filterSelectedValues\": []}, {\"id\": 10, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/start\", \"label\": \"start\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"decimal\", \"faldo\": \"http://askomics.org/internal/faldoStart\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filters\": [{\"filterValue\": \"\", \"filterSign\": \"=\"}]}, {\"id\": 11, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/end\", \"label\": \"end\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"decimal\", \"faldo\": \"http://askomics.org/internal/faldoEnd\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filters\": [{\"filterValue\": \"\", \"filterSign\": \"=\"}]}, {\"id\": 12, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/description\", \"label\": \"description\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}, {\"id\": 13, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/featureName\", \"label\": \"featureName\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}, {\"id\": 14, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/ID\", \"label\": \"ID\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}, {\"id\": 15, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/Name\", \"label\": \"Name\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}, {\"id\": 16, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/source\", \"label\": \"source\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}, {\"id\": 17, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/transcript_id\", \"label\": \"transcript_id\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}]}", "id": ###ID###, - "nrows": 11, + "nrows": 13, "path": "###PATH###", "public": ###PUBLIC###, "size": ###SIZE###, diff --git a/tests/results/results_admin.json b/tests/results/results_admin.json index a21b0c64..34cceb45 100644 --- a/tests/results/results_admin.json +++ b/tests/results/results_admin.json @@ -7,7 +7,7 @@ "end": ###END###, "execTime": ###EXECTIME###, "id": ###ID###, - "nrows": 11, + "nrows": 13, "public": ###PUBLIC###, "size": ###SIZE###, "start": ###START###, diff --git a/tests/results/results_form.json b/tests/results/results_form.json index 5c4cb14a..8d9bcc64 100644 --- a/tests/results/results_form.json +++ b/tests/results/results_form.json @@ -11,7 +11,7 @@ "graphState": "{\"nodes\": [{\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, {\"uri\": \"http://askomics.org/test/data/gene\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", \"urn:sparql:askomics_test:1_jdoe:gene.bed_1590576352\", null], \"id\": 18, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"gene\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#d80002\", \"index\": 1, \"x\": -18.936663966428853, \"y\": 27.854539518654068, \"vx\": 3.0435888926329303e-10, \"vy\": 2.455944547131252e-10}, {\"uri\": \"http://askomics.org/test/data/DifferentialExpression\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, null, \"urn:sparql:askomics_test:1_jdoe:de.tsv_1590570405\"], \"id\": 20, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"DifferentialExpression\", \"faldo\": false, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#c40003\", \"index\": 2, \"x\": -5.504944105164966, \"y\": -30.053414398937772, \"vx\": 1.6289496823647462e-10, \"vy\": 1.9886120976258667e-10}, {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 23, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#b00004\", \"index\": 3, \"x\": 24.169971227492816, \"y\": 27.218300246800673, \"vx\": 3.366634402979017e-10, \"vy\": 1.1297513262220989e-10}, {\"uri\": \"http://askomics.org/test/data/QTL\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, \"urn:sparql:askomics_test:1_jdoe:qtl.tsv_1590570413\", null, null], \"id\": 25, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"QTL\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#9c0005\", \"index\": 4, \"x\": -29.503539254383465, \"y\": -7.095712074145055, \"vx\": 2.1843706072578676e-10, \"vy\": 2.560853024904153e-10}, {\"uri\": \"http://askomics.org/test/data/gene\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", \"urn:sparql:askomics_test:1_jdoe:gene.bed_1590576352\", null], \"id\": 27, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"gene\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#880006\", \"index\": 5, \"x\": 27.314123105593524, \"y\": -20.150587318393672, \"vx\": 1.8446839255154e-10, \"vy\": 1.1018030967605363e-10}], \"links\": [{\"uri\": \"http://askomics.org/test/data/Parent\", \"type\": \"link\", \"sameStrand\": true, \"sameRef\": true, \"id\": 19, \"label\": \"Parent\", \"source\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, \"target\": {\"uri\": \"http://askomics.org/test/data/gene\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", \"urn:sparql:askomics_test:1_jdoe:gene.bed_1590576352\", null], \"id\": 18, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"gene\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#d80002\", \"index\": 1, \"x\": -18.936663966428853, \"y\": 27.854539518654068, \"vx\": 3.0435888926329303e-10, \"vy\": 2.455944547131252e-10}, \"selected\": false, \"suggested\": true, \"directed\": true, \"__indexColor\": \"#740007\", \"__controlPoints\": null, \"index\": 0}, {\"uri\": \"http://askomics.org/test/data/concern\", \"type\": \"link\", \"sameStrand\": false, \"sameRef\": false, \"id\": 22, \"label\": \"concern\", \"source\": {\"uri\": \"http://askomics.org/test/data/DifferentialExpression\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, null, \"urn:sparql:askomics_test:1_jdoe:de.tsv_1590570405\"], \"id\": 20, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"DifferentialExpression\", \"faldo\": false, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#c40003\", \"index\": 2, \"x\": -5.504944105164966, \"y\": -30.053414398937772, \"vx\": 1.6289496823647462e-10, \"vy\": 1.9886120976258667e-10}, \"target\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, \"selected\": false, \"suggested\": true, \"directed\": true, \"__indexColor\": \"#600008\", \"__controlPoints\": null, \"index\": 1}, {\"uri\": \"included_in\", \"type\": \"posLink\", \"id\": 24, \"sameStrand\": true, \"sameRef\": true, \"strict\": true, \"label\": \"Included in\", \"source\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, \"target\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 23, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#b00004\", \"index\": 3, \"x\": 24.169971227492816, \"y\": 27.218300246800673, \"vx\": 3.366634402979017e-10, \"vy\": 1.1297513262220989e-10}, \"selected\": false, \"suggested\": true, \"directed\": true, \"__indexColor\": \"#4c0009\", \"__controlPoints\": null, \"index\": 2}, {\"uri\": \"included_in\", \"type\": \"posLink\", \"id\": 26, \"sameStrand\": false, \"sameRef\": true, \"strict\": true, \"label\": \"Included in\", \"source\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, \"target\": {\"uri\": \"http://askomics.org/test/data/QTL\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, \"urn:sparql:askomics_test:1_jdoe:qtl.tsv_1590570413\", null, null], \"id\": 25, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"QTL\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#9c0005\", \"index\": 4, \"x\": -29.503539254383465, \"y\": -7.095712074145055, \"vx\": 2.1843706072578676e-10, \"vy\": 2.560853024904153e-10}, \"selected\": false, \"suggested\": true, \"directed\": true, \"__indexColor\": \"#38000a\", \"__controlPoints\": null, \"index\": 3}, {\"uri\": \"included_in\", \"type\": \"posLink\", \"id\": 28, \"sameStrand\": true, \"sameRef\": true, \"strict\": true, \"label\": \"Included in\", \"source\": {\"uri\": \"http://askomics.org/test/data/transcript\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [\"urn:sparql:askomics_test:1_jdoe:transcripts.tsv_1590570429\", \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", null, null, null], \"id\": 1, \"humanId\": 1, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"transcript\", \"faldo\": true, \"selected\": true, \"suggested\": false, \"__indexColor\": \"#ec0001\", \"index\": 0, \"x\": 2.4610529943331394, \"y\": 2.226874027134668, \"vx\": 2.353770443806525e-10, \"vy\": 1.892184783500829e-10}, \"target\": {\"uri\": \"http://askomics.org/test/data/gene\", \"type\": \"node\", \"filterNode\": \"\", \"filterLink\": \"\", \"graphs\": [null, null, \"urn:sparql:askomics_test:1_jdoe:gene.gff3_1590576352\", \"urn:sparql:askomics_test:1_jdoe:gene.bed_1590576352\", null], \"id\": 27, \"humanId\": null, \"specialNodeId\": null, \"specialNodeGroupId\": null, \"specialPreviousIds\": [null, null], \"label\": \"gene\", \"faldo\": true, \"selected\": false, \"suggested\": true, \"__indexColor\": \"#880006\", \"index\": 5, \"x\": 27.314123105593524, \"y\": -20.150587318393672, \"vx\": 1.8446839255154e-10, \"vy\": 1.1018030967605363e-10}, \"selected\": false, \"suggested\": true, \"directed\": true, \"__indexColor\": \"#24000b\", \"__controlPoints\": null, \"index\": 4}], \"attr\": [{\"id\": 2, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"rdf:type\", \"label\": \"Uri\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"uri\", \"faldo\": false, \"filterType\": \"exact\", \"filterValue\": \"\", \"optional\": false, \"negative\": false, \"linked\": false, \"form\": true, \"linkedWith\": null}, {\"id\": 3, \"visible\": true, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"rdfs:label\", \"label\": \"Label\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": false, \"filterType\": \"exact\", \"filterValue\": \"\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null}, {\"id\": 4, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/strand\", \"label\": \"strand\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": \"http://askomics.org/internal/faldoStrand\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"plus\", \"uri\": \"http://askomics.org/test/data/plus\"}, {\"label\": \"minus\", \"uri\": \"http://askomics.org/test/data/minus\"}, {\"label\": \"-\", \"uri\": \"http://askomics.org/test/data/-\"}, {\"label\": \"+\", \"uri\": \"http://askomics.org/test/data/%2B\"}], \"filterSelectedValues\": []}, {\"id\": 5, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/reference\", \"label\": \"reference\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": \"http://askomics.org/internal/faldoReference\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"1\", \"uri\": \"http://askomics.org/test/data/1\"}], \"filterSelectedValues\": []}, {\"id\": 6, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/chromosomeName\", \"label\": \"chromosomeName\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": \"http://askomics.org/internal/faldoReference\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"At3\", \"uri\": \"http://askomics.org/test/data/At3\"}, {\"label\": \"At5\", \"uri\": \"http://askomics.org/test/data/At5\"}, {\"label\": \"At1\", \"uri\": \"http://askomics.org/test/data/At1\"}], \"filterSelectedValues\": []}, {\"id\": 7, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/taxon\", \"label\": \"taxon\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"Arabidopsis_thaliana\", \"uri\": \"http://askomics.org/test/data/Arabidopsis_thaliana\"}], \"filterSelectedValues\": []}, {\"id\": 8, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/featureType\", \"label\": \"featureType\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"gene\", \"uri\": \"http://askomics.org/test/data/gene\"}, {\"label\": \"miRNA_gene\", \"uri\": \"http://askomics.org/test/data/miRNA_gene\"}, {\"label\": \"ncRNA_gene\", \"uri\": \"http://askomics.org/test/data/ncRNA_gene\"}], \"filterSelectedValues\": []}, {\"id\": 9, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/biotype\", \"label\": \"biotype\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"category\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterValues\": [{\"label\": \"miRNA\", \"uri\": \"http://askomics.org/test/data/miRNA\"}, {\"label\": \"ncRNA\", \"uri\": \"http://askomics.org/test/data/ncRNA\"}, {\"label\": \"protein_coding\", \"uri\": \"http://askomics.org/test/data/protein_coding\"}, {\"label\": \"transposable_element\", \"uri\": \"http://askomics.org/test/data/transposable_element\"}], \"filterSelectedValues\": []}, {\"id\": 10, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/start\", \"label\": \"start\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"decimal\", \"faldo\": \"http://askomics.org/internal/faldoStart\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filters\": [{\"filterValue\": \"\", \"filterSign\": \"=\"}]}, {\"id\": 11, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/end\", \"label\": \"end\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"decimal\", \"faldo\": \"http://askomics.org/internal/faldoEnd\", \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filters\": [{\"filterValue\": \"\", \"filterSign\": \"=\"}]}, {\"id\": 12, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/description\", \"label\": \"description\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}, {\"id\": 13, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/featureName\", \"label\": \"featureName\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}, {\"id\": 14, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/ID\", \"label\": \"ID\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}, {\"id\": 15, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/Name\", \"label\": \"Name\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}, {\"id\": 16, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/source\", \"label\": \"source\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}, {\"id\": 17, \"visible\": false, \"nodeId\": 1, \"humanNodeId\": 1, \"uri\": \"http://askomics.org/test/data/transcript_id\", \"label\": \"transcript_id\", \"entityLabel\": \"transcript\", \"entityUris\": [\"http://askomics.org/test/data/transcript\"], \"type\": \"text\", \"faldo\": null, \"optional\": false, \"negative\": false, \"linked\": false, \"linkedWith\": null, \"filterType\": \"exact\", \"filterValue\": \"\"}]}", "has_form_attr": ###HAS_FORM_ATTR###, "id": ###ID###, - "nrows": 11, + "nrows": 13, "path": "###PATH###", "public": ###PUBLIC###, "size": ###SIZE###, diff --git a/tests/results/sparql_and_graph.json b/tests/results/sparql_and_graph.json index 34caa773..cc485305 100644 --- a/tests/results/sparql_and_graph.json +++ b/tests/results/sparql_and_graph.json @@ -9,6 +9,7 @@ }, "error": false, "errorMessage": "", + "console_enabled": true, "graphState": { "attr": [ { @@ -435,4 +436,4 @@ } }, "sparqlQuery": null -} \ No newline at end of file +} diff --git a/tests/results/sparql_preview.json b/tests/results/sparql_preview.json index b372209c..e508fa85 100644 --- a/tests/results/sparql_preview.json +++ b/tests/results/sparql_preview.json @@ -1,37 +1,37 @@ { "data": [ { - "transcript1_Label": "AT3G13660" + "transcript1_Label": "label_AT3G13660" }, { - "transcript1_Label": "AT3G10460" + "transcript1_Label": "label_AT3G10460" }, { - "transcript1_Label": "AT3G51470" + "transcript1_Label": "label_AT3G51470" }, { - "transcript1_Label": "AT5G35334" + "transcript1_Label": "label_AT5G35334" }, { - "transcript1_Label": "AT3G10490" + "transcript1_Label": "label_AT3G10490" }, { - "transcript1_Label": "AT3G22640" + "transcript1_Label": "label_AT3G22640" }, { - "transcript1_Label": "AT1G57800" + "transcript1_Label": "label_AT1G57800" }, { - "transcript1_Label": "AT1G49500" + "transcript1_Label": "label_AT1G49500" }, { - "transcript1_Label": "AT1G33615" + "transcript1_Label": "label_AT1G33615" }, { - "transcript1_Label": "AT5G41905" + "transcript1_Label": "label_AT5G41905" } ], "header": [ "transcript1_Label" ] -} \ No newline at end of file +} diff --git a/tests/results/sparql_query.json b/tests/results/sparql_query.json index d815b914..0bfe4a08 100644 --- a/tests/results/sparql_query.json +++ b/tests/results/sparql_query.json @@ -37,5 +37,5 @@ "uri": "urn:sparql:askomics_test:1_jdoe:gene.gff3_###GFF_TIMESTAMP###" } }, - "query": "PREFIX : \nPREFIX askomics: \nPREFIX dc: \nPREFIX faldo: \nPREFIX owl: \nPREFIX prov: \nPREFIX rdf: \nPREFIX rdfs: \nPREFIX xsd: \n\nSELECT DISTINCT ?transcript1_Label\nWHERE {\n ?transcript1_uri rdf:type .\n ?transcript1_uri rdfs:label ?transcript1_Label .\n\n\n\n}\n" + "query": "PREFIX : \nPREFIX askomics: \nPREFIX dc: \nPREFIX dcat: \nPREFIX faldo: \nPREFIX owl: \nPREFIX prov: \nPREFIX rdf: \nPREFIX rdfs: \nPREFIX skos: \nPREFIX xsd: \n\nSELECT DISTINCT ?transcript1_Label\nWHERE {\n ?transcript1_uri rdf:type .\n ?transcript1_uri rdfs:label ?transcript1_Label .\n\n\n\n}\n" } diff --git a/tests/results/startpoints.json b/tests/results/startpoints.json index 58475efd..ba87cada 100644 --- a/tests/results/startpoints.json +++ b/tests/results/startpoints.json @@ -8,10 +8,10 @@ [{ "endpoints": [{ "name": "local", - "url": "http://localhost:8891/sparql" + "url": "http://localhost:8891/sparql-auth" }, { "name": "local", - "url": "http://localhost:8891/sparql" + "url": "http://localhost:8891/sparql-auth" }], "entity": "http://askomics.org/test/data/transcript", @@ -37,10 +37,10 @@ { "endpoints": [{ "name": "local", - "url": "http://localhost:8891/sparql" + "url": "http://localhost:8891/sparql-auth" }, { "name": "local", - "url": "http://localhost:8891/sparql" + "url": "http://localhost:8891/sparql-auth" }], "entity": "http://askomics.org/test/data/gene", @@ -70,7 +70,7 @@ { "endpoints": [{ "name": "local", - "url": "http://localhost:8891/sparql" + "url": "http://localhost:8891/sparql-auth" }], "entity": "http://askomics.org/test/data/DifferentialExpression", @@ -89,7 +89,7 @@ { "endpoints": [{ "name": "local", - "url": "http://localhost:8891/sparql" + "url": "http://localhost:8891/sparql-auth" }], "entity": "http://askomics.org/test/data/QTL", diff --git a/tests/test_api.py b/tests/test_api.py index 7e00b700..81a8bb23 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -42,7 +42,10 @@ def test_start(self, client): "namespaceInternal": client.get_config('triplestore', 'namespace_internal'), "proxyPath": "/", "user": {}, - "logged": False + "logged": False, + "ontologies": [], + "singleTenant": False, + "autocompleteMaxResults": 20 } response = client.client.get('/api/start') assert response.status_code == 200 diff --git a/tests/test_api_admin.py b/tests/test_api_admin.py index efaf3030..30b6cbba 100644 --- a/tests/test_api_admin.py +++ b/tests/test_api_admin.py @@ -68,9 +68,10 @@ def test_get_files(self, client): 'date': info["transcripts"]["upload"]["file_date"], 'id': 1, 'name': 'transcripts.tsv', - 'size': 2102, + 'size': 2264, 'type': 'csv/tsv', - 'user': 'jsmith' + 'user': 'jsmith', + 'status': 'available' }, { 'date': info["de"]["upload"]["file_date"], @@ -78,7 +79,8 @@ def test_get_files(self, client): 'name': 'de.tsv', 'size': 819, 'type': 'csv/tsv', - 'user': 'jsmith' + 'user': 'jsmith', + 'status': 'available' }, { 'date': info["qtl"]["upload"]["file_date"], @@ -86,15 +88,17 @@ def test_get_files(self, client): 'name': 'qtl.tsv', 'size': 99, 'type': 'csv/tsv', - 'user': 'jsmith' + 'user': 'jsmith', + 'status': 'available' }, { 'date': info["gene"]["upload"]["file_date"], 'id': 4, 'name': 'gene.gff3', - 'size': 2267, + 'size': 2555, 'type': 'gff/gff3', - 'user': 'jsmith' + 'user': 'jsmith', + 'status': 'available' }, { 'date': info["bed"]["upload"]["file_date"], @@ -102,7 +106,8 @@ def test_get_files(self, client): 'name': 'gene.bed', 'size': 689, 'type': 'bed', - 'user': 'jsmith' + 'user': 'jsmith', + 'status': 'available' }] } @@ -134,7 +139,8 @@ def test_get_datasets(self, client): 'traceback': None, 'percent': 100.0, 'exec_time': info["transcripts"]["end"] - info["transcripts"]["start"], - 'user': 'jsmith' + 'user': 'jsmith', + 'ontology': False }, { 'end': info["de"]["end"], 'error_message': '', @@ -147,7 +153,8 @@ def test_get_datasets(self, client): 'traceback': None, 'percent': 100.0, 'exec_time': info["de"]["end"] - info["de"]["start"], - 'user': 'jsmith' + 'user': 'jsmith', + 'ontology': False }, { 'end': info["qtl"]["end"], 'error_message': '', @@ -160,7 +167,8 @@ def test_get_datasets(self, client): 'traceback': None, 'percent': 100.0, 'exec_time': info["qtl"]["end"] - info["qtl"]["start"], - 'user': 'jsmith' + 'user': 'jsmith', + 'ontology': False }, { 'end': info["gff"]["end"], 'error_message': '', @@ -173,7 +181,8 @@ def test_get_datasets(self, client): 'traceback': None, 'percent': 100.0, 'exec_time': info["gff"]["end"] - info["gff"]["start"], - 'user': 'jsmith' + 'user': 'jsmith', + 'ontology': False }, { 'end': info["bed"]["end"], 'error_message': '', @@ -186,7 +195,8 @@ def test_get_datasets(self, client): 'traceback': None, 'percent': 100.0, 'exec_time': info["bed"]["end"] - info["bed"]["start"], - 'user': 'jsmith' + 'user': 'jsmith', + 'ontology': False }], 'error': False, 'errorMessage': '' @@ -437,15 +447,17 @@ def test_delete_files(self, client): 'name': 'qtl.tsv', 'size': 99, 'type': 'csv/tsv', - 'user': 'jsmith' + 'user': 'jsmith', + 'status': 'available' }, { 'date': info["gene"]["upload"]["file_date"], 'id': 4, 'name': 'gene.gff3', - 'size': 2267, + 'size': 2555, 'type': 'gff/gff3', - 'user': 'jsmith' + 'user': 'jsmith', + 'status': 'available' }, { 'date': info["bed"]["upload"]["file_date"], @@ -453,7 +465,8 @@ def test_delete_files(self, client): 'name': 'gene.bed', 'size': 689, 'type': 'bed', - 'user': 'jsmith' + 'user': 'jsmith', + 'status': 'available' }] } @@ -483,3 +496,205 @@ def test_delete_datasets(self, client): assert response.json["datasets"][0]["status"] == "queued" assert response.json["datasets"][1]["status"] == "queued" assert response.json["datasets"][2]["status"] == "queued" + + def test_view_custom_prefixes(self, client): + """test /api/admin/getprefixes route""" + client.create_two_users() + client.log_user("jsmith") + + response = client.client.get('/api/admin/getprefixes') + assert response.status_code == 401 + + client.log_user("jdoe") + + expected_empty = { + "error": False, + "errorMessage": "", + "prefixes": [] + } + + response = client.client.get('/api/admin/getprefixes') + assert response.status_code == 200 + assert response.json == expected_empty + + client.create_prefix() + + response = client.client.get('/api/admin/getprefixes') + + expected = { + "error": False, + "errorMessage": "", + "prefixes": [{ + "id": 1, + "namespace": "http://purl.obolibrary.org/obo/", + "prefix": "OBO" + }] + } + + assert response.status_code == 200 + assert response.json == expected + + def test_add_custom_prefix(self, client): + """test /api/admin/addprefix route""" + client.create_two_users() + client.log_user("jsmith") + + data = {"prefix": "OBO", "namespace": "http://purl.obolibrary.org/obo/"} + + response = client.client.post('/api/admin/addprefix', json=data) + assert response.status_code == 401 + + client.log_user("jdoe") + + response = client.client.post('/api/admin/addprefix', json=data) + + expected = { + "error": False, + "errorMessage": "", + "prefixes": [{ + "id": 1, + "namespace": "http://purl.obolibrary.org/obo/", + "prefix": "OBO" + }] + } + + assert response.status_code == 200 + assert response.json == expected + + def test_delete_custom_prefix(self, client): + """test /api/admin/delete_prefixes route""" + client.create_two_users() + client.log_user("jsmith") + + data = {"prefixesIdToDelete": [1]} + + response = client.client.post('/api/admin/delete_prefixes', json=data) + assert response.status_code == 401 + + client.log_user("jdoe") + client.create_prefix() + + response = client.client.post('/api/admin/delete_prefixes', json=data) + + expected = { + "error": False, + "errorMessage": "", + "prefixes": [] + } + + assert response.status_code == 200 + assert response.json == expected + + def test_view_ontologies(self, client): + """test /api/admin/getontologies route""" + client.create_two_users() + client.log_user("jsmith") + + response = client.client.get('/api/admin/getontologies') + assert response.status_code == 401 + + client.log_user("jdoe") + + expected_empty = { + "error": False, + "errorMessage": "", + "ontologies": [] + } + + response = client.client.get('/api/admin/getontologies') + assert response.status_code == 200 + assert response.json == expected_empty + + graph, endpoint = client.create_ontology() + + response = client.client.get('/api/admin/getontologies') + + expected = { + "error": False, + "errorMessage": "", + "ontologies": [{ + "id": 1, + "name": "AgrO ontology", + "uri": "http://purl.obolibrary.org/obo/agro.owl", + "short_name": "AGRO", + "type": "local", + "dataset_id": 1, + "dataset_name": "agro_min.ttl", + "graph": graph, + "endpoint": endpoint, + "remote_graph": None, + "label_uri": "rdfs:label" + }] + } + + assert response.status_code == 200 + assert response.json == expected + + def test_add_ontology(self, client): + """test /api/admin/addontology route""" + client.create_two_users() + client.log_user("jsmith") + + data = {"shortName": "AGRO", "uri": "http://purl.obolibrary.org/obo/agro.owl", "name": "AgrO ontology", "type": "local", "datasetId": 1, "labelUri": "rdfs:label"} + + response = client.client.post('/api/admin/addontology', json=data) + assert response.status_code == 401 + + client.log_user("jdoe") + graph_data = client.upload_and_integrate_ontology() + graph = graph_data["graph"] + endpoint = graph_data["endpoint"] + + response = client.client.post('/api/admin/addontology', json=data) + + # Dataset is not public + assert response.status_code == 400 + assert response.json['errorMessage'] == "Invalid dataset id" + + client.publicize_dataset(1, True) + response = client.client.post('/api/admin/addontology', json=data) + + expected = { + "error": False, + "errorMessage": "", + "ontologies": [{ + "id": 1, + "name": "AgrO ontology", + "uri": "http://purl.obolibrary.org/obo/agro.owl", + "short_name": "AGRO", + "type": "local", + "dataset_id": 1, + "dataset_name": "agro_min.ttl", + "label_uri": "rdfs:label", + "graph": graph, + "endpoint": endpoint, + "remote_graph": None + }] + } + + assert response.status_code == 200 + assert response.json == expected + + def test_delete_ontologies(self, client): + """test /api/admin/delete_ontologies route""" + client.create_two_users() + client.log_user("jsmith") + + data = {"ontologiesIdToDelete": [1]} + + response = client.client.post('/api/admin/delete_ontologies', json=data) + assert response.status_code == 401 + + client.log_user("jdoe") + client.create_ontology() + + response = client.client.post('/api/admin/delete_ontologies', json=data) + + expected = { + "error": False, + "errorMessage": "", + "ontologies": [] + } + + assert response.status_code == 200 + assert response.json == expected diff --git a/tests/test_api_data.py b/tests/test_api_data.py index 9693f11c..f7569042 100644 --- a/tests/test_api_data.py +++ b/tests/test_api_data.py @@ -12,15 +12,12 @@ def test_get_uri(self, client): client.log_user("jdoe") client.upload_and_integrate() - with open("tests/results/data.json", "r") as file: + with open("tests/results/data_full.json", "r") as file: file_content = file.read() expected = json.loads(file_content) response = client.client.get('/api/data/AT3G10490') - # Remove this dict since the node value seems to change (dependant on load order maybe?) - response.json['data'] = [val for val in response.json['data'] if not val['predicat'] == "http://biohackathon.org/resource/faldo/location"] - assert response.status_code == 200 assert self.equal_objects(response.json, expected) @@ -63,18 +60,15 @@ def test_public_access(self, client): client.integrate_file({ "id": 1, - "columns_type": ["start_entity", "category", "text", "reference", "start", "end", "category", "strand", "text", "text", "date"] + "columns_type": ["start_entity", "label", "category", "text", "reference", "start", "end", "category", "strand", "text", "text", "date"] }, public=True) - with open("tests/results/data.json", "r") as file: + with open("tests/results/data_public.json", "r") as file: file_content = file.read() expected = json.loads(file_content) client.logout() response = client.client.get('/api/data/AT3G10490') - # Remove this dict since the node value seems to change (dependant on load order maybe?) - response.json['data'] = [val for val in response.json['data'] if not val['predicat'] == "http://biohackathon.org/resource/faldo/location"] - assert response.status_code == 200 assert self.equal_objects(response.json, expected) diff --git a/tests/test_api_datasets.py b/tests/test_api_datasets.py index 3e35faed..ba5dba74 100644 --- a/tests/test_api_datasets.py +++ b/tests/test_api_datasets.py @@ -24,7 +24,8 @@ def test_get_datasets(self, client): 'status': 'success', 'traceback': None, 'percent': 100.0, - 'exec_time': info["transcripts"]["end"] - info["transcripts"]["start"] + 'exec_time': info["transcripts"]["end"] - info["transcripts"]["start"], + 'ontology': False }, { 'end': info["de"]["end"], 'error_message': '', @@ -36,7 +37,8 @@ def test_get_datasets(self, client): 'status': 'success', 'traceback': None, 'percent': 100.0, - 'exec_time': info["de"]["end"] - info["de"]["start"] + 'exec_time': info["de"]["end"] - info["de"]["start"], + 'ontology': False }, { 'end': info["qtl"]["end"], 'error_message': '', @@ -48,7 +50,8 @@ def test_get_datasets(self, client): 'status': 'success', 'traceback': None, 'percent': 100.0, - 'exec_time': info["qtl"]["end"] - info["qtl"]["start"] + 'exec_time': info["qtl"]["end"] - info["qtl"]["start"], + 'ontology': False }, { 'end': info["gff"]["end"], 'error_message': '', @@ -60,7 +63,8 @@ def test_get_datasets(self, client): 'status': 'success', 'traceback': None, 'percent': 100.0, - 'exec_time': info["gff"]["end"] - info["gff"]["start"] + 'exec_time': info["gff"]["end"] - info["gff"]["start"], + 'ontology': False }, { 'end': info["bed"]["end"], 'error_message': '', @@ -72,7 +76,8 @@ def test_get_datasets(self, client): 'status': 'success', 'traceback': None, 'percent': 100.0, - 'exec_time': info["bed"]["end"] - info["bed"]["start"] + 'exec_time': info["bed"]["end"] - info["bed"]["start"], + 'ontology': False }], 'error': False, 'errorMessage': '' @@ -118,7 +123,8 @@ def test_toggle_public(self, client): 'status': 'success', 'traceback': None, 'percent': 100.0, - 'exec_time': info["transcripts"]["end"] - info["transcripts"]["start"] + 'exec_time': info["transcripts"]["end"] - info["transcripts"]["start"], + 'ontology': False }, { 'end': info["de"]["end"], 'error_message': '', @@ -130,7 +136,8 @@ def test_toggle_public(self, client): 'status': 'success', 'traceback': None, 'percent': 100.0, - 'exec_time': info["de"]["end"] - info["de"]["start"] + 'exec_time': info["de"]["end"] - info["de"]["start"], + 'ontology': False }, { 'end': info["qtl"]["end"], 'error_message': '', @@ -142,7 +149,8 @@ def test_toggle_public(self, client): 'status': 'success', 'traceback': None, 'percent': 100.0, - 'exec_time': info["qtl"]["end"] - info["qtl"]["start"] + 'exec_time': info["qtl"]["end"] - info["qtl"]["start"], + 'ontology': False }, { 'end': info["gff"]["end"], 'error_message': '', @@ -154,7 +162,8 @@ def test_toggle_public(self, client): 'status': 'success', 'traceback': None, 'percent': 100.0, - 'exec_time': info["gff"]["end"] - info["gff"]["start"] + 'exec_time': info["gff"]["end"] - info["gff"]["start"], + 'ontology': False }, { 'end': info["bed"]["end"], 'error_message': '', @@ -166,7 +175,8 @@ def test_toggle_public(self, client): 'status': 'success', 'traceback': None, 'percent': 100.0, - 'exec_time': info["bed"]["end"] - info["bed"]["start"] + 'exec_time': info["bed"]["end"] - info["bed"]["start"], + 'ontology': False }], 'error': False, 'errorMessage': '' diff --git a/tests/test_api_file.py b/tests/test_api_file.py index e27468d8..a3a0f708 100644 --- a/tests/test_api_file.py +++ b/tests/test_api_file.py @@ -25,32 +25,37 @@ def test_get_files(self, client): 'date': info["transcripts"]["upload"]["file_date"], 'id': 1, 'name': 'transcripts.tsv', - 'size': 2102, - 'type': 'csv/tsv' + 'size': 2264, + 'type': 'csv/tsv', + 'status': 'available' }, { 'date': info["de"]["upload"]["file_date"], 'id': 2, 'name': 'de.tsv', 'size': 819, - 'type': 'csv/tsv' + 'type': 'csv/tsv', + 'status': 'available' }, { 'date': info["qtl"]["upload"]["file_date"], 'id': 3, 'name': 'qtl.tsv', 'size': 99, - 'type': 'csv/tsv' + 'type': 'csv/tsv', + 'status': 'available' }, { 'date': info["gene"]["upload"]["file_date"], 'id': 4, 'name': 'gene.gff3', - 'size': 2267, - 'type': 'gff/gff3' + 'size': 2555, + 'type': 'gff/gff3', + 'status': 'available' }, { 'date': info["bed"]["upload"]["file_date"], 'id': 5, 'name': 'gene.bed', 'size': 689, - 'type': 'bed' + 'type': 'bed', + 'status': 'available' }] } @@ -73,8 +78,9 @@ def test_get_files(self, client): 'date': info["transcripts"]["upload"]["file_date"], 'id': 1, 'name': 'transcripts.tsv', - 'size': 2102, - 'type': 'csv/tsv' + 'size': 2264, + 'type': 'csv/tsv', + 'status': 'available' }] } @@ -84,7 +90,30 @@ def test_get_files(self, client): 'diskSpace': client.get_size_occupied_by_user(), 'error': False, 'errorMessage': '', - 'files': [] + 'files': [], + } + + def test_get_files_upload(self, client): + """test the /api/files route after an url upload""" + client.create_two_users() + client.log_user("jdoe") + date = client.upload_file_url("https://raw.githubusercontent.com/askomics/demo-data/master/Example/gene.tsv") + + response = client.client.get('/api/files') + + assert response.status_code == 200 + assert response.json == { + 'diskSpace': client.get_size_occupied_by_user(), + 'error': False, + 'errorMessage': '', + 'files': [{ + 'date': date, + 'id': 1, + 'name': 'gene.tsv', + 'size': 369, + 'type': 'csv/tsv', + 'status': 'available' + }] } def test_edit_file(self, client): @@ -105,32 +134,37 @@ def test_edit_file(self, client): 'date': info["transcripts"]["upload"]["file_date"], 'id': 1, 'name': 'new name.tsv', - 'size': 2102, - 'type': 'csv/tsv' + 'size': 2264, + 'type': 'csv/tsv', + 'status': 'available' }, { 'date': info["de"]["upload"]["file_date"], 'id': 2, 'name': 'de.tsv', 'size': 819, - 'type': 'csv/tsv' + 'type': 'csv/tsv', + 'status': 'available' }, { 'date': info["qtl"]["upload"]["file_date"], 'id': 3, 'name': 'qtl.tsv', 'size': 99, - 'type': 'csv/tsv' + 'type': 'csv/tsv', + 'status': 'available' }, { 'date': info["gene"]["upload"]["file_date"], 'id': 4, 'name': 'gene.gff3', - 'size': 2267, - 'type': 'gff/gff3' + 'size': 2555, + 'type': 'gff/gff3', + 'status': 'available' }, { 'date': info["bed"]["upload"]["file_date"], 'id': 5, 'name': 'gene.bed', 'size': 689, - 'type': 'bed' + 'type': 'bed', + 'status': 'available' }] } @@ -323,7 +357,6 @@ def test_upload_url(self, client): response = client.client.get("/api/files") assert response.status_code == 200 - assert len(response.json["files"]) == 1 def test_get_preview(self, client): """Test /api/files/preview route""" @@ -427,25 +460,29 @@ def test_delete_files(self, client): 'id': 2, 'name': 'de.tsv', 'size': 819, - 'type': 'csv/tsv' + 'type': 'csv/tsv', + 'status': 'available' }, { 'date': info["qtl"]["upload"]["file_date"], 'id': 3, 'name': 'qtl.tsv', 'size': 99, - 'type': 'csv/tsv' + 'type': 'csv/tsv', + 'status': 'available' }, { 'date': info["gene"]["upload"]["file_date"], 'id': 4, 'name': 'gene.gff3', - 'size': 2267, - 'type': 'gff/gff3' + 'size': 2555, + 'type': 'gff/gff3', + 'status': 'available' }, { 'date': info["bed"]["upload"]["file_date"], 'id': 5, 'name': 'gene.bed', 'size': 689, - 'type': 'bed' + 'type': 'bed', + 'status': 'available' }] } @@ -459,19 +496,22 @@ def test_delete_files(self, client): 'id': 3, 'name': 'qtl.tsv', 'size': 99, - 'type': 'csv/tsv' + 'type': 'csv/tsv', + 'status': 'available' }, { 'date': info["gene"]["upload"]["file_date"], 'id': 4, 'name': 'gene.gff3', - 'size': 2267, - 'type': 'gff/gff3' + 'size': 2555, + 'type': 'gff/gff3', + 'status': 'available' }, { 'date': info["bed"]["upload"]["file_date"], 'id': 5, 'name': 'gene.bed', 'size': 689, - 'type': 'bed' + 'type': 'bed', + 'status': 'available' }] } @@ -560,5 +600,4 @@ def test_serve_file(self, client): response = client.client.get('/api/files/ttl/1/jdoe/{}'.format(filename)) assert response.status_code == 200 - # print(response.data.decode("utf-8")) assert response.data.decode("utf-8") == content diff --git a/tests/test_api_ontology.py b/tests/test_api_ontology.py new file mode 100644 index 00000000..c22a1821 --- /dev/null +++ b/tests/test_api_ontology.py @@ -0,0 +1,73 @@ +from . import AskomicsTestCase + + +class TestApiOntology(AskomicsTestCase): + """Test AskOmics API /api/ontology/""" + + def test_local_autocompletion_protected(self, client): + """ Test autocompletion on missing ontology""" + query = "blabla" + client.set_config("askomics", "protect_public", "true") + response = client.client.get('/api/ontology/AGRO/autocomplete?q={}'.format(query)) + + assert response.status_code == 401 + assert len(response.json["results"]) == 0 + + def test_local_autocompletion_missing_ontology(self, client): + """ Test autocompletion on missing ontology""" + query = "blabla" + response = client.client.get('/api/ontology/AGRO/autocomplete?q={}'.format(query)) + + assert response.status_code == 404 + assert len(response.json["results"]) == 0 + + def test_local_autocompletion(self, client): + """test /api/ontology/AGRO/autocomplete route""" + client.create_two_users() + client.log_user("jdoe") + + client.create_ontology() + + query = "blabla" + response = client.client.get('/api/ontology/AGRO/autocomplete?q={}'.format(query)) + + assert response.status_code == 200 + assert len(response.json["results"]) == 0 + assert response.json["results"] == [] + + query = "" + response = client.client.get('/api/ontology/AGRO/autocomplete?q={}'.format(query)) + + expected = [ + "desuckering", + "irrigation water source role", + "irrigation water quantity", + "reduced tillage process", + "laser land levelling process", + "chemical pest control process", + "no-till", + "puddling process", + "mulch-till", + "ridge-till", + "strip-till", + "aerial application" + ] + + assert response.status_code == 200 + assert len(response.json["results"]) == 12 + + # SPARQL order is not reliable, so we make sure to return everything + # If it fails, skip this + assert self.equal_objects(response.json["results"], expected) + + query = "irrigation" + response = client.client.get('/api/ontology/AGRO/autocomplete?q={}'.format(query)) + + expected = [ + "irrigation water source role", + "irrigation water quantity" + ] + + assert response.status_code == 200 + assert len(response.json["results"]) == 2 + assert self.equal_objects(response.json["results"], expected) diff --git a/tests/test_api_query.py b/tests/test_api_query.py index 9a1cdc54..68b9b486 100644 --- a/tests/test_api_query.py +++ b/tests/test_api_query.py @@ -153,7 +153,7 @@ def test_get_preview(self, client): client.log_user("jdoe") response = client.client.post('/api/query/preview', json=data) - expected = {'error': False, 'errorMessage': '', 'headerPreview': ['transcript1_Label'], 'resultsPreview': [{'transcript1_Label': 'AT1G57800'}, {'transcript1_Label': 'AT5G35334'}, {'transcript1_Label': 'AT3G10460'}, {'transcript1_Label': 'AT1G49500'}, {'transcript1_Label': 'AT3G10490'}, {'transcript1_Label': 'AT3G51470'}, {'transcript1_Label': 'AT5G41905'}, {'transcript1_Label': 'AT1G33615'}, {'transcript1_Label': 'AT3G22640'}, {'transcript1_Label': 'AT3G13660'}, {'transcript1_Label': 'AT1G01010.1'}]} + expected = {'error': False, 'errorMessage': '', 'headerPreview': ['transcript1_Label'], 'resultsPreview': [{'transcript1_Label': 'label_AT1G57800'}, {'transcript1_Label': 'label_AT5G35334'}, {'transcript1_Label': 'label_AT3G10460'}, {'transcript1_Label': 'label_AT1G49500'}, {'transcript1_Label': 'label_AT3G10490'}, {'transcript1_Label': 'label_AT3G51470'}, {'transcript1_Label': 'label_AT5G41905'}, {'transcript1_Label': 'label_AT1G33615'}, {'transcript1_Label': 'label_AT3G22640'}, {'transcript1_Label': 'label_AT3G13660'}, {'transcript1_Label': 'AT1G01010.1'}, {'transcript1_Label': 'AT1G01010.2'}, {'transcript1_Label': 'AT1G01010.3'}]} # print(response.json) @@ -171,7 +171,7 @@ def test_get_preview(self, client): "graphState": json_query, } response = client.client.post('/api/query/preview', json=data) - expected = {'error': False, 'errorMessage': '', 'headerPreview': ['transcript1_Label'], 'resultsPreview': [{'transcript1_Label': 'AT3G10490'}]} + expected = {'error': False, 'errorMessage': '', 'headerPreview': ['transcript1_Label'], 'resultsPreview': [{'transcript1_Label': 'label_AT3G10490'}]} assert response.status_code == 200 assert self.equal_objects(response.json, expected) @@ -197,7 +197,7 @@ def test_get_preview(self, client): "graphState": json_query, } response = client.client.post('/api/query/preview', json=data) - expected = {'error': False, 'errorMessage': '', 'headerPreview': ['transcript1_Label'], 'resultsPreview': [{'transcript1_Label': 'AT3G10490'}]} + expected = {'error': False, 'errorMessage': '', 'headerPreview': ['transcript1_Label'], 'resultsPreview': [{'transcript1_Label': 'label_AT3G10490'}]} assert response.status_code == 200 assert self.equal_objects(response.json, expected)