From 7223be10646d3cd7c9137f37cdfdacf9a431f500 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 29 Oct 2021 13:12:22 +0000 Subject: [PATCH 01/22] ci: Add config file for `semantic-pull-requests` #242 --- .github/semantic.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/semantic.yml diff --git a/.github/semantic.yml b/.github/semantic.yml new file mode 100644 index 00000000..152e0e9d --- /dev/null +++ b/.github/semantic.yml @@ -0,0 +1,4 @@ +# Only check commits so we don't need to squash and merge PRs preventing loss of commit history +commitsOnly: true +# One or more commits need to follow the Angular commit spec, though ideally we should be using this as much as possible for the changelog +anyCommit: true From 4358f686dbacf9d6e19be913dd8fcd9e66693be9 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 29 Oct 2021 13:15:33 +0000 Subject: [PATCH 02/22] ci: Add file to create releases and do automatic versioning #242 --- .github/workflows/release-build.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/release-build.yml diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml new file mode 100644 index 00000000..2ce19cd8 --- /dev/null +++ b/.github/workflows/release-build.yml @@ -0,0 +1,21 @@ +name: Release Build +on: + push: + branches: + - master + +jobs: + build: + name: Release Build + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Python Semantic Release + uses: relekang/python-semantic-release@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} From ceef3bebeb0573b646f44322347e3afede7c617e Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 29 Oct 2021 13:31:04 +0000 Subject: [PATCH 03/22] build: Add config for `semantic_release` #242 - Used so the tool can make a release via our CI --- pyproject.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 9a954592..0c8889b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,15 @@ homepage = "https://github.com/ral-facilities/datagateway-api" repository = "https://github.com/ral-facilities/datagateway-api" authors = ["Matthew Richards "] +[tool.semantic_release] +version_toml = [ + "pyproject.toml:tool.poetry.version" +] +branch = "master" +upload_to_pypi = false +upload_to_release = true +build_command = "pip install poetry==1.1.9 && poetry build" + [tool.poetry.dependencies] python = "^3.6" Flask-RESTful = "^0.3.7" From 1afbd71b169f068b58c14332513ccaa27569e4e8 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 29 Oct 2021 13:34:00 +0000 Subject: [PATCH 04/22] build: Add dependency to help with versioning releases #242 --- poetry.lock | 492 ++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 492 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index c55070d0..a5a0a34c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -90,6 +90,19 @@ typed-ast = ">=1.4.0" [package.extras] d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] +[[package]] +name = "bleach" +version = "4.1.0" +description = "An easy safelist-based HTML-sanitizing tool." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +packaging = "*" +six = ">=1.9.0" +webencodings = "*" + [[package]] name = "cachetools" version = "4.2.2" @@ -106,6 +119,17 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "cffi" +version = "1.15.0" +description = "Foreign Function Interface for Python calling C code." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +pycparser = "*" + [[package]] name = "chardet" version = "4.0.0" @@ -122,6 +146,17 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "click-log" +version = "0.3.2" +description = "Logging integration for Click" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +click = "*" + [[package]] name = "colorama" version = "0.4.4" @@ -144,6 +179,44 @@ toml = {version = "*", optional = true, markers = "extra == \"toml\""} [package.extras] toml = ["toml"] +[[package]] +name = "cryptography" +version = "35.0.0" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] +docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] +pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] +sdist = ["setuptools_rust (>=0.11.4)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] + +[[package]] +name = "docutils" +version = "0.18" +description = "Docutils -- Python Documentation Utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "dotty-dict" +version = "1.3.0" +description = "Dictionary wrapper for quick access to deeply nested keys." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +setuptools_scm = "*" + [[package]] name = "dparse" version = "0.5.1" @@ -450,6 +523,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "invoke" +version = "1.6.0" +description = "Pythonic task execution" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "itsdangerous" version = "1.1.0" @@ -458,6 +539,18 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "jeepney" +version = "0.7.1" +description = "Low-level, pure Python DBus protocol wrapper." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio", "async-timeout"] +trio = ["trio", "async-generator"] + [[package]] name = "jinja2" version = "2.11.3" @@ -472,6 +565,24 @@ MarkupSafe = ">=0.23" [package.extras] i18n = ["Babel (>=0.8)"] +[[package]] +name = "keyring" +version = "23.2.1" +description = "Store and access your passwords safely." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +importlib-metadata = ">=3.6" +jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} +pywin32-ctypes = {version = "<0.1.0 || >0.1.0,<0.1.1 || >0.1.1", markers = "sys_platform == \"win32\""} +SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy"] + [[package]] name = "markupsafe" version = "1.1.1" @@ -542,6 +653,17 @@ six = "*" coverage = ["pytest-cov"] testing = ["mock", "pytest", "pytest-rerunfailures"] +[[package]] +name = "pkginfo" +version = "1.7.1" +description = "Query metadatdata from sdists / bdists / installed packages." +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +testing = ["nose", "coverage"] + [[package]] name = "pluggy" version = "0.13.1" @@ -588,6 +710,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pycparser" +version = "2.20" +description = "C parser in Python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "pyflakes" version = "2.3.1" @@ -596,6 +726,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pygments" +version = "2.10.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "dev" +optional = false +python-versions = ">=3.5" + [[package]] name = "pymysql" version = "1.0.2" @@ -677,6 +815,22 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" [package.dependencies] six = ">=1.5" +[[package]] +name = "python-gitlab" +version = "2.10.1" +description = "Interact with GitLab API" +category = "dev" +optional = false +python-versions = ">=3.6.0" + +[package.dependencies] +requests = ">=2.25.0" +requests-toolbelt = ">=0.9.1" + +[package.extras] +autocompletion = ["argcomplete (>=1.10.0,<2)"] +yaml = ["PyYaml (>=5.2)"] + [[package]] name = "python-icat" version = "0.19.0" @@ -685,6 +839,32 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "python-semantic-release" +version = "7.19.2" +description = "Automatic Semantic Versioning for Python projects" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +click = ">=7,<9" +click-log = ">=0.3,<1" +dotty-dict = ">=1.3.0,<2" +gitpython = ">=3.0.8,<4" +invoke = ">=1.4.1,<2" +python-gitlab = ">=1.10,<3" +requests = ">=2.25,<3" +semver = ">=2.10,<3" +tomlkit = "0.7.0" +twine = ">=3,<4" + +[package.extras] +dev = ["tox", "isort", "black"] +docs = ["Sphinx (==1.3.6)"] +mypy = ["mypy", "types-requests"] +test = ["coverage (>=5,<6)", "pytest (>=5,<6)", "pytest-xdist (>=1,<2)", "pytest-mock (>=2,<3)", "responses (==0.13.3)", "mock (==1.3.0)"] + [[package]] name = "pytz" version = "2021.1" @@ -693,6 +873,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "pywin32-ctypes" +version = "0.2.0" +description = "" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "pyyaml" version = "5.4" @@ -701,6 +889,22 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +[[package]] +name = "readme-renderer" +version = "30.0" +description = "readme_renderer is a library for rendering \"readme\" descriptions for Warehouse" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +bleach = ">=2.1.0" +docutils = ">=0.13.1" +Pygments = ">=2.5.1" + +[package.extras] +md = ["cmarkgfm (>=0.5.0,<0.7.0)"] + [[package]] name = "regex" version = "2021.4.4" @@ -727,6 +931,28 @@ urllib3 = ">=1.21.1,<1.27" security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +[[package]] +name = "requests-toolbelt" +version = "0.9.1" +description = "A utility belt for advanced users of python-requests" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "rfc3986" +version = "1.5.0" +description = "Validating URI References per RFC 3986" +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +idna2008 = ["idna"] + [[package]] name = "safety" version = "1.10.3" @@ -741,6 +967,41 @@ dparse = ">=0.5.1" packaging = "*" requests = "*" +[[package]] +name = "secretstorage" +version = "3.3.1" +description = "Python bindings to FreeDesktop.org Secret Service API" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cryptography = ">=2.0" +jeepney = ">=0.6" + +[[package]] +name = "semver" +version = "2.13.0" +description = "Python helper for Semantic Versioning (http://semver.org/)" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "setuptools-scm" +version = "6.3.2" +description = "the blessed package to manage your versions by scm tags" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +packaging = ">=20.0" +tomli = ">=1.0.0" + +[package.extras] +toml = ["setuptools (>=42)", "tomli (>=1.0.0)"] + [[package]] name = "six" version = "1.15.0" @@ -825,6 +1086,57 @@ category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "tomli" +version = "1.2.2" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "tomlkit" +version = "0.7.0" +description = "Style preserving TOML library" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "tqdm" +version = "4.62.3" +description = "Fast, Extensible Progress Meter" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +notebook = ["ipywidgets (>=6)"] +telegram = ["requests"] + +[[package]] +name = "twine" +version = "3.4.2" +description = "Collection of utilities for publishing packages on PyPI" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = ">=0.4.3" +importlib-metadata = ">=3.6" +keyring = ">=15.1" +pkginfo = ">=1.4.2" +readme-renderer = ">=21.0" +requests = ">=2.20" +requests-toolbelt = ">=0.8.0,<0.9.0 || >0.9.0" +rfc3986 = ">=1.4.0" +tqdm = ">=4.14" + [[package]] name = "typed-ast" version = "1.4.3" @@ -854,6 +1166,14 @@ secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "cer socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] brotli = ["brotlipy (>=0.6.0)"] +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "werkzeug" version = "1.0.1" @@ -881,7 +1201,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = "^3.6" -content-hash = "50007daac3ccc714a1b88bf352ca296d7aa7d8c2a4bb84996f3a4f3dc083dec1" +content-hash = "e9ed2e014a4c32b12e243928ccb6079dc36eff25a8adf282595500d9f7ff080a" [metadata.files] aniso8601 = [ @@ -912,6 +1232,10 @@ black = [ {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, ] +bleach = [ + {file = "bleach-4.1.0-py2.py3-none-any.whl", hash = "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994"}, + {file = "bleach-4.1.0.tar.gz", hash = "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da"}, +] cachetools = [ {file = "cachetools-4.2.2-py3-none-any.whl", hash = "sha256:2cc0b89715337ab6dbba85b5b50effe2b0c74e035d83ee8ed637cf52f12ae001"}, {file = "cachetools-4.2.2.tar.gz", hash = "sha256:61b5ed1e22a0924aed1d23b478f37e8d52549ff8a961de2909c69bf950020cff"}, @@ -920,6 +1244,58 @@ certifi = [ {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, ] +cffi = [ + {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"}, + {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"}, + {file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"}, + {file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"}, + {file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"}, + {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"}, + {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"}, + {file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"}, + {file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"}, + {file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"}, + {file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"}, + {file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"}, + {file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"}, + {file = "cffi-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc"}, + {file = "cffi-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"}, + {file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"}, + {file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"}, + {file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"}, + {file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"}, + {file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"}, + {file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"}, + {file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"}, + {file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"}, + {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"}, + {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"}, +] chardet = [ {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, @@ -928,6 +1304,10 @@ click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, ] +click-log = [ + {file = "click-log-0.3.2.tar.gz", hash = "sha256:16fd1ca3fc6b16c98cea63acf1ab474ea8e676849dc669d86afafb0ed7003124"}, + {file = "click_log-0.3.2-py2.py3-none-any.whl", hash = "sha256:eee14dc37cdf3072158570f00406572f9e03e414accdccfccd4c538df9ae322c"}, +] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, @@ -986,6 +1366,35 @@ coverage = [ {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"}, {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, ] +cryptography = [ + {file = "cryptography-35.0.0-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:d57e0cdc1b44b6cdf8af1d01807db06886f10177469312fbde8f44ccbb284bc9"}, + {file = "cryptography-35.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:ced40344e811d6abba00295ced98c01aecf0c2de39481792d87af4fa58b7b4d6"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:54b2605e5475944e2213258e0ab8696f4f357a31371e538ef21e8d61c843c28d"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7b7ceeff114c31f285528ba8b390d3e9cfa2da17b56f11d366769a807f17cbaa"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d69645f535f4b2c722cfb07a8eab916265545b3475fdb34e0be2f4ee8b0b15e"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2d0e0acc20ede0f06ef7aa58546eee96d2592c00f450c9acb89c5879b61992"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:07bb7fbfb5de0980590ddfc7f13081520def06dc9ed214000ad4372fb4e3c7f6"}, + {file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7eba2cebca600a7806b893cb1d541a6e910afa87e97acf2021a22b32da1df52d"}, + {file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:18d90f4711bf63e2fb21e8c8e51ed8189438e6b35a6d996201ebd98a26abbbe6"}, + {file = "cryptography-35.0.0-cp36-abi3-win32.whl", hash = "sha256:c10c797ac89c746e488d2ee92bd4abd593615694ee17b2500578b63cad6b93a8"}, + {file = "cryptography-35.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:7075b304cd567694dc692ffc9747f3e9cb393cc4aa4fb7b9f3abd6f5c4e43588"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a688ebcd08250eab5bb5bca318cc05a8c66de5e4171a65ca51db6bd753ff8953"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99915d6ab265c22873f1b4d6ea5ef462ef797b4140be4c9d8b179915e0985c6"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:928185a6d1ccdb816e883f56ebe92e975a262d31cc536429041921f8cb5a62fd"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ebeddd119f526bcf323a89f853afb12e225902a24d29b55fe18dd6fcb2838a76"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:22a38e96118a4ce3b97509443feace1d1011d0571fae81fc3ad35f25ba3ea999"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb80e8a1f91e4b7ef8b33041591e6d89b2b8e122d787e87eeb2b08da71bb16ad"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:abb5a361d2585bb95012a19ed9b2c8f412c5d723a9836418fab7aaa0243e67d2"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:1ed82abf16df40a60942a8c211251ae72858b25b7421ce2497c2eb7a1cee817c"}, + {file = "cryptography-35.0.0.tar.gz", hash = "sha256:9933f28f70d0517686bd7de36166dda42094eac49415459d9bdf5e7df3e0086d"}, +] +docutils = [ + {file = "docutils-0.18-py2.py3-none-any.whl", hash = "sha256:a31688b2ea858517fa54293e5d5df06fbb875fb1f7e4c64529271b77781ca8fc"}, + {file = "docutils-0.18.tar.gz", hash = "sha256:c1d5dab2b11d16397406a282e53953fe495a46d69ae329f55aa98a5c4e3c5fbb"}, +] +dotty-dict = [ + {file = "dotty_dict-1.3.0.tar.gz", hash = "sha256:eb0035a3629ecd84397a68f1f42f1e94abd1c34577a19cd3eacad331ee7cbaf0"}, +] dparse = [ {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, @@ -1122,14 +1531,27 @@ iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +invoke = [ + {file = "invoke-1.6.0-py2-none-any.whl", hash = "sha256:e6c9917a1e3e73e7ea91fdf82d5f151ccfe85bf30cc65cdb892444c02dbb5f74"}, + {file = "invoke-1.6.0-py3-none-any.whl", hash = "sha256:769e90caeb1bd07d484821732f931f1ad8916a38e3f3e618644687fc09cb6317"}, + {file = "invoke-1.6.0.tar.gz", hash = "sha256:374d1e2ecf78981da94bfaf95366216aaec27c2d6a7b7d5818d92da55aa258d3"}, +] itsdangerous = [ {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, ] +jeepney = [ + {file = "jeepney-0.7.1-py3-none-any.whl", hash = "sha256:1b5a0ea5c0e7b166b2f5895b91a08c14de8915afda4407fb5022a195224958ac"}, + {file = "jeepney-0.7.1.tar.gz", hash = "sha256:fa9e232dfa0c498bd0b8a3a73b8d8a31978304dcef0515adc859d4e096f96f4f"}, +] jinja2 = [ {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"}, ] +keyring = [ + {file = "keyring-23.2.1-py3-none-any.whl", hash = "sha256:bd2145a237ed70c8ce72978b497619ddfcae640b6dcf494402d5143e37755c6e"}, + {file = "keyring-23.2.1.tar.gz", hash = "sha256:6334aee6073db2fb1f30892697b1730105b5e9a77ce7e61fca6b435225493efe"}, +] 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"}, @@ -1208,6 +1630,10 @@ 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"}, ] +pkginfo = [ + {file = "pkginfo-1.7.1-py2.py3-none-any.whl", hash = "sha256:37ecd857b47e5f55949c41ed061eb51a0bee97a87c969219d144c0e023982779"}, + {file = "pkginfo-1.7.1.tar.gz", hash = "sha256:e7432f81d08adec7297633191bbf0bd47faf13cd8724c3a13250e51d542635bd"}, +] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, @@ -1228,10 +1654,18 @@ pycodestyle = [ {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, ] +pycparser = [ + {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"}, + {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, +] pyflakes = [ {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] +pygments = [ + {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"}, + {file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"}, +] pymysql = [ {file = "PyMySQL-1.0.2-py3-none-any.whl", hash = "sha256:41fc3a0c5013d5f039639442321185532e3e2c8924687abe6537de157d403641"}, {file = "PyMySQL-1.0.2.tar.gz", hash = "sha256:816927a350f38d56072aeca5dfb10221fe1dc653745853d30a216637f5d7ad36"}, @@ -1255,13 +1689,25 @@ 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-gitlab = [ + {file = "python-gitlab-2.10.1.tar.gz", hash = "sha256:7afa7d7c062fa62c173190452265a30feefb844428efc58ea5244f3b9fc0d40f"}, + {file = "python_gitlab-2.10.1-py3-none-any.whl", hash = "sha256:581a219759515513ea9399e936ed7137437cfb681f52d2641626685c492c999d"}, +] python-icat = [ {file = "python-icat-0.19.0.tar.gz", hash = "sha256:16d64bc8a9fa3d0e3861d38c8fb094a2eeee0b5343d33135b49e9743d9dcfc63"}, ] +python-semantic-release = [ + {file = "python-semantic-release-7.19.2.tar.gz", hash = "sha256:8ca0e5f72d31e7b0603b95caad6fb2d5315483ac1fadd86648771966d9ec6f2c"}, + {file = "python_semantic_release-7.19.2-py3-none-any.whl", hash = "sha256:b2c8bb16a643fee0831be4d06138bc1440ebd4f252c3397d41abde179ea56852"}, +] pytz = [ {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, ] +pywin32-ctypes = [ + {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, + {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, +] pyyaml = [ {file = "PyYAML-5.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:f7a21e3d99aa3095ef0553e7ceba36fb693998fbb1226f1392ce33681047465f"}, {file = "PyYAML-5.4-cp27-cp27m-win32.whl", hash = "sha256:52bf0930903818e600ae6c2901f748bc4869c0c406056f679ab9614e5d21a166"}, @@ -1285,6 +1731,10 @@ pyyaml = [ {file = "PyYAML-5.4-cp39-cp39-win_amd64.whl", hash = "sha256:8bf38641b4713d77da19e91f8b5296b832e4db87338d6aeffe422d42f1ca896d"}, {file = "PyYAML-5.4.tar.gz", hash = "sha256:3c49e39ac034fd64fd576d63bb4db53cda89b362768a67f07749d55f128ac18a"}, ] +readme-renderer = [ + {file = "readme_renderer-30.0-py2.py3-none-any.whl", hash = "sha256:3286806450d9961d6e3b5f8a59f77e61503799aca5155c8d8d40359b4e1e1adc"}, + {file = "readme_renderer-30.0.tar.gz", hash = "sha256:8299700d7a910c304072a7601eafada6712a5b011a20139417e1b1e9f04645d8"}, +] regex = [ {file = "regex-2021.4.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000"}, {file = "regex-2021.4.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711"}, @@ -1332,10 +1782,30 @@ requests = [ {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, ] +requests-toolbelt = [ + {file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"}, + {file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"}, +] +rfc3986 = [ + {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, + {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, +] safety = [ {file = "safety-1.10.3-py2.py3-none-any.whl", hash = "sha256:5f802ad5df5614f9622d8d71fedec2757099705c2356f862847c58c6dfe13e84"}, {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"}, ] +secretstorage = [ + {file = "SecretStorage-3.3.1-py3-none-any.whl", hash = "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f"}, + {file = "SecretStorage-3.3.1.tar.gz", hash = "sha256:fd666c51a6bf200643495a04abb261f83229dcb6fd8472ec393df7ffc8b6f195"}, +] +semver = [ + {file = "semver-2.13.0-py2.py3-none-any.whl", hash = "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4"}, + {file = "semver-2.13.0.tar.gz", hash = "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"}, +] +setuptools-scm = [ + {file = "setuptools_scm-6.3.2-py3-none-any.whl", hash = "sha256:4c64444b1d49c4063ae60bfe1680f611c8b13833d556fd1d6050c0023162a119"}, + {file = "setuptools_scm-6.3.2.tar.gz", hash = "sha256:a49aa8081eeb3514eb9728fa5040f2eaa962d6c6f4ec9c32f6c1fba88f88a0f2"}, +] six = [ {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, @@ -1397,6 +1867,22 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +tomli = [ + {file = "tomli-1.2.2-py3-none-any.whl", hash = "sha256:f04066f68f5554911363063a30b108d2b5a5b1a010aa8b6132af78489fe3aade"}, + {file = "tomli-1.2.2.tar.gz", hash = "sha256:c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee"}, +] +tomlkit = [ + {file = "tomlkit-0.7.0-py2.py3-none-any.whl", hash = "sha256:6babbd33b17d5c9691896b0e68159215a9387ebfa938aa3ac42f4a4beeb2b831"}, + {file = "tomlkit-0.7.0.tar.gz", hash = "sha256:ac57f29693fab3e309ea789252fcce3061e19110085aa31af5446ca749325618"}, +] +tqdm = [ + {file = "tqdm-4.62.3-py2.py3-none-any.whl", hash = "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c"}, + {file = "tqdm-4.62.3.tar.gz", hash = "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d"}, +] +twine = [ + {file = "twine-3.4.2-py3-none-any.whl", hash = "sha256:087328e9bb405e7ce18527a2dca4042a84c7918658f951110b38bc135acab218"}, + {file = "twine-3.4.2.tar.gz", hash = "sha256:4caec0f1ed78dc4c9b83ad537e453d03ce485725f2aea57f1bb3fdde78dae936"}, +] typed-ast = [ {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, @@ -1438,6 +1924,10 @@ urllib3 = [ {file = "urllib3-1.26.4-py2.py3-none-any.whl", hash = "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df"}, {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"}, ] +webencodings = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] werkzeug = [ {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, {file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"}, diff --git a/pyproject.toml b/pyproject.toml index 0c8889b6..a93fbe9d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,6 +54,7 @@ pytest = "^6.1.2" coverage = {extras = ["toml"], version = "^5.3"} pytest-cov = "^2.10.1" pytest-icdiff = "^0.5" +python-semantic-release = "^7.19.2" [tool.poetry.scripts] From ccf6d2974216f8979a03e3e223f7c9e84ced05cb Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 1 Nov 2021 10:43:21 +0000 Subject: [PATCH 05/22] docs: Add documentation to explain versioning on this repo #242 BREAKING CHANGE: As the API will be approaching production use soon, this seems like a good opportunity to bump the version to 1.0.0. This also serves as a good test that the introduction of automatic versioning actually works --- .github/PULL_REQUEST_TEMPLATE.md | 1 + README.md | 54 ++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1e365c2d..2328f902 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,6 +10,7 @@ Add a set up instructions describing how the reviewer should test the code - [ ] Check GitHub Actions build - [ ] If `icatdb Generator Script Consistency Test` CI job fails, is this because of a deliberate change made to the script to change generated data (which isn't actually a problem) or is here an underlying issue with the changes made? - [ ] Review changes to test coverage +- [ ] Does this change mean a new patch, minor or major version should be made? If so, does one of the commit messages feature `fix:`, `feat:` or `BREAKING CHANGE:` so a release is automatically made via GitHub Actions upon merge? - [ ] {more steps here} ## Agile Board Tracking diff --git a/README.md b/README.md index ad6e19fa..5732e930 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ sqlalchemy to communicate directly with ICAT's database. - [Automated Testing & Other Development Helpers (Nox)](#automated-testing-&-other-development-helpers-(nox)) - [Automated Checks during Git Commit (Pre Commit)](#automated-checks-during-git-commit-(pre-commit)) - [Summary](#summary) +- [API Versioning](#api-versioning) - [Running DataGateway API](#running-datagateway-api) - [API Startup](#api-startup) - [Authentication](#authentication) @@ -281,6 +282,59 @@ pre-commit install +# API Versioning +This repository uses semantic versioning as the standard for version number +incrementing, with the version stored in `pyproject.toml`. There is a GitHub Actions +workflow (`release-build.yml`) which runs when master is updated (i.e. when a pull +request is merged). This uses +[python-semantic-release](https://github.com/relekang/python-semantic-release) to +determine whether a release needs to be made, and if so, whether a major, minor or patch +version bump should be made. This decision is made based on commit message content. + +In a PR, at least one commit must follow the +[Angular commit message format](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commit-message-format) +and use one of the +[conventional commit types](https://github.com/commitizen/conventional-commit-types/blob/master/index.json). +Note, there are no scopes (part of the Angular message format) configured for this repo +so there's no need to make use of this feature. Compliance to this format and use of +standard types will be checked by +[semantic-pull-requests](https://github.com/zeke/semantic-pull-requests) which is a +GitHub app installed into this repo and runs alongside existing CI jobs for pull +requests. For example, the following commit messages follow the conventional commit +standard: + +``` +# Commit to edit a CI job +ci: Edit linting job #issue-number + +# Commit for a bug fix +fix: Fix bug found with count endpoints #issue-number + +# Commit for a new feature +feat: Add endpoints for search API #issue-number + +# Commit which introduces a breaking change for users +BREAKING CHANGE: Change format of `config.json`, the previous version is no longer supported #issue-number + +# You can also use `BREAKING CHANGE:` in the additional information if the commit also adds a new feature, like so: +feat: My new feature #issue-number + +BREAKING CHANGE: This feature means X functionality has been removed +``` + +For each pull request, only one commit message in this format is required to satisfy the +semantic pull request checker. Requiring only one commit message in this format should +hopefully not impose this commit style on developer. However, it is encouraged to use it +where possible, as the types are also used to form `CHANGELOG.md`. + +New releases are only made when a `fix:` (patch), `feat:` (minor) or `BREAKING CHANGE:` +(major) commit type is found between the previous release and the most recent commit on +master. When the version is bumped, a GitHub tag and release is made which contains +the source code and the built versions of the API (sdist and wheel). + + + + # Running DataGateway API Depending on the backend you want to use (either `db` or `python_icat`, more details about backends [here](#backends)) the connection URL for the backend needs to be set. From d53d85ad46a115ba871c6da8273a242e790c810c Mon Sep 17 00:00:00 2001 From: Matthew Richards <32678030+MRichards99@users.noreply.github.com> Date: Tue, 2 Nov 2021 12:16:19 +0000 Subject: [PATCH 06/22] docs: follow Angular commit message capitalisation #242 Co-authored-by: Viktor Bozhinov <45173816+VKTB@users.noreply.github.com> --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5732e930..8e92e41c 100644 --- a/README.md +++ b/README.md @@ -305,21 +305,21 @@ standard: ``` # Commit to edit a CI job -ci: Edit linting job #issue-number +ci: edit linting job #issue-number # Commit for a bug fix -fix: Fix bug found with count endpoints #issue-number +fix: fix bug found with count endpoints #issue-number # Commit for a new feature -feat: Add endpoints for search API #issue-number +feat: add endpoints for search API #issue-number # Commit which introduces a breaking change for users -BREAKING CHANGE: Change format of `config.json`, the previous version is no longer supported #issue-number +BREAKING CHANGE: change format of `config.json`, the previous version is no longer supported #issue-number # You can also use `BREAKING CHANGE:` in the additional information if the commit also adds a new feature, like so: -feat: My new feature #issue-number +feat: my new feature #issue-number -BREAKING CHANGE: This feature means X functionality has been removed +BREAKING CHANGE: this feature means X functionality has been removed ``` For each pull request, only one commit message in this format is required to satisfy the From fd763154c31ad183a989f807bfbf2926a2de4ae4 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Wed, 3 Nov 2021 12:28:37 +0000 Subject: [PATCH 07/22] ci: use admin personal access token to automate releases --- .github/workflows/release-build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml index 2ce19cd8..c94f92c7 100644 --- a/.github/workflows/release-build.yml +++ b/.github/workflows/release-build.yml @@ -14,8 +14,9 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 + token: ${{ secrets.ADMIN_PAT }} - name: Python Semantic Release uses: relekang/python-semantic-release@master with: - github_token: ${{ secrets.GITHUB_TOKEN }} + github_token: ${{ secrets.ADMIN_PAT }} From 68b996e86cd314b1250a9e9ffe4b26034c6bb7fb Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 3 Nov 2021 13:37:43 +0000 Subject: [PATCH 08/22] 1.0.0 Automatically generated by python-semantic-release --- CHANGELOG.md | 11 +++++++++++ pyproject.toml | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..db971546 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + + + +## v1.0.0 (2021-11-03) +### Breaking +* As the API will be approaching production use soon, this seems like a good opportunity to bump the version to 1.0.0. This also serves as a good test that the introduction of automatic versioning actually works ([`ccf6d29`](https://github.com/ral-facilities/datagateway-api/commit/ccf6d2974216f8979a03e3e223f7c9e84ced05cb)) + +### Documentation +* Follow Angular commit message capitalisation #242 ([`d53d85a`](https://github.com/ral-facilities/datagateway-api/commit/d53d85ad46a115ba871c6da8273a242e790c810c)) +* Add documentation to explain versioning on this repo #242 ([`ccf6d29`](https://github.com/ral-facilities/datagateway-api/commit/ccf6d2974216f8979a03e3e223f7c9e84ced05cb)) diff --git a/pyproject.toml b/pyproject.toml index 93fdf128..079f9ba3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "datagateway-api" -version = "0.1.0" +version = "1.0.0" description = "ICAT API to interface with the DataGateway" license = "Apache-2.0" readme = "README.md" From f2f5edcbc412d205eafdd9bfe4a0603386063e75 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 25 Oct 2021 11:57:57 +0000 Subject: [PATCH 09/22] refactor: #257: Add unimplemented endpoint classes - Matching DataGateway API's class structure, with relevant TODOs to add in code when endpoints are defined and implemented --- .../search_api/search_api_endpoints.py | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 datagateway_api/src/resources/search_api/search_api_endpoints.py diff --git a/datagateway_api/src/resources/search_api/search_api_endpoints.py b/datagateway_api/src/resources/search_api/search_api_endpoints.py new file mode 100644 index 00000000..e040f9d2 --- /dev/null +++ b/datagateway_api/src/resources/search_api/search_api_endpoints.py @@ -0,0 +1,94 @@ +from flask_restful import Resource + + +# TODO - Might need kwargs on get_endpoint(), get_id_endpoint(), get_count_endpoint(), +# get_files_endpoint(), get_count_files_endpoint() for client handling? +def get_endpoint(name): + """ + TODO - Add docstring + """ + + class Endpoint(Resource): + def get(self): + """ + TODO - Need to return similar to + return ( + backend.get_with_filters( + get_session_id_from_auth_header(), + entity_type, + get_filters_from_query_string(), + **kwargs, + ), + 200, + ) + """ + pass + + # TODO - Add `get.__doc__` + + Endpoint.__name__ = name + return Endpoint + + +def get_id_endpoint(name): + """ + TODO - Add docstring + """ + + class EndpointWithID(Resource): + def get(self, pid): + # TODO - Add return + pass + + # TODO - Add `get.__doc__` + + EndpointWithID.__name__ = name + return EndpointWithID + + +def get_count_endpoint(name): + """ + TODO - Add docstring + """ + + class CountEndpoint(Resource): + def get(self): + # TODO - Add return + pass + + # TODO - Add `get.__doc__` + + CountEndpoint.__name__ = name + return CountEndpoint + + +def get_files_endpoint(name): + """ + TODO - Add docstring + """ + + class FilesEndpoint(Resource): + def get(self, pid): + # TODO - Add return + pass + + # TODO - Add `get.__doc__` + + FilesEndpoint.__name__ = name + return FilesEndpoint + + +def get_count_files_endpoint(name): + """ + TODO - Add docstring + """ + + class CountFilesEndpoint(Resource): + def get(self, pid): + # TODO - Add return + pass + + # TODO - Add `get.__doc__` + + CountFilesEndpoint.__name__ = name + return CountFilesEndpoint From b57b92d19155f554c533b526922aa483a8ef9f09 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 25 Oct 2021 12:02:29 +0000 Subject: [PATCH 10/22] #256: Change directory structure to suit search API - Since this repository will support DataGateway API and the Search API, there needs to be some changes in directory structure to split the different files up. Essentially this means adding `datagateway_api/` and `search_api/` in `common/` and `src/resources/` - The imports will be fixed in a future commit --- .../common/{database => datagateway_api}/__init__.py | 0 datagateway_api/common/{ => datagateway_api}/backend.py | 0 datagateway_api/common/{ => datagateway_api}/backends.py | 0 .../common/{icat => datagateway_api/database}/__init__.py | 0 .../common/{ => datagateway_api}/database/backend.py | 0 .../common/{ => datagateway_api}/database/filters.py | 0 .../common/{ => datagateway_api}/database/helpers.py | 0 .../common/{ => datagateway_api}/database/models.py | 0 .../common/{ => datagateway_api}/filter_order_handler.py | 0 .../entities => common/datagateway_api/icat}/__init__.py | 0 datagateway_api/common/{ => datagateway_api}/icat/backend.py | 0 datagateway_api/common/{ => datagateway_api}/icat/filters.py | 0 datagateway_api/common/{ => datagateway_api}/icat/helpers.py | 0 .../common/{ => datagateway_api}/icat/icat_client_pool.py | 0 datagateway_api/common/{ => datagateway_api}/icat/lru_cache.py | 0 datagateway_api/common/{ => datagateway_api}/icat/query.py | 0 .../common/{ => datagateway_api}/query_filter_factory.py | 0 .../resources/non_entities => common/search_api}/__init__.py | 0 datagateway_api/common/search_api/helpers.py | 3 +++ .../{table_endpoints => datagateway_api/entities}/__init__.py | 0 .../{ => datagateway_api}/entities/entity_endpoint.py | 0 .../{ => datagateway_api}/entities/entity_endpoint_dict.py | 0 .../src/resources/{ => datagateway_api}/entities/entity_map.py | 0 .../src/resources/datagateway_api/non_entities/__init__.py | 0 .../{ => datagateway_api}/non_entities/ping_endpoint.py | 0 .../{ => datagateway_api}/non_entities/sessions_endpoints.py | 0 .../src/resources/datagateway_api/table_endpoints/__init__.py | 0 .../{ => datagateway_api}/table_endpoints/table_endpoints.py | 0 datagateway_api/src/resources/search_api/__init__.py | 0 29 files changed, 3 insertions(+) rename datagateway_api/common/{database => datagateway_api}/__init__.py (100%) rename datagateway_api/common/{ => datagateway_api}/backend.py (100%) rename datagateway_api/common/{ => datagateway_api}/backends.py (100%) rename datagateway_api/common/{icat => datagateway_api/database}/__init__.py (100%) rename datagateway_api/common/{ => datagateway_api}/database/backend.py (100%) rename datagateway_api/common/{ => datagateway_api}/database/filters.py (100%) rename datagateway_api/common/{ => datagateway_api}/database/helpers.py (100%) rename datagateway_api/common/{ => datagateway_api}/database/models.py (100%) rename datagateway_api/common/{ => datagateway_api}/filter_order_handler.py (100%) rename datagateway_api/{src/resources/entities => common/datagateway_api/icat}/__init__.py (100%) rename datagateway_api/common/{ => datagateway_api}/icat/backend.py (100%) rename datagateway_api/common/{ => datagateway_api}/icat/filters.py (100%) rename datagateway_api/common/{ => datagateway_api}/icat/helpers.py (100%) rename datagateway_api/common/{ => datagateway_api}/icat/icat_client_pool.py (100%) rename datagateway_api/common/{ => datagateway_api}/icat/lru_cache.py (100%) rename datagateway_api/common/{ => datagateway_api}/icat/query.py (100%) rename datagateway_api/common/{ => datagateway_api}/query_filter_factory.py (100%) rename datagateway_api/{src/resources/non_entities => common/search_api}/__init__.py (100%) create mode 100644 datagateway_api/common/search_api/helpers.py rename datagateway_api/src/resources/{table_endpoints => datagateway_api/entities}/__init__.py (100%) rename datagateway_api/src/resources/{ => datagateway_api}/entities/entity_endpoint.py (100%) rename datagateway_api/src/resources/{ => datagateway_api}/entities/entity_endpoint_dict.py (100%) rename datagateway_api/src/resources/{ => datagateway_api}/entities/entity_map.py (100%) create mode 100644 datagateway_api/src/resources/datagateway_api/non_entities/__init__.py rename datagateway_api/src/resources/{ => datagateway_api}/non_entities/ping_endpoint.py (100%) rename datagateway_api/src/resources/{ => datagateway_api}/non_entities/sessions_endpoints.py (100%) create mode 100644 datagateway_api/src/resources/datagateway_api/table_endpoints/__init__.py rename datagateway_api/src/resources/{ => datagateway_api}/table_endpoints/table_endpoints.py (100%) create mode 100644 datagateway_api/src/resources/search_api/__init__.py diff --git a/datagateway_api/common/database/__init__.py b/datagateway_api/common/datagateway_api/__init__.py similarity index 100% rename from datagateway_api/common/database/__init__.py rename to datagateway_api/common/datagateway_api/__init__.py diff --git a/datagateway_api/common/backend.py b/datagateway_api/common/datagateway_api/backend.py similarity index 100% rename from datagateway_api/common/backend.py rename to datagateway_api/common/datagateway_api/backend.py diff --git a/datagateway_api/common/backends.py b/datagateway_api/common/datagateway_api/backends.py similarity index 100% rename from datagateway_api/common/backends.py rename to datagateway_api/common/datagateway_api/backends.py diff --git a/datagateway_api/common/icat/__init__.py b/datagateway_api/common/datagateway_api/database/__init__.py similarity index 100% rename from datagateway_api/common/icat/__init__.py rename to datagateway_api/common/datagateway_api/database/__init__.py diff --git a/datagateway_api/common/database/backend.py b/datagateway_api/common/datagateway_api/database/backend.py similarity index 100% rename from datagateway_api/common/database/backend.py rename to datagateway_api/common/datagateway_api/database/backend.py diff --git a/datagateway_api/common/database/filters.py b/datagateway_api/common/datagateway_api/database/filters.py similarity index 100% rename from datagateway_api/common/database/filters.py rename to datagateway_api/common/datagateway_api/database/filters.py diff --git a/datagateway_api/common/database/helpers.py b/datagateway_api/common/datagateway_api/database/helpers.py similarity index 100% rename from datagateway_api/common/database/helpers.py rename to datagateway_api/common/datagateway_api/database/helpers.py diff --git a/datagateway_api/common/database/models.py b/datagateway_api/common/datagateway_api/database/models.py similarity index 100% rename from datagateway_api/common/database/models.py rename to datagateway_api/common/datagateway_api/database/models.py diff --git a/datagateway_api/common/filter_order_handler.py b/datagateway_api/common/datagateway_api/filter_order_handler.py similarity index 100% rename from datagateway_api/common/filter_order_handler.py rename to datagateway_api/common/datagateway_api/filter_order_handler.py diff --git a/datagateway_api/src/resources/entities/__init__.py b/datagateway_api/common/datagateway_api/icat/__init__.py similarity index 100% rename from datagateway_api/src/resources/entities/__init__.py rename to datagateway_api/common/datagateway_api/icat/__init__.py diff --git a/datagateway_api/common/icat/backend.py b/datagateway_api/common/datagateway_api/icat/backend.py similarity index 100% rename from datagateway_api/common/icat/backend.py rename to datagateway_api/common/datagateway_api/icat/backend.py diff --git a/datagateway_api/common/icat/filters.py b/datagateway_api/common/datagateway_api/icat/filters.py similarity index 100% rename from datagateway_api/common/icat/filters.py rename to datagateway_api/common/datagateway_api/icat/filters.py diff --git a/datagateway_api/common/icat/helpers.py b/datagateway_api/common/datagateway_api/icat/helpers.py similarity index 100% rename from datagateway_api/common/icat/helpers.py rename to datagateway_api/common/datagateway_api/icat/helpers.py diff --git a/datagateway_api/common/icat/icat_client_pool.py b/datagateway_api/common/datagateway_api/icat/icat_client_pool.py similarity index 100% rename from datagateway_api/common/icat/icat_client_pool.py rename to datagateway_api/common/datagateway_api/icat/icat_client_pool.py diff --git a/datagateway_api/common/icat/lru_cache.py b/datagateway_api/common/datagateway_api/icat/lru_cache.py similarity index 100% rename from datagateway_api/common/icat/lru_cache.py rename to datagateway_api/common/datagateway_api/icat/lru_cache.py diff --git a/datagateway_api/common/icat/query.py b/datagateway_api/common/datagateway_api/icat/query.py similarity index 100% rename from datagateway_api/common/icat/query.py rename to datagateway_api/common/datagateway_api/icat/query.py diff --git a/datagateway_api/common/query_filter_factory.py b/datagateway_api/common/datagateway_api/query_filter_factory.py similarity index 100% rename from datagateway_api/common/query_filter_factory.py rename to datagateway_api/common/datagateway_api/query_filter_factory.py diff --git a/datagateway_api/src/resources/non_entities/__init__.py b/datagateway_api/common/search_api/__init__.py similarity index 100% rename from datagateway_api/src/resources/non_entities/__init__.py rename to datagateway_api/common/search_api/__init__.py diff --git a/datagateway_api/common/search_api/helpers.py b/datagateway_api/common/search_api/helpers.py new file mode 100644 index 00000000..ca6a72a5 --- /dev/null +++ b/datagateway_api/common/search_api/helpers.py @@ -0,0 +1,3 @@ +""" +Code to store helper functions to deal with the endpoints, like for DataGateway API +""" diff --git a/datagateway_api/src/resources/table_endpoints/__init__.py b/datagateway_api/src/resources/datagateway_api/entities/__init__.py similarity index 100% rename from datagateway_api/src/resources/table_endpoints/__init__.py rename to datagateway_api/src/resources/datagateway_api/entities/__init__.py diff --git a/datagateway_api/src/resources/entities/entity_endpoint.py b/datagateway_api/src/resources/datagateway_api/entities/entity_endpoint.py similarity index 100% rename from datagateway_api/src/resources/entities/entity_endpoint.py rename to datagateway_api/src/resources/datagateway_api/entities/entity_endpoint.py diff --git a/datagateway_api/src/resources/entities/entity_endpoint_dict.py b/datagateway_api/src/resources/datagateway_api/entities/entity_endpoint_dict.py similarity index 100% rename from datagateway_api/src/resources/entities/entity_endpoint_dict.py rename to datagateway_api/src/resources/datagateway_api/entities/entity_endpoint_dict.py diff --git a/datagateway_api/src/resources/entities/entity_map.py b/datagateway_api/src/resources/datagateway_api/entities/entity_map.py similarity index 100% rename from datagateway_api/src/resources/entities/entity_map.py rename to datagateway_api/src/resources/datagateway_api/entities/entity_map.py diff --git a/datagateway_api/src/resources/datagateway_api/non_entities/__init__.py b/datagateway_api/src/resources/datagateway_api/non_entities/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/datagateway_api/src/resources/non_entities/ping_endpoint.py b/datagateway_api/src/resources/datagateway_api/non_entities/ping_endpoint.py similarity index 100% rename from datagateway_api/src/resources/non_entities/ping_endpoint.py rename to datagateway_api/src/resources/datagateway_api/non_entities/ping_endpoint.py diff --git a/datagateway_api/src/resources/non_entities/sessions_endpoints.py b/datagateway_api/src/resources/datagateway_api/non_entities/sessions_endpoints.py similarity index 100% rename from datagateway_api/src/resources/non_entities/sessions_endpoints.py rename to datagateway_api/src/resources/datagateway_api/non_entities/sessions_endpoints.py diff --git a/datagateway_api/src/resources/datagateway_api/table_endpoints/__init__.py b/datagateway_api/src/resources/datagateway_api/table_endpoints/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/datagateway_api/src/resources/table_endpoints/table_endpoints.py b/datagateway_api/src/resources/datagateway_api/table_endpoints/table_endpoints.py similarity index 100% rename from datagateway_api/src/resources/table_endpoints/table_endpoints.py rename to datagateway_api/src/resources/datagateway_api/table_endpoints/table_endpoints.py diff --git a/datagateway_api/src/resources/search_api/__init__.py b/datagateway_api/src/resources/search_api/__init__.py new file mode 100644 index 00000000..e69de29b From f5633806a50d0cbb09d1498d56a6d5286b10004b Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 26 Oct 2021 14:16:34 +0000 Subject: [PATCH 11/22] #256: Revert back to old example config format - Reverting back so the tests pass until I re-implement the config --- datagateway_api/config.json.example | 32 ++++++++++------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/datagateway_api/config.json.example b/datagateway_api/config.json.example index 97812c5b..68137ce9 100644 --- a/datagateway_api/config.json.example +++ b/datagateway_api/config.json.example @@ -1,26 +1,16 @@ { - "datagateway_api": { - "extension": "/datagateway-api", - "backend": "python_icat", - "client_cache_size": 10, - "client_pool_init_size": 3, - "client_pool_max_size": 20, - "db_url": "mysql+pymysql://icatdbuser:icatdbuserpw@localhost:3306/icatdb", - "icat_url": "https://icatisis.esc.rl.ac.uk:8181", - "icat_check_cert": false - }, - "search_api": { - "extension": "/search-api", - "icat_url": "https://icatisis.esc.rl.ac.uk:8181", - "icat_check_cert": false, - "client_pool_init_size": 3 - "client_pool_max_size": 20 - }, + "backend": "db", + "client_cache_size": 5, + "client_pool_init_size": 2, + "client_pool_max_size": 5, + "db_url": "mysql+pymysql://icatdbuser:icatdbuserpw@localhost:3306/icatdb", "flask_reloader": false, - "log_level": "DEBUG", - "log_location": "/root/seg_dev/datagateway-api/logs.log", - "debug_mode": true, - "generate_swagger": true, + "icat_url": "https://localhost:8181", + "icat_check_cert": false, + "log_level": "WARN", + "log_location": "/home/runner/work/datagateway-api/datagateway-api/logs.log", + "debug_mode": false, + "generate_swagger": false, "host": "127.0.0.1", "port": "5000", "test_user_credentials": {"username": "root", "password": "pw"}, From 8caccfdaa7161f7105875a59060e7778adecaeaf Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 26 Oct 2021 14:26:58 +0000 Subject: [PATCH 12/22] Change ignore paths for new directory structure --- .flake8 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.flake8 b/.flake8 index ddf94ee5..9d789e85 100644 --- a/.flake8 +++ b/.flake8 @@ -10,6 +10,7 @@ per-file-ignores = test/*: S101 util/icat_db_generator.py: S311 datagateway_api/wsgi.py:E402,F401 - datagateway_api/common/database/models.py: N815,A003 - datagateway_api/common/icat/filters.py: C901 + datagateway_api/common/datagateway_api/database/models.py: N815,A003 + datagateway_api/common/datagateway_api/icat/filters.py: C901 + datagateway_api/common/search_api/models.py: B950 enable-extensions=G From bca8d2294eb459ff5e79bea092dfba0017858e1b Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 26 Oct 2021 14:27:35 +0000 Subject: [PATCH 13/22] Fix imports for new directory structure - Directory structure due to implementation of search API --- .../common/datagateway_api/backends.py | 4 ++-- .../datagateway_api/database/backend.py | 6 ++--- .../datagateway_api/database/filters.py | 4 ++-- .../datagateway_api/database/helpers.py | 8 ++++--- .../datagateway_api/filter_order_handler.py | 2 +- .../common/datagateway_api/icat/backend.py | 8 +++---- .../common/datagateway_api/icat/helpers.py | 17 +++++++------- .../datagateway_api/query_filter_factory.py | 4 ++-- datagateway_api/common/helpers.py | 12 ++++++---- datagateway_api/common/search_api/filters.py | 2 +- datagateway_api/common/search_api/models.py | 2 +- .../common/search_api/session_handler.py | 3 +++ datagateway_api/src/api_start_utils.py | 22 ++++++++++++------- .../datagateway_api/entities/entity_map.py | 4 +++- .../src/swagger/initialise_spec.py | 4 +++- test/conftest.py | 4 ++-- test/db/conftest.py | 4 ++-- test/db/endpoints/test_ping_db.py | 2 +- test/db/test_database_filter_utilities.py | 6 +++-- test/db/test_entity_helper.py | 2 +- test/db/test_query_filter_factory.py | 6 +++-- test/icat/endpoints/test_ping_icat.py | 6 +++-- test/icat/filters/test_distinct_filter.py | 4 +++- test/icat/filters/test_include_filter.py | 2 +- test/icat/filters/test_limit_filter.py | 8 ++++--- test/icat/filters/test_order_filter.py | 6 +++-- test/icat/filters/test_skip_filter.py | 2 +- test/icat/filters/test_where_filter.py | 6 +++-- test/icat/test_filter_order_handler.py | 6 +++-- test/icat/test_helpers.py | 4 ++-- test/icat/test_icat_client.py | 2 +- test/icat/test_lru_cache.py | 6 +++-- test/icat/test_query.py | 8 +++---- test/icat/test_session_handling.py | 8 ++++--- test/test_backends.py | 8 +++---- test/test_endpoint_rules.py | 4 +++- test/test_get_entity_object.py | 6 ++++- test/test_get_filters_from_query.py | 2 +- test/test_openapi.py | 4 +++- test/test_query_filter.py | 4 +++- util/icat_db_generator.py | 2 +- 41 files changed, 137 insertions(+), 87 deletions(-) diff --git a/datagateway_api/common/datagateway_api/backends.py b/datagateway_api/common/datagateway_api/backends.py index 84993b5f..f04fa9ca 100644 --- a/datagateway_api/common/datagateway_api/backends.py +++ b/datagateway_api/common/datagateway_api/backends.py @@ -1,7 +1,7 @@ import sys -from datagateway_api.common.database.backend import DatabaseBackend -from datagateway_api.common.icat.backend import PythonICATBackend +from datagateway_api.common.datagateway_api.database.backend import DatabaseBackend +from datagateway_api.common.datagateway_api.icat.backend import PythonICATBackend def create_backend(backend_type): diff --git a/datagateway_api/common/datagateway_api/database/backend.py b/datagateway_api/common/datagateway_api/database/backend.py index e77b53ef..c92fc295 100644 --- a/datagateway_api/common/datagateway_api/database/backend.py +++ b/datagateway_api/common/datagateway_api/database/backend.py @@ -5,9 +5,9 @@ from sqlalchemy import inspect from sqlalchemy.exc import SQLAlchemyError -from datagateway_api.common.backend import Backend from datagateway_api.common.constants import Constants -from datagateway_api.common.database.helpers import ( +from datagateway_api.common.datagateway_api.backend import Backend +from datagateway_api.common.datagateway_api.database.helpers import ( create_rows_from_json, db, delete_row_by_id, @@ -24,7 +24,7 @@ requires_session_id, update_row_from_id, ) -from datagateway_api.common.database.models import SESSION +from datagateway_api.common.datagateway_api.database.models import SESSION from datagateway_api.common.exceptions import AuthenticationError, DatabaseError from datagateway_api.common.helpers import get_entity_object_from_name, queries_records diff --git a/datagateway_api/common/datagateway_api/database/filters.py b/datagateway_api/common/datagateway_api/database/filters.py index 69d982b6..f37f5e91 100644 --- a/datagateway_api/common/datagateway_api/database/filters.py +++ b/datagateway_api/common/datagateway_api/database/filters.py @@ -73,7 +73,7 @@ def add_query_join(self, query): filter :param query: The query to have filters applied to - :type query: :class:`datagateway_api.common.database.helpers.[QUERY]` + :type query: :class:`.common.datagateway_api.database.helpers.[QUERY]` """ if self.related_related_field: @@ -92,7 +92,7 @@ def get_entity_model_for_filter(self, query): variables of this class :param query: The query to have filters applied to - :type query: :class:`datagateway_api.common.database.helpers.[QUERY]` + :type query: :class:`.common.datagateway_api.database.helpers.[QUERY]` :return: Entity model of the field (usually the field relating to the endpoint the request is coming from) """ diff --git a/datagateway_api/common/datagateway_api/database/helpers.py b/datagateway_api/common/datagateway_api/database/helpers.py index 19cb31f9..97bad712 100644 --- a/datagateway_api/common/datagateway_api/database/helpers.py +++ b/datagateway_api/common/datagateway_api/database/helpers.py @@ -6,12 +6,12 @@ from flask_sqlalchemy import SQLAlchemy from sqlalchemy.orm import aliased -from datagateway_api.common.database.filters import ( +from datagateway_api.common.datagateway_api.database.filters import ( DatabaseDistinctFieldFilter, DatabaseIncludeFilter as IncludeFilter, DatabaseWhereFilter as WhereFilter, ) -from datagateway_api.common.database.models import ( +from datagateway_api.common.datagateway_api.database.models import ( FACILITY, FACILITYCYCLE, INSTRUMENT, @@ -19,12 +19,14 @@ INVESTIGATIONINSTRUMENT, SESSION, ) +from datagateway_api.common.datagateway_api.filter_order_handler import ( + FilterOrderHandler, +) from datagateway_api.common.exceptions import ( AuthenticationError, BadRequestError, MissingRecordError, ) -from datagateway_api.common.filter_order_handler import FilterOrderHandler from datagateway_api.common.helpers import map_distinct_attributes_to_results diff --git a/datagateway_api/common/datagateway_api/filter_order_handler.py b/datagateway_api/common/datagateway_api/filter_order_handler.py index 02f55ccc..c5d44493 100644 --- a/datagateway_api/common/datagateway_api/filter_order_handler.py +++ b/datagateway_api/common/datagateway_api/filter_order_handler.py @@ -1,6 +1,6 @@ import logging -from datagateway_api.common.icat.filters import ( +from datagateway_api.common.datagateway_api.icat.filters import ( PythonICATLimitFilter, PythonICATOrderFilter, PythonICATSkipFilter, diff --git a/datagateway_api/common/datagateway_api/icat/backend.py b/datagateway_api/common/datagateway_api/icat/backend.py index 18866f2b..56f4177e 100644 --- a/datagateway_api/common/datagateway_api/icat/backend.py +++ b/datagateway_api/common/datagateway_api/icat/backend.py @@ -2,11 +2,9 @@ from icat.exception import ICATError, ICATSessionError -from datagateway_api.common.backend import Backend from datagateway_api.common.constants import Constants -from datagateway_api.common.exceptions import AuthenticationError, PythonICATError -from datagateway_api.common.helpers import queries_records -from datagateway_api.common.icat.helpers import ( +from datagateway_api.common.datagateway_api.backend import Backend +from datagateway_api.common.datagateway_api.icat.helpers import ( create_entities, delete_entity_by_id, get_cached_client, @@ -25,6 +23,8 @@ update_entities, update_entity_by_id, ) +from datagateway_api.common.exceptions import AuthenticationError, PythonICATError +from datagateway_api.common.helpers import queries_records log = logging.getLogger() diff --git a/datagateway_api/common/datagateway_api/icat/helpers.py b/datagateway_api/common/datagateway_api/icat/helpers.py index 078da702..45edf46a 100644 --- a/datagateway_api/common/datagateway_api/icat/helpers.py +++ b/datagateway_api/common/datagateway_api/icat/helpers.py @@ -14,6 +14,15 @@ ICATValidationError, ) +from datagateway_api.common.datagateway_api.filter_order_handler import ( + FilterOrderHandler, +) +from datagateway_api.common.datagateway_api.icat.filters import ( + PythonICATLimitFilter, + PythonICATWhereFilter, +) +from datagateway_api.common.datagateway_api.icat.lru_cache import ExtendedLRUCache +from datagateway_api.common.datagateway_api.icat.query import ICATQuery from datagateway_api.common.date_handler import DateHandler from datagateway_api.common.exceptions import ( AuthenticationError, @@ -21,14 +30,6 @@ MissingRecordError, PythonICATError, ) -from datagateway_api.common.filter_order_handler import FilterOrderHandler -from datagateway_api.common.icat.filters import ( - PythonICATLimitFilter, - PythonICATWhereFilter, -) -from datagateway_api.common.icat.lru_cache import ExtendedLRUCache -from datagateway_api.common.icat.query import ICATQuery - log = logging.getLogger() diff --git a/datagateway_api/common/datagateway_api/query_filter_factory.py b/datagateway_api/common/datagateway_api/query_filter_factory.py index 078becf3..f2e58c52 100644 --- a/datagateway_api/common/datagateway_api/query_filter_factory.py +++ b/datagateway_api/common/datagateway_api/query_filter_factory.py @@ -29,7 +29,7 @@ def get_query_filter(request_filter): backend_type = config.get_config_value(APIConfigOptions.BACKEND) if backend_type == "db": - from datagateway_api.common.database.filters import ( + from datagateway_api.common.datagateway_api.database.filters import ( DatabaseDistinctFieldFilter as DistinctFieldFilter, DatabaseIncludeFilter as IncludeFilter, DatabaseLimitFilter as LimitFilter, @@ -38,7 +38,7 @@ def get_query_filter(request_filter): DatabaseWhereFilter as WhereFilter, ) elif backend_type == "python_icat": - from datagateway_api.common.icat.filters import ( + from datagateway_api.common.datagateway_api.icat.filters import ( PythonICATDistinctFieldFilter as DistinctFieldFilter, PythonICATIncludeFilter as IncludeFilter, PythonICATLimitFilter as LimitFilter, diff --git a/datagateway_api/common/helpers.py b/datagateway_api/common/helpers.py index 88d8f178..aef45023 100644 --- a/datagateway_api/common/helpers.py +++ b/datagateway_api/common/helpers.py @@ -8,7 +8,10 @@ from flask_restful import reqparse from sqlalchemy.exc import IntegrityError -from datagateway_api.common.database import models +from datagateway_api.common.datagateway_api.database import models +from datagateway_api.common.datagateway_api.query_filter_factory import ( + QueryFilterFactory, +) from datagateway_api.common.date_handler import DateHandler from datagateway_api.common.exceptions import ( ApiError, @@ -17,8 +20,9 @@ FilterError, MissingCredentialsError, ) -from datagateway_api.common.query_filter_factory import QueryFilterFactory -from datagateway_api.src.resources.entities.entity_endpoint_dict import endpoints +from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( + endpoints, +) log = logging.getLogger() @@ -115,7 +119,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. - :class:`datagateway_api.common.database.models.INVESTIGATIONINSTRUMENT`) + :class:`.datagateway_api.database.models.INVESTIGATIONINSTRUMENT`) :raises: KeyError: If an entity model cannot be found as a class in this model """ try: diff --git a/datagateway_api/common/search_api/filters.py b/datagateway_api/common/search_api/filters.py index 25a058fa..b3ca847d 100644 --- a/datagateway_api/common/search_api/filters.py +++ b/datagateway_api/common/search_api/filters.py @@ -1,4 +1,4 @@ -from datagateway_api.common.icat.filters import ( +from datagateway_api.common.datagateway_api.icat.filters import ( PythonICATIncludeFilter, PythonICATLimitFilter, PythonICATSkipFilter, diff --git a/datagateway_api/common/search_api/models.py b/datagateway_api/common/search_api/models.py index 5abfe3b0..425e2b38 100644 --- a/datagateway_api/common/search_api/models.py +++ b/datagateway_api/common/search_api/models.py @@ -9,7 +9,7 @@ class PaNOSCAttribute(ABC): @abstractclassmethod - def from_icat(cls): + def from_icat(self): pass @abstractmethod diff --git a/datagateway_api/common/search_api/session_handler.py b/datagateway_api/common/search_api/session_handler.py index d7f9c51c..5666e40a 100644 --- a/datagateway_api/common/search_api/session_handler.py +++ b/datagateway_api/common/search_api/session_handler.py @@ -9,9 +9,12 @@ def requires_session_id(method): """ TODO """ + pass + """ @wraps(method) def wrapper_requires_session(*args, **kwargs): pass return wrapper_requires_session + """ diff --git a/datagateway_api/src/api_start_utils.py b/datagateway_api/src/api_start_utils.py index 01c4d81c..4589cbeb 100644 --- a/datagateway_api/src/api_start_utils.py +++ b/datagateway_api/src/api_start_utils.py @@ -7,22 +7,28 @@ from flask_restful import Api from flask_swagger_ui import get_swaggerui_blueprint -from datagateway_api.common.backends import create_backend from datagateway_api.common.config import APIConfigOptions, config -from datagateway_api.common.database.helpers import db -from datagateway_api.common.icat.icat_client_pool import create_client_pool -from datagateway_api.src.resources.entities.entity_endpoint import ( +from datagateway_api.common.datagateway_api.backends import create_backend +from datagateway_api.common.datagateway_api.database.helpers import db +from datagateway_api.common.datagateway_api.icat.icat_client_pool import ( + create_client_pool, +) +from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint import ( get_count_endpoint, get_endpoint, get_find_one_endpoint, get_id_endpoint, ) -from datagateway_api.src.resources.entities.entity_endpoint_dict import endpoints -from datagateway_api.src.resources.non_entities.ping_endpoint import ping_endpoint -from datagateway_api.src.resources.non_entities.sessions_endpoints import ( +from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( + endpoints, +) +from datagateway_api.src.resources.datagateway_api.non_entities.ping_endpoint import ( + ping_endpoint, +) +from datagateway_api.src.resources.datagateway_api.non_entities.sessions_endpoints import ( session_endpoints, ) -from datagateway_api.src.resources.table_endpoints.table_endpoints import ( +from datagateway_api.src.resources.datagateway_api.table_endpoints.table_endpoints import ( count_instrument_facility_cycles_endpoint, count_instrument_investigation_endpoint, instrument_facility_cycles_endpoint, diff --git a/datagateway_api/src/resources/datagateway_api/entities/entity_map.py b/datagateway_api/src/resources/datagateway_api/entities/entity_map.py index 6bb74659..599e3feb 100644 --- a/datagateway_api/src/resources/datagateway_api/entities/entity_map.py +++ b/datagateway_api/src/resources/datagateway_api/entities/entity_map.py @@ -3,7 +3,9 @@ from sqlalchemy.inspection import inspect from datagateway_api.common.helpers import get_entity_object_from_name -from datagateway_api.src.resources.entities.entity_endpoint_dict import endpoints +from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( + endpoints, +) def type_conversion(python_type): diff --git a/datagateway_api/src/swagger/initialise_spec.py b/datagateway_api/src/swagger/initialise_spec.py index 79350077..e987c760 100644 --- a/datagateway_api/src/swagger/initialise_spec.py +++ b/datagateway_api/src/swagger/initialise_spec.py @@ -1,4 +1,6 @@ -from datagateway_api.src.resources.entities.entity_map import create_entity_models +from datagateway_api.src.resources.datagateway_api.entities.entity_map import ( + create_entity_models, +) def initialise_spec(spec): diff --git a/test/conftest.py b/test/conftest.py index c699ce20..b0fa5352 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -3,11 +3,11 @@ from flask import Flask import pytest -from datagateway_api.common.database.helpers import ( +from datagateway_api.common.datagateway_api.database.helpers import ( delete_row_by_id, insert_row_into_table, ) -from datagateway_api.common.database.models import SESSION +from datagateway_api.common.datagateway_api.database.models import SESSION from datagateway_api.src.api_start_utils import ( create_api_endpoints, create_app_infrastructure, diff --git a/test/db/conftest.py b/test/db/conftest.py index b7815ed8..98381fdf 100644 --- a/test/db/conftest.py +++ b/test/db/conftest.py @@ -4,11 +4,11 @@ import pytest from datagateway_api.common.constants import Constants -from datagateway_api.common.database.helpers import ( +from datagateway_api.common.datagateway_api.database.helpers import ( delete_row_by_id, insert_row_into_table, ) -from datagateway_api.common.database.models import ( +from datagateway_api.common.datagateway_api.database.models import ( FACILITYCYCLE, INSTRUMENT, INVESTIGATION, diff --git a/test/db/endpoints/test_ping_db.py b/test/db/endpoints/test_ping_db.py index 96c4588b..279d60b1 100644 --- a/test/db/endpoints/test_ping_db.py +++ b/test/db/endpoints/test_ping_db.py @@ -3,8 +3,8 @@ import pytest from sqlalchemy.exc import SQLAlchemyError -from datagateway_api.common.backends import create_backend from datagateway_api.common.constants import Constants +from datagateway_api.common.datagateway_api.backends import create_backend from datagateway_api.common.exceptions import DatabaseError diff --git a/test/db/test_database_filter_utilities.py b/test/db/test_database_filter_utilities.py index 8321bbf8..80874171 100644 --- a/test/db/test_database_filter_utilities.py +++ b/test/db/test_database_filter_utilities.py @@ -1,7 +1,9 @@ import pytest -from datagateway_api.common.database.filters import DatabaseFilterUtilities -from datagateway_api.common.database.helpers import ReadQuery +from datagateway_api.common.datagateway_api.database.filters import ( + DatabaseFilterUtilities, +) +from datagateway_api.common.datagateway_api.database.helpers import ReadQuery from datagateway_api.common.exceptions import FilterError from datagateway_api.common.helpers import get_entity_object_from_name diff --git a/test/db/test_entity_helper.py b/test/db/test_entity_helper.py index 6818b86d..a52e5542 100644 --- a/test/db/test_entity_helper.py +++ b/test/db/test_entity_helper.py @@ -1,7 +1,7 @@ import pytest from datagateway_api.common.constants import Constants -from datagateway_api.common.database.models import ( +from datagateway_api.common.datagateway_api.database.models import ( DATAFILE, DATAFILEFORMAT, DATASET, diff --git a/test/db/test_query_filter_factory.py b/test/db/test_query_filter_factory.py index 16e3394b..7f81d98e 100644 --- a/test/db/test_query_filter_factory.py +++ b/test/db/test_query_filter_factory.py @@ -1,6 +1,6 @@ import pytest -from datagateway_api.common.database.filters import ( +from datagateway_api.common.datagateway_api.database.filters import ( DatabaseDistinctFieldFilter, DatabaseIncludeFilter, DatabaseLimitFilter, @@ -8,7 +8,9 @@ DatabaseSkipFilter, DatabaseWhereFilter, ) -from datagateway_api.common.query_filter_factory import QueryFilterFactory +from datagateway_api.common.datagateway_api.query_filter_factory import ( + QueryFilterFactory, +) class TestQueryFilterFactory: diff --git a/test/icat/endpoints/test_ping_icat.py b/test/icat/endpoints/test_ping_icat.py index d18d15e1..27568193 100644 --- a/test/icat/endpoints/test_ping_icat.py +++ b/test/icat/endpoints/test_ping_icat.py @@ -3,10 +3,12 @@ from icat.exception import ICATError import pytest -from datagateway_api.common.backends import create_backend from datagateway_api.common.constants import Constants +from datagateway_api.common.datagateway_api.backends import create_backend +from datagateway_api.common.datagateway_api.icat.icat_client_pool import ( + create_client_pool, +) from datagateway_api.common.exceptions import PythonICATError -from datagateway_api.common.icat.icat_client_pool import create_client_pool class TestICATPing: diff --git a/test/icat/filters/test_distinct_filter.py b/test/icat/filters/test_distinct_filter.py index 4adf3ae8..f7eeced0 100644 --- a/test/icat/filters/test_distinct_filter.py +++ b/test/icat/filters/test_distinct_filter.py @@ -1,7 +1,9 @@ import pytest +from datagateway_api.common.datagateway_api.icat.filters import ( + PythonICATDistinctFieldFilter, +) from datagateway_api.common.exceptions import FilterError -from datagateway_api.common.icat.filters import PythonICATDistinctFieldFilter class TestICATDistinctFilter: diff --git a/test/icat/filters/test_include_filter.py b/test/icat/filters/test_include_filter.py index f50bcefe..45df7ad0 100644 --- a/test/icat/filters/test_include_filter.py +++ b/test/icat/filters/test_include_filter.py @@ -1,7 +1,7 @@ import pytest +from datagateway_api.common.datagateway_api.icat.filters import PythonICATIncludeFilter from datagateway_api.common.exceptions import FilterError -from datagateway_api.common.icat.filters import PythonICATIncludeFilter class TestICATIncludeFilter: diff --git a/test/icat/filters/test_limit_filter.py b/test/icat/filters/test_limit_filter.py index c9d02e9d..59f3c8d0 100644 --- a/test/icat/filters/test_limit_filter.py +++ b/test/icat/filters/test_limit_filter.py @@ -2,13 +2,15 @@ import pytest -from datagateway_api.common.exceptions import FilterError -from datagateway_api.common.filter_order_handler import FilterOrderHandler -from datagateway_api.common.icat.filters import ( +from datagateway_api.common.datagateway_api.filter_order_handler import ( + FilterOrderHandler, +) +from datagateway_api.common.datagateway_api.icat.filters import ( icat_set_limit, PythonICATLimitFilter, PythonICATSkipFilter, ) +from datagateway_api.common.exceptions import FilterError class TestICATLimitFilter: diff --git a/test/icat/filters/test_order_filter.py b/test/icat/filters/test_order_filter.py index 2b45e366..2f60b453 100644 --- a/test/icat/filters/test_order_filter.py +++ b/test/icat/filters/test_order_filter.py @@ -1,9 +1,11 @@ import pytest +from datagateway_api.common.datagateway_api.filter_order_handler import ( + FilterOrderHandler, +) +from datagateway_api.common.datagateway_api.icat.filters import PythonICATOrderFilter from datagateway_api.common.exceptions import FilterError -from datagateway_api.common.filter_order_handler import FilterOrderHandler -from datagateway_api.common.icat.filters import PythonICATOrderFilter class TestICATOrderFilter: diff --git a/test/icat/filters/test_skip_filter.py b/test/icat/filters/test_skip_filter.py index 995b19bd..40bb081e 100644 --- a/test/icat/filters/test_skip_filter.py +++ b/test/icat/filters/test_skip_filter.py @@ -1,8 +1,8 @@ import pytest from datagateway_api.common.config import config +from datagateway_api.common.datagateway_api.icat.filters import PythonICATSkipFilter from datagateway_api.common.exceptions import FilterError -from datagateway_api.common.icat.filters import PythonICATSkipFilter class TestICATSkipFilter: diff --git a/test/icat/filters/test_where_filter.py b/test/icat/filters/test_where_filter.py index 6fde3665..2e00342e 100644 --- a/test/icat/filters/test_where_filter.py +++ b/test/icat/filters/test_where_filter.py @@ -1,8 +1,10 @@ import pytest +from datagateway_api.common.datagateway_api.filter_order_handler import ( + FilterOrderHandler, +) +from datagateway_api.common.datagateway_api.icat.filters import PythonICATWhereFilter from datagateway_api.common.exceptions import BadRequestError, FilterError -from datagateway_api.common.filter_order_handler import FilterOrderHandler -from datagateway_api.common.icat.filters import PythonICATWhereFilter class TestICATWhereFilter: diff --git a/test/icat/test_filter_order_handler.py b/test/icat/test_filter_order_handler.py index b31fe13d..bc557877 100644 --- a/test/icat/test_filter_order_handler.py +++ b/test/icat/test_filter_order_handler.py @@ -1,7 +1,9 @@ import pytest -from datagateway_api.common.filter_order_handler import FilterOrderHandler -from datagateway_api.common.icat.filters import ( +from datagateway_api.common.datagateway_api.filter_order_handler import ( + FilterOrderHandler, +) +from datagateway_api.common.datagateway_api.icat.filters import ( PythonICATLimitFilter, PythonICATWhereFilter, ) diff --git a/test/icat/test_helpers.py b/test/icat/test_helpers.py index c1963ca3..71b8d515 100644 --- a/test/icat/test_helpers.py +++ b/test/icat/test_helpers.py @@ -3,11 +3,11 @@ from icat.exception import ICATInternalError import pytest -from datagateway_api.common.exceptions import BadRequestError, PythonICATError -from datagateway_api.common.icat.helpers import ( +from datagateway_api.common.datagateway_api.icat.helpers import ( get_icat_entity_name_as_camel_case, push_data_updates_to_icat, ) +from datagateway_api.common.exceptions import BadRequestError, PythonICATError class TestICATHelpers: diff --git a/test/icat/test_icat_client.py b/test/icat/test_icat_client.py index b68f3e19..286a3ba2 100644 --- a/test/icat/test_icat_client.py +++ b/test/icat/test_icat_client.py @@ -1,6 +1,6 @@ from icat.client import Client -from datagateway_api.common.icat.icat_client_pool import ICATClient +from datagateway_api.common.datagateway_api.icat.icat_client_pool import ICATClient class TestICATClient: diff --git a/test/icat/test_lru_cache.py b/test/icat/test_lru_cache.py index 3f27d603..4612883b 100644 --- a/test/icat/test_lru_cache.py +++ b/test/icat/test_lru_cache.py @@ -4,8 +4,10 @@ from icat.client import Client from datagateway_api.common.config import APIConfigOptions, config -from datagateway_api.common.icat.icat_client_pool import create_client_pool -from datagateway_api.common.icat.lru_cache import ExtendedLRUCache +from datagateway_api.common.datagateway_api.icat.icat_client_pool import ( + create_client_pool, +) +from datagateway_api.common.datagateway_api.icat.lru_cache import ExtendedLRUCache class TestLRUCache: diff --git a/test/icat/test_query.py b/test/icat/test_query.py index c72ae934..7a5334c8 100644 --- a/test/icat/test_query.py +++ b/test/icat/test_query.py @@ -3,13 +3,13 @@ from icat.entity import Entity import pytest -from datagateway_api.common.date_handler import DateHandler -from datagateway_api.common.exceptions import PythonICATError -from datagateway_api.common.icat.filters import ( +from datagateway_api.common.datagateway_api.icat.filters import ( PythonICATSkipFilter, PythonICATWhereFilter, ) -from datagateway_api.common.icat.query import ICATQuery +from datagateway_api.common.datagateway_api.icat.query import ICATQuery +from datagateway_api.common.date_handler import DateHandler +from datagateway_api.common.exceptions import PythonICATError def prepare_icat_data_for_assertion(data, remove_id=False, remove_visit_id=False): diff --git a/test/icat/test_session_handling.py b/test/icat/test_session_handling.py index 1392f962..9d52210e 100644 --- a/test/icat/test_session_handling.py +++ b/test/icat/test_session_handling.py @@ -5,12 +5,14 @@ from icat.client import Client import pytest -from datagateway_api.common.backends import create_backend from datagateway_api.common.config import APIConfigOptions, config +from datagateway_api.common.datagateway_api.backends import create_backend +from datagateway_api.common.datagateway_api.icat.filters import PythonICATWhereFilter +from datagateway_api.common.datagateway_api.icat.icat_client_pool import ( + create_client_pool, +) from datagateway_api.common.date_handler import DateHandler from datagateway_api.common.exceptions import AuthenticationError -from datagateway_api.common.icat.filters import PythonICATWhereFilter -from datagateway_api.common.icat.icat_client_pool import create_client_pool class TestSessionHandling: diff --git a/test/test_backends.py b/test/test_backends.py index d2d82948..6cb25511 100644 --- a/test/test_backends.py +++ b/test/test_backends.py @@ -1,9 +1,9 @@ import pytest -from datagateway_api.common.backend import Backend -from datagateway_api.common.backends import create_backend -from datagateway_api.common.database.backend import DatabaseBackend -from datagateway_api.common.icat.backend import PythonICATBackend +from datagateway_api.common.datagateway_api.backend import Backend +from datagateway_api.common.datagateway_api.backends import create_backend +from datagateway_api.common.datagateway_api.database.backend import DatabaseBackend +from datagateway_api.common.datagateway_api.icat.backend import PythonICATBackend class TestBackends: diff --git a/test/test_endpoint_rules.py b/test/test_endpoint_rules.py index cc3c5b14..e1a09efc 100644 --- a/test/test_endpoint_rules.py +++ b/test/test_endpoint_rules.py @@ -1,6 +1,8 @@ import pytest -from datagateway_api.src.resources.entities.entity_endpoint_dict import endpoints +from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( + endpoints, +) class TestEndpointRules: diff --git a/test/test_get_entity_object.py b/test/test_get_entity_object.py index 19834a2f..9d6679ed 100644 --- a/test/test_get_entity_object.py +++ b/test/test_get_entity_object.py @@ -1,6 +1,10 @@ import pytest -from datagateway_api.common.database.models import FACILITY, INVESTIGATION, JOB +from datagateway_api.common.datagateway_api.database.models import ( + FACILITY, + INVESTIGATION, + JOB, +) from datagateway_api.common.exceptions import ApiError from datagateway_api.common.helpers import get_entity_object_from_name diff --git a/test/test_get_filters_from_query.py b/test/test_get_filters_from_query.py index 80dd2608..0c3cb3a4 100644 --- a/test/test_get_filters_from_query.py +++ b/test/test_get_filters_from_query.py @@ -1,6 +1,6 @@ import pytest -from datagateway_api.common.database.filters import ( +from datagateway_api.common.datagateway_api.database.filters import ( DatabaseDistinctFieldFilter, DatabaseIncludeFilter, DatabaseLimitFilter, diff --git a/test/test_openapi.py b/test/test_openapi.py index bbf2cdf3..1282552f 100644 --- a/test/test_openapi.py +++ b/test/test_openapi.py @@ -2,7 +2,9 @@ import pytest -from datagateway_api.src.resources.entities.entity_map import type_conversion +from datagateway_api.src.resources.datagateway_api.entities.entity_map import ( + type_conversion, +) class TestOpenAPI: diff --git a/test/test_query_filter.py b/test/test_query_filter.py index 7eddfcd1..3304fa40 100644 --- a/test/test_query_filter.py +++ b/test/test_query_filter.py @@ -2,9 +2,11 @@ import pytest +from datagateway_api.common.datagateway_api.query_filter_factory import ( + QueryFilterFactory, +) from datagateway_api.common.exceptions import ApiError from datagateway_api.common.filters import QueryFilter -from datagateway_api.common.query_filter_factory import QueryFilterFactory class TestQueryFilter: diff --git a/util/icat_db_generator.py b/util/icat_db_generator.py index 64972dfe..2f361bc3 100644 --- a/util/icat_db_generator.py +++ b/util/icat_db_generator.py @@ -9,7 +9,7 @@ from sqlalchemy.pool import QueuePool from datagateway_api.common.config import APIConfigOptions, config -from datagateway_api.common.database import models +from datagateway_api.common.datagateway_api.database import models parser = argparse.ArgumentParser() parser.add_argument( From 12a45ba4ce63d5dd3ee468b9fa52e84d15a7b219 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 25 Oct 2021 12:28:58 +0000 Subject: [PATCH 14/22] Use Python 3.9 on CI jobs --- .github/workflows/ci-build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 7a1db0b7..72efcc9c 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -97,7 +97,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v2 with: - python-version: '3.6' + python-version: '3.9' architecture: x64 - name: Checkout DataGateway API uses: actions/checkout@v2 @@ -117,7 +117,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v2 with: - python-version: '3.6' + python-version: '3.9' architecture: x64 - name: Checkout DataGateway API uses: actions/checkout@v2 @@ -137,7 +137,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v2 with: - python-version: '3.6' + python-version: '3.9' architecture: x64 - name: Checkout DataGateway API uses: actions/checkout@v2 @@ -167,7 +167,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v2 with: - python-version: '3.x' + python-version: '3.9' architecture: x64 # ICAT Ansible clone and install dependencies From bcb84b1465b2ce887aef54c08f0b837cc5d7faea Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 25 Oct 2021 12:30:54 +0000 Subject: [PATCH 15/22] Fix spacing in PR template --- .github/PULL_REQUEST_TEMPLATE.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1dc144a3..1e365c2d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,9 +8,7 @@ Add a set up instructions describing how the reviewer should test the code - [ ] Review code - [ ] Check GitHub Actions build -- [ ] If `icatdb Generator Script Consistency Test` CI job fails, is this because of a - deliberate change made to the script to change generated data (which isn't - actually a problem) or is there an underlying issue with the changes made? +- [ ] If `icatdb Generator Script Consistency Test` CI job fails, is this because of a deliberate change made to the script to change generated data (which isn't actually a problem) or is here an underlying issue with the changes made? - [ ] Review changes to test coverage - [ ] {more steps here} From 5431c95f4021370c60c2c69d5c81a1eec813818e Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 26 Oct 2021 15:03:00 +0000 Subject: [PATCH 16/22] Add flake8 ignore comments to long imports --- datagateway_api/common/helpers.py | 2 +- datagateway_api/src/api_start_utils.py | 6 +++--- .../src/resources/datagateway_api/entities/entity_map.py | 2 +- test/test_endpoint_rules.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/datagateway_api/common/helpers.py b/datagateway_api/common/helpers.py index aef45023..a474a3c4 100644 --- a/datagateway_api/common/helpers.py +++ b/datagateway_api/common/helpers.py @@ -20,7 +20,7 @@ FilterError, MissingCredentialsError, ) -from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( +from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( # noqa: B950 endpoints, ) diff --git a/datagateway_api/src/api_start_utils.py b/datagateway_api/src/api_start_utils.py index 4589cbeb..ea680e95 100644 --- a/datagateway_api/src/api_start_utils.py +++ b/datagateway_api/src/api_start_utils.py @@ -19,16 +19,16 @@ get_find_one_endpoint, get_id_endpoint, ) -from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( +from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( # noqa: B950 endpoints, ) from datagateway_api.src.resources.datagateway_api.non_entities.ping_endpoint import ( ping_endpoint, ) -from datagateway_api.src.resources.datagateway_api.non_entities.sessions_endpoints import ( +from datagateway_api.src.resources.datagateway_api.non_entities.sessions_endpoints import ( # noqa: B950 session_endpoints, ) -from datagateway_api.src.resources.datagateway_api.table_endpoints.table_endpoints import ( +from datagateway_api.src.resources.datagateway_api.table_endpoints.table_endpoints import ( # noqa: B950 count_instrument_facility_cycles_endpoint, count_instrument_investigation_endpoint, instrument_facility_cycles_endpoint, diff --git a/datagateway_api/src/resources/datagateway_api/entities/entity_map.py b/datagateway_api/src/resources/datagateway_api/entities/entity_map.py index 599e3feb..53e76f8b 100644 --- a/datagateway_api/src/resources/datagateway_api/entities/entity_map.py +++ b/datagateway_api/src/resources/datagateway_api/entities/entity_map.py @@ -3,7 +3,7 @@ from sqlalchemy.inspection import inspect from datagateway_api.common.helpers import get_entity_object_from_name -from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( +from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( # noqa: B950 endpoints, ) diff --git a/test/test_endpoint_rules.py b/test/test_endpoint_rules.py index e1a09efc..9930228d 100644 --- a/test/test_endpoint_rules.py +++ b/test/test_endpoint_rules.py @@ -1,6 +1,6 @@ import pytest -from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( +from datagateway_api.src.resources.datagateway_api.entities.entity_endpoint_dict import ( # noqa: B950 endpoints, ) From b0d8b4dae587e995d282a4ea0571e7fb292dfb2c Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 1 Nov 2021 12:36:45 +0000 Subject: [PATCH 17/22] Upgrade version of `werkzeug` via Flask --- poetry.lock | 190 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 110 insertions(+), 80 deletions(-) diff --git a/poetry.lock b/poetry.lock index c55070d0..39653e8a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -144,6 +144,14 @@ toml = {version = "*", optional = true, markers = "extra == \"toml\""} [package.extras] toml = ["toml"] +[[package]] +name = "dataclasses" +version = "0.8" +description = "A backport of the dataclasses module for Python 3.6" +category = "main" +optional = false +python-versions = ">=3.6, <3.7" + [[package]] name = "dparse" version = "0.5.1" @@ -307,21 +315,20 @@ flake8 = "*" [[package]] name = "flask" -version = "1.1.2" +version = "2.0.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.*" +python-versions = ">=3.6" [package.dependencies] -click = ">=5.1" -itsdangerous = ">=0.24" -Jinja2 = ">=2.10.1" -Werkzeug = ">=0.15" +click = ">=7.1.2" +itsdangerous = ">=2.0" +Jinja2 = ">=3.0" +Werkzeug = ">=2.0" [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"] +async = ["asgiref (>=3.2)"] dotenv = ["python-dotenv"] [[package]] @@ -452,33 +459,33 @@ python-versions = "*" [[package]] name = "itsdangerous" -version = "1.1.0" -description = "Various helpers to pass data to untrusted environments and back." +version = "2.0.1" +description = "Safely pass data to untrusted environments and back." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [[package]] name = "jinja2" -version = "2.11.3" +version = "3.0.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.*" +python-versions = ">=3.6" [package.dependencies] -MarkupSafe = ">=0.23" +MarkupSafe = ">=2.0" [package.extras] -i18n = ["Babel (>=0.8)"] +i18n = ["Babel (>=2.7)"] [[package]] name = "markupsafe" -version = "1.1.1" +version = "2.0.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.*" +python-versions = ">=3.6" [[package]] name = "mccabe" @@ -856,14 +863,16 @@ brotli = ["brotlipy (>=0.6.0)"] [[package]] name = "werkzeug" -version = "1.0.1" +version = "2.0.2" 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.*" +python-versions = ">=3.6" + +[package.dependencies] +dataclasses = {version = "*", markers = "python_version < \"3.7\""} [package.extras] -dev = ["pytest", "pytest-timeout", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinx-issues"] watchdog = ["watchdog"] [[package]] @@ -986,6 +995,10 @@ coverage = [ {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"}, {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, ] +dataclasses = [ + {file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"}, + {file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"}, +] dparse = [ {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, @@ -1036,8 +1049,8 @@ flake8-polyfill = [ {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"}, + {file = "Flask-2.0.2-py3-none-any.whl", hash = "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a"}, + {file = "Flask-2.0.2.tar.gz", hash = "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2"}, ] flask-cors = [ {file = "Flask-Cors-3.0.9.tar.gz", hash = "sha256:6bcfc100288c5d1bcb1dbb854babd59beee622ffd321e444b05f24d6d58466b8"}, @@ -1123,66 +1136,83 @@ iniconfig = [ {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] itsdangerous = [ - {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, - {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, + {file = "itsdangerous-2.0.1-py3-none-any.whl", hash = "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c"}, + {file = "itsdangerous-2.0.1.tar.gz", hash = "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0"}, ] jinja2 = [ - {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, - {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"}, + {file = "Jinja2-3.0.2-py3-none-any.whl", hash = "sha256:8569982d3f0889eed11dd620c706d39b60c36d6d25843961f33f77fb6bc6b20c"}, + {file = "Jinja2-3.0.2.tar.gz", hash = "sha256:827a0e32839ab1600d4eb1c4c33ec5a8edfbc5cb42dafa13b81f182f97784b45"}, ] 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-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"}, - {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-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"}, - {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-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"}, - {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-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"}, - {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-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"}, - {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-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"}, - {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, + {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, ] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, @@ -1439,8 +1469,8 @@ urllib3 = [ {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"}, ] werkzeug = [ - {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, - {file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"}, + {file = "Werkzeug-2.0.2-py3-none-any.whl", hash = "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f"}, + {file = "Werkzeug-2.0.2.tar.gz", hash = "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a"}, ] zipp = [ {file = "zipp-3.4.1-py3-none-any.whl", hash = "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"}, From c81eda1cb9ef03444494957bc72c09b5b9d16ca5 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 1 Nov 2021 12:52:39 +0000 Subject: [PATCH 18/22] Upgrade Flask-RESTful - To fix issue described in a Flask RESTful PR: https://github.com/flask-restful/flask-restful/pull/913 --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 39653e8a..f38204c2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -345,7 +345,7 @@ Six = "*" [[package]] name = "flask-restful" -version = "0.3.8" +version = "0.3.9" description = "Simple framework for creating REST APIs" category = "main" optional = false @@ -1057,8 +1057,8 @@ flask-cors = [ {file = "Flask_Cors-3.0.9-py2.py3-none-any.whl", hash = "sha256:cee4480aaee421ed029eaa788f4049e3e26d15b5affb6a880dade6bafad38324"}, ] flask-restful = [ - {file = "Flask-RESTful-0.3.8.tar.gz", hash = "sha256:5ea9a5991abf2cb69b4aac19793faac6c032300505b325687d7c305ffaa76915"}, - {file = "Flask_RESTful-0.3.8-py2.py3-none-any.whl", hash = "sha256:d891118b951921f1cec80cabb4db98ea6058a35e6404788f9e70d5b243813ec2"}, + {file = "Flask-RESTful-0.3.9.tar.gz", hash = "sha256:ccec650b835d48192138c85329ae03735e6ced58e9b2d9c2146d6c84c06fa53e"}, + {file = "Flask_RESTful-0.3.9-py2.py3-none-any.whl", hash = "sha256:4970c49b6488e46c520b325f54833374dc2b98e211f1b272bd4b0c516232afe2"}, ] flask-sqlalchemy = [ {file = "Flask-SQLAlchemy-2.5.1.tar.gz", hash = "sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912"}, From c4ca364fad1f22da347d63425e577778785aeb29 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 15 Oct 2021 13:34:30 +0000 Subject: [PATCH 19/22] #243: Fix tests for changes in Python ICAT 0.20.0 --- test/icat/filters/test_order_filter.py | 4 ++-- test/icat/filters/test_where_filter.py | 26 +++++++++++++------------- test/icat/test_filter_order_handler.py | 5 ++++- test/icat/test_query.py | 2 +- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/test/icat/filters/test_order_filter.py b/test/icat/filters/test_order_filter.py index 2f60b453..2fa66089 100644 --- a/test/icat/filters/test_order_filter.py +++ b/test/icat/filters/test_order_filter.py @@ -1,5 +1,5 @@ import pytest - +from typing_extensions import OrderedDict from datagateway_api.common.datagateway_api.filter_order_handler import ( FilterOrderHandler, @@ -83,7 +83,7 @@ def test_filter_applied_to_query(self, icat_query): filter_handler.add_filter(test_filter) filter_handler.apply_filters(icat_query) - assert icat_query.order == [("id", "DESC")] + assert icat_query.order == OrderedDict([("id", "%s DESC")]) filter_handler.clear_python_icat_order_filters() diff --git a/test/icat/filters/test_where_filter.py b/test/icat/filters/test_where_filter.py index 2e00342e..2ae808ad 100644 --- a/test/icat/filters/test_where_filter.py +++ b/test/icat/filters/test_where_filter.py @@ -11,16 +11,16 @@ class TestICATWhereFilter: @pytest.mark.parametrize( "operation, value, expected_condition_value", [ - pytest.param("eq", 5, "= '5'", id="equal"), - pytest.param("ne", 5, "!= 5", id="not equal"), - pytest.param("like", 5, "like '%5%'", id="like"), - pytest.param("nlike", 5, "not like '%5%'", id="not like"), - pytest.param("lt", 5, "< '5'", id="less than"), - pytest.param("lte", 5, "<= '5'", id="less than or equal"), - pytest.param("gt", 5, "> '5'", id="greater than"), - pytest.param("gte", 5, ">= '5'", id="greater than or equal"), - pytest.param("in", [1, 2, 3, 4], "in (1, 2, 3, 4)", id="in a list"), - pytest.param("in", [], "in (NULL)", id="empty list"), + pytest.param("eq", 5, ["%s = '5'"], id="equal"), + pytest.param("ne", 5, ["%s != 5"], id="not equal"), + pytest.param("like", 5, ["%s like '%%5%%'"], id="like"), + pytest.param("nlike", 5, ["%s not like '%%5%%'"], id="not like"), + pytest.param("lt", 5, ["%s < '5'"], id="less than"), + pytest.param("lte", 5, ["%s <= '5'"], id="less than or equal"), + pytest.param("gt", 5, ["%s > '5'"], id="greater than"), + pytest.param("gte", 5, ["%s >= '5'"], id="greater than or equal"), + pytest.param("in", [1, 2, 3, 4], ["%s in (1, 2, 3, 4)"], id="in a list"), + pytest.param("in", [], ["%s in (NULL)"], id="empty list"), ], ) def test_valid_operations( @@ -46,13 +46,13 @@ def test_valid_internal_icat_value(self, icat_query): test_filter = PythonICATWhereFilter("startDate", "o.endDate", "lt") test_filter.apply_filter(icat_query) - assert icat_query.conditions == {"startDate": "< o.endDate"} + assert icat_query.conditions == {"startDate": ["%s < o.endDate"]} def test_valid_field(self, icat_query): test_filter = PythonICATWhereFilter("title", "Investigation Title", "eq") test_filter.apply_filter(icat_query) - assert icat_query.conditions == {"title": "= 'Investigation Title'"} + assert icat_query.conditions == {"title": ["%s = 'Investigation Title'"]} def test_invalid_field(self, icat_query): test_filter = PythonICATWhereFilter("random_field", "my_value", "eq") @@ -68,4 +68,4 @@ def test_multiple_conditions_per_field(self, icat_query): filter_handler.add_filters([lt_filter, gt_filter]) filter_handler.apply_filters(icat_query) - assert icat_query.conditions == {"id": ["< '10'", "> '5'"]} + assert icat_query.conditions == {"id": ["%s < '10'", "%s > '5'"]} diff --git a/test/icat/test_filter_order_handler.py b/test/icat/test_filter_order_handler.py index bc557877..ab5eb4b6 100644 --- a/test/icat/test_filter_order_handler.py +++ b/test/icat/test_filter_order_handler.py @@ -68,4 +68,7 @@ def test_apply_filters(self, icat_query): test_handler.add_filters([where_filter, limit_filter]) test_handler.apply_filters(icat_query) - assert icat_query.conditions == {"id": "= '2'"} and icat_query.limit == (0, 10) + assert icat_query.conditions == {"id": ["%s = '2'"]} and icat_query.limit == ( + 0, + 10, + ) diff --git a/test/icat/test_query.py b/test/icat/test_query.py index 7a5334c8..4e76672b 100644 --- a/test/icat/test_query.py +++ b/test/icat/test_query.py @@ -55,7 +55,7 @@ class TestICATQuery: {"fullName": "like Bob"}, None, None, - {"fullName": "like Bob"}, + {"fullName": ["%s like Bob"]}, None, set(), id="Query with condition", From f5947901721a3b3b38a0611091755cab95f95547 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 15 Oct 2021 13:34:59 +0000 Subject: [PATCH 20/22] #243: Add ilike and nilike operators --- .../common/datagateway_api/icat/filters.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/datagateway_api/common/datagateway_api/icat/filters.py b/datagateway_api/common/datagateway_api/icat/filters.py index 6d9ad19c..f0f588ee 100644 --- a/datagateway_api/common/datagateway_api/icat/filters.py +++ b/datagateway_api/common/datagateway_api/icat/filters.py @@ -48,10 +48,20 @@ def create_filter(self): where_filter = self.create_condition(self.field, "!=", self.value) elif self.operation == "like": where_filter = self.create_condition(self.field, "like", f"%{self.value}%") + elif self.operation == "ilike": + self.field = f"UPPER({self.field})" + where_filter = self.create_condition( + self.field, "like", f"UPPER('%{self.value}%')", + ) elif self.operation == "nlike": where_filter = self.create_condition( self.field, "not like", f"%{self.value}%", ) + elif self.operation == "nilike": + self.field = f"UPPER({self.field})" + where_filter = self.create_condition( + self.field, "not like", f"UPPER('%{self.value}%')", + ) elif self.operation == "lt": where_filter = self.create_condition(self.field, "<", self.value) elif self.operation == "lte": @@ -101,7 +111,10 @@ def create_condition(attribute_name, operator, value): # distinct filter is used in a request jpql_value = ( f"{value}" - if operator == "in" or operator == "!=" or "o." in str(value) + if operator == "in" + or operator == "!=" + or str(value).startswith("UPPER") + or "o." in str(value) else f"'{value}'" ) From bb8098ff5d89921ebd5eef18a633af344315b584 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 15 Oct 2021 13:59:58 +0000 Subject: [PATCH 21/22] #243: Add tests for ilike and nilike operators --- test/icat/filters/test_where_filter.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/icat/filters/test_where_filter.py b/test/icat/filters/test_where_filter.py index 2ae808ad..1b0d7776 100644 --- a/test/icat/filters/test_where_filter.py +++ b/test/icat/filters/test_where_filter.py @@ -14,7 +14,11 @@ class TestICATWhereFilter: pytest.param("eq", 5, ["%s = '5'"], id="equal"), pytest.param("ne", 5, ["%s != 5"], id="not equal"), pytest.param("like", 5, ["%s like '%%5%%'"], id="like"), + pytest.param("ilike", 5, ["UPPER(%s) like UPPER('%%5%%')"], id="ilike"), pytest.param("nlike", 5, ["%s not like '%%5%%'"], id="not like"), + pytest.param( + "nilike", 5, ["UPPER(%s) not like UPPER('%%5%%')"], id="not ilike", + ), pytest.param("lt", 5, ["%s < '5'"], id="less than"), pytest.param("lte", 5, ["%s <= '5'"], id="less than or equal"), pytest.param("gt", 5, ["%s > '5'"], id="greater than"), From b59abba226d8673639403d6cb0f6b2066056b6cc Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 1 Nov 2021 11:01:39 +0000 Subject: [PATCH 22/22] #243: Upgrade Python ICAT version --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index f38204c2..d1e61b0c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -686,7 +686,7 @@ six = ">=1.5" [[package]] name = "python-icat" -version = "0.19.0" +version = "0.20.0" description = "Python interface to ICAT and IDS" category = "main" optional = false @@ -890,7 +890,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = "^3.6" -content-hash = "50007daac3ccc714a1b88bf352ca296d7aa7d8c2a4bb84996f3a4f3dc083dec1" +content-hash = "5926db8e5305909c59d6eb8b4601040c09a3747dba65e7b8cc421f806d815c04" [metadata.files] aniso8601 = [ @@ -1286,7 +1286,7 @@ python-dateutil = [ {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, ] python-icat = [ - {file = "python-icat-0.19.0.tar.gz", hash = "sha256:16d64bc8a9fa3d0e3861d38c8fb094a2eeee0b5343d33135b49e9743d9dcfc63"}, + {file = "python-icat-0.20.0.tar.gz", hash = "sha256:d09e85f0269ac5f8f6a43f2365eb269b532e611a5eaa3ab23ad7f742ee2bfa25"}, ] pytz = [ {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, diff --git a/pyproject.toml b/pyproject.toml index 9a954592..680f4d25 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ Flask-Cors = "3.0.9" apispec = "3.3.0" flask-swagger-ui = "3.25.0" PyYAML = "5.4" -python-icat = "0.19.0" +python-icat = "0.20.0" suds-community = "^0.8.4" py-object-pool = "^1.1" cachetools = "^4.2.1"