diff --git a/poetry.lock b/poetry.lock index e1f735a..0c0f30a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -33,20 +33,22 @@ files = [ [[package]] name = "attrs" -version = "21.4.0" +version = "23.2.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" files = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] [package.extras] -dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"] -docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] -tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"] -tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] name = "black" @@ -363,24 +365,42 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] [[package]] name = "jsonschema" -version = "4.6.1" +version = "4.21.1" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "jsonschema-4.6.1-py3-none-any.whl", hash = "sha256:5eb781753403847fb320f05e9ab2191725b58c5e7f97f1bed63285ca423159bc"}, - {file = "jsonschema-4.6.1.tar.gz", hash = "sha256:ec2802e6a37517f09d47d9ba107947589ae1d25ff557b925d83a321fc2aa5d3b"}, + {file = "jsonschema-4.21.1-py3-none-any.whl", hash = "sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f"}, + {file = "jsonschema-4.21.1.tar.gz", hash = "sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5"}, ] [package.dependencies] -attrs = ">=17.4.0" +attrs = ">=22.2.0" importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +jsonschema-specifications = ">=2023.03.6" +pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +[[package]] +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] + +[package.dependencies] +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +referencing = ">=0.31.0" + [[package]] name = "mypy-extensions" version = "0.4.3" @@ -417,6 +437,17 @@ files = [ {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, ] +[[package]] +name = "pkgutil-resolve-name" +version = "1.3.10" +description = "Resolve a name to an object." +optional = false +python-versions = ">=3.6" +files = [ + {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, + {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, +] + [[package]] name = "platformdirs" version = "2.5.2" @@ -523,36 +554,6 @@ files = [ [package.extras] diagrams = ["jinja2", "railroad-diagrams"] -[[package]] -name = "pyrsistent" -version = "0.18.1" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, - {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, - {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"}, - {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"}, - {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"}, - {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"}, - {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"}, - {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"}, - {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"}, - {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"}, - {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"}, - {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"}, - {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"}, - {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"}, - {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"}, - {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"}, -] - [[package]] name = "pytest" version = "7.1.2" @@ -609,6 +610,21 @@ files = [ [package.extras] dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatch", "invoke (==2.2.0)", "more-itertools (==4.3.0)", "pbr (==4.3.0)", "pluggy (==1.0.0)", "py (==1.11.0)", "pytest (==7.2.0)", "pytest-cov (==4.0.0)", "pytest-timeout (==2.1.0)", "pyyaml (==5.1)"] +[[package]] +name = "referencing" +version = "0.33.0" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.33.0-py3-none-any.whl", hash = "sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5"}, + {file = "referencing-0.33.0.tar.gz", hash = "sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + [[package]] name = "requests" version = "2.28.0" @@ -648,6 +664,114 @@ urllib3 = ">=1.25.10" [package.extras] tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asyncio", "pytest-cov", "pytest-localserver", "types-mock", "types-requests"] +[[package]] +name = "rpds-py" +version = "0.18.0" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.18.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e"}, + {file = "rpds_py-0.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88"}, + {file = "rpds_py-0.18.0-cp310-none-win32.whl", hash = "sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337"}, + {file = "rpds_py-0.18.0-cp310-none-win_amd64.whl", hash = "sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66"}, + {file = "rpds_py-0.18.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4"}, + {file = "rpds_py-0.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836"}, + {file = "rpds_py-0.18.0-cp311-none-win32.whl", hash = "sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1"}, + {file = "rpds_py-0.18.0-cp311-none-win_amd64.whl", hash = "sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa"}, + {file = "rpds_py-0.18.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0"}, + {file = "rpds_py-0.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7"}, + {file = "rpds_py-0.18.0-cp312-none-win32.whl", hash = "sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98"}, + {file = "rpds_py-0.18.0-cp312-none-win_amd64.whl", hash = "sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec"}, + {file = "rpds_py-0.18.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e"}, + {file = "rpds_py-0.18.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594"}, + {file = "rpds_py-0.18.0-cp38-none-win32.whl", hash = "sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e"}, + {file = "rpds_py-0.18.0-cp38-none-win_amd64.whl", hash = "sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1"}, + {file = "rpds_py-0.18.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33"}, + {file = "rpds_py-0.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20"}, + {file = "rpds_py-0.18.0-cp39-none-win32.whl", hash = "sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7"}, + {file = "rpds_py-0.18.0-cp39-none-win_amd64.whl", hash = "sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f"}, + {file = "rpds_py-0.18.0.tar.gz", hash = "sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d"}, +] + [[package]] name = "setuptools" version = "68.1.0" diff --git a/preClinVar/main.py b/preClinVar/main.py index 2f6686f..d68cbe7 100644 --- a/preClinVar/main.py +++ b/preClinVar/main.py @@ -7,6 +7,7 @@ import uvicorn from fastapi import FastAPI, File, Form, Request, UploadFile from fastapi.responses import JSONResponse + from preClinVar.__version__ import VERSION from preClinVar.build import build_header, build_submission from preClinVar.constants import DRY_RUN_SUBMISSION_URL, VALIDATE_SUBMISSION_URL @@ -43,7 +44,13 @@ async def validate(api_key: str = Form(), json_file: UploadFile = File(...)): # And use it in POST request to API data = { - "actions": [{"type": "AddData", "targetDb": "clinvar", "data": {"content": submission_obj}}] + "actions": [ + { + "type": "AddData", + "targetDb": "clinvar", + "data": {"content": submission_obj}, + } + ] } resp = requests.post(VALIDATE_SUBMISSION_URL, data=json.dumps(data), headers=header) return JSONResponse( @@ -63,7 +70,13 @@ async def dry_run(api_key: str = Form(), json_file: UploadFile = File(...)): # And use it in POST request to API data = { - "actions": [{"type": "AddData", "targetDb": "clinvar", "data": {"content": submission_obj}}] + "actions": [ + { + "type": "AddData", + "targetDb": "clinvar", + "data": {"content": submission_obj}, + } + ] } resp = requests.post(DRY_RUN_SUBMISSION_URL, data=json.dumps(data), headers=header) @@ -83,11 +96,6 @@ async def dry_run(api_key: str = Form(), json_file: UploadFile = File(...)): async def tsv_2_json( request: Request, files: List[UploadFile] = File(...), - submissionName: Union[str, None] = None, - releaseStatus: Union[str, None] = None, - assertionCriteriaDB: Union[str, None] = None, - assertionCriteriaID: Union[str, None] = None, - assembly: Union[str, None] = None, ): """Create a json submission object using 2 TSV files (Variant.tsv and CaseData.tsv). Validate the submission objects agains the official schema: @@ -140,11 +148,6 @@ async def tsv_2_json( async def csv_2_json( request: Request, files: List[UploadFile] = File(...), - submissionName: Union[str, None] = None, - releaseStatus: Union[str, None] = None, - assertionCriteriaDB: Union[str, None] = None, - assertionCriteriaID: Union[str, None] = None, - assembly: Union[str, None] = None, ): """Create a json submission object using 2 CSV files (Variant.csv and CaseData.csv). Validate the submission objects agains the official schema: @@ -178,8 +181,14 @@ async def csv_2_json( ) # Convert lines extracted from csv files to a submission object (a dictionary) - submission_dict = file_fields_to_submission(variants_lines, casedata_lines) - build_submission(submission_dict, request) + try: + submission_dict = file_fields_to_submission(variants_lines, casedata_lines) + build_submission(submission_dict, request) + except Exception as ex: + return JSONResponse( + status_code=400, + content={"message": str(ex)}, + ) # Validate submission object using official schema valid_results = validate_submission(submission_dict) diff --git a/preClinVar/resources/submission_schema.json b/preClinVar/resources/submission_schema.json index 6a2f149..855a02c 100644 --- a/preClinVar/resources/submission_schema.json +++ b/preClinVar/resources/submission_schema.json @@ -1,64 +1,15 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", + "anyOf": [ + {"required": ["clinvarSubmission"]}, + {"required": ["clinvarDeletion"]} + ], "properties": { - "assertionCriteria": { - "type": "object", - "description": "\"Assertion criteria\" refers to documentation of the criteria that your organization uses to classify variants. It can be provided as a database identifier, like a PubMed ID, or a file that is submitted to ClinVar, but not both. Only one document may be provided for assertion criteria. These fields are equivalent to the \"Assertion method citation\" column in the spreadsheet. Note that only one single assertion criteria (a citation or an electronic document) may be provided for a submission. This assertion criteria will be applied to all interpretations in the submission. For assertion criteria submitted as a database identifier, an assertion criteria name will be calculated based on the citation details. For assertion criteria submitted as a file, you may provide an assertion criteria name during file upload on your Organization page in Submission Portal.", - "properties": { - "db": { - "type": "string", - "enum": [ - "PubMed", - "DOI", - "pmc" - ] - }, - "id": { - "type": "string", - "description": "The document identifier. Formats are: \nPubMed: the PubMed ID, digits only, e.g. 10862036\npmc: the PubMedCentral ID, digits only, e.g. 2746682\nDOI: the full DOI including prefix, forward slash, and suffix, e.g. 10.1038/gim.2015.30", - "errors": { - "pattern": "The identifier value is considered an invalid citation. Please provide only one identifier as the citation for your assertion criteria." - }, - "pattern": "^[^;]+$" - }, - "url": { - "type": "string", - "description": " The URL for a file that you have already submitted to ClinVar as assertion criteria. If you need to find this URL or if you need to submit new assertion criteria, please go to the \"View/add assertion criteria files\" tab on your Organization page in Submission Portal.", - "errors": { - "pattern": "The URL for assertion criteria must be the URL provided by ClinVar. If you need to find this URL or if you need to submit new assertion criteria, Please go to the \"View/add assertion criteria files\" tab on your Organization page in Submission Portal." - }, - "pattern": "^https://[qd]?submit.ncbi.nlm.nih.gov/(api/2.0/files|ft/byid)/.*" - } - }, - "additionalProperties": false, - "oneOf": [ - { - "required": [ - "url" - ] - }, - { - "required": [ - "db", - "id" - ] - } - ] - }, - "behalfOrgID": { - "type": "integer", - "description": "Optional. When submitting on behalf of another organization, this specifies the other organization's ID", - "minimum": 1 - }, "clinvarDeletion": { "type": "object", - "items": { - "type": "object", + "required": ["accessionSet"], "title": "ClinVar Deletions", - "required": [ - "accessionSet" - ], "properties": { "accessionSet": { "type": "array", @@ -67,603 +18,532 @@ "items": { "type": "object", "title": "Clinvar accession and reason for deleting", - "required": [ - "accession" - ], + "required": ["accession"], "properties": { "accession": { "type": "string", - "description": "The SCV accession for your submitted record to delete (not the RCV or the VCV), e.g. SCV000123456.", - "pattern": "^SCV[0123456789]{9}$" + "pattern": "^SCV[0123456789]{9}$", + "description": "The SCV accession for your submitted record to delete (not the RCV or the VCV), e.g. SCV000123456." }, "reason": { "type": "string", "description": "A public comment explaining why this record is being deleted." } } + }, + "errors": { + "minItems": "Empty list of assertionSet for clinvarDeletion not allowed", + "maxItems": "no more than 10000 assertionSet for clinvarDeletion allowed" } } } - } }, "clinvarSubmission": { "type": "array", "title": "ClinVar Submission Set", "minItems": 1, "maxItems": 10000, - "items": { - "type": "object", - "title": "ClinVar Submission", - "description": "Submissions to ClinVar are considered 'variant-level' (not case-level or patient-specific), because they are focused on the variant or set of variants that was interpreted. One of variantSet, haplotypeSet, haplotypeSingleVariantSet, phaseUnknownSet, distinctChromosomesSet, diplotypeSet, compoundHeterozygoteSet is required to define the variant or set of variants that was interpreted.", - "required": [ - "recordStatus", - "clinicalSignificance", - "observedIn", - "conditionSet" - ], - "properties": { - "clinicalSignificance": { - "type": "object", - "description": "Clinical significance", - "required": [ - "clinicalSignificanceDescription" - ], - "properties": { - "citation": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "description": "Citations that were used by the submitter to evaluate the clinical significance of the variant. More than one citation may be provided. Each citation can be provided as a database identifier, like a PubMed ID, or a URL, but not both.", - "properties": { - "db": { - "type": "string", - "enum": [ - "PubMed", - "BookShelf", - "DOI", - "pmc" - ] - }, - "id": { - "type": "string", - "description": "The document identifier. Formats are: \nPubMed: the PubMed ID, digits only, e.g. 10862036\npmc: the PubMedCentral ID, digits only, e.g. 2746682\nDOI: the full DOI including prefix, forward slash, and suffix, e.g. 10.1038/gim.2015.30\nBookShelf: the Bookshelf ID including the prefix, e.g. NBK1384" - }, - "url": { - "type": "string" - } - }, - "additionalProperties": false, - "oneOf": [ - { - "required": [ - "db", - "id" - ] - }, - { - "required": [ - "url" - ] - } - ] - } - }, - "clinicalSignificanceDescription": { - "type": "string", - "description": "The interpretation, or clinical significance, of the variant for the submitted condition, equivalent to Clinical significance in the submission spreadsheet.", - "enum": [ - "Pathogenic", - "Likely pathogenic", - "Uncertain significance", - "Likely benign", - "Benign", - "Pathogenic, low penetrance", - "Uncertain risk allele", - "Likely pathogenic, low penetrance", - "Established risk allele", - "Likely risk allele", - "affects", - "association", - "drug response", - "confers sensitivity", - "protective", - "other", - "not provided" - ] - }, - "comment": { - "type": "string", - "description": "Optional, but highly encouraged. Free text describing the rationale for the clinical significance." - }, - "customAssertionScore": { - "type": "number", - "description": "The final score, or point value, calculated when the assertion method uses a point-based scoring system, e.g. ACMG/ClinGen CNV Guidelines, 2019 (PMID: 31690835). The assertion method must also be provided. " - }, - "dateLastEvaluated": { - "type": "string", - "description": "The date that the clinical significance was last evaluated by the submitter (not the date the phenotype of the patient was evaluated), equivalent to Date last evaluated in the submission spreadsheet. Use the format yyyy-mm-dd. If only month/year is known, use the first day of the month. If only year is known, use Jan. 1.", - "pattern": "^[1-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]$" - }, - "explanationOfDrugResponse": { - "type": "string", - "description": "Required for a record with clinical significance of 'drug response'. Please provide a value describing the drug response, e.g. 'likely responsive'. This value must be short for display purposes. A longer explanation should be provided in the 'Comment on clinical significance'." - }, - "explanationOfOtherClinicalSignificance": { - "type": "string", - "description": "Required if 'other' is selected for clinical significance. Please provide the new value for clinical significance, e.g. pseudodeficiency allele. This value must be short for display purposes. A longer explanation should be provided in the 'Comment on clinical significance'." - }, - "modeOfInheritance": { - "type": "string", - "description": "The mode of inheritance specific to the variant-disease pair, not generally for the disease.", - "enum": [ - "Autosomal dominant inheritance", - "Autosomal recessive inheritance", - "Mitochondrial inheritance", - "Genetic anticipation", - "Sporadic", - "Sex-limited autosomal dominant", - "X-linked recessive inheritance", - "X-linked dominant inheritance", - "Y-linked inheritance", - "Other", - "X-linked inheritance", - "Codominant", - "Semidominant inheritance", - "Autosomal unknown", - "Autosomal dominant inheritance with maternal imprinting", - "Autosomal dominant inheritance with paternal imprinting", - "Multifactorial inheritance", - "Unknown mechanism", - "Oligogenic inheritance" - ] - } - }, - "additionalProperties": false - }, - "clinvarAccession": { - "type": "string", - "description": "Required for updated records and for novel records if accession numbers were reserved. Provide the SCV number for your submitted record (not the RCV number), e.g. SCV000123456." - }, - "compoundHeterozygoteSet": { - "$ref": "#/definitions/compoundHeterozygoteSetType" - }, - "conditionSet": { - "type": "object", - "description": "The condition for which the variant is interpreted. Detailed information about reporting condition is available at https://www.ncbi.nlm.nih.gov/clinvar/docs/faq_submitters/#pheno If multiple conditions are submitted for a variant, this indicates that the variant was interpreted for the combination of conditions in the same individual(s). i.e. this variant causes both condition A and condition B in the same individual. This scenario is most common for a new disease or syndrome that does not yet have a name and is described by several clinical features. If you want to indicate that the variant has been interpreted for more than one condition, please submit these as separate records. i.e. this variant causes condition A in some individuals and causes disease B in other individuals. Provide only one name or identifier for a condition; do not provide multiple names or identifiers for the same condition.", - "properties": { - "condition": { - "description": "The condition must be provided as either a database identifier or a name, but not both. A database identifier is preferred by ClinVar; a name should be provided only if there is no database identifier available.", - "$ref": "#/definitions/conditionType" - }, - "drugResponse": { - "description": "The drug Response evaluated specified by database ID or drug name, but not both", - "$ref": "#/definitions/drugResponseType" - }, - "multipleConditionExplanation": { - "type": "string", - "description": "Variants in ClinVar are typically classified for a single condition (disease or drug response). If more than one condition is provided in the conditionSet, this field is required and explains why multiple conditions are valid. Options are \"Novel disease\" when a new disease is unnamed and only described by a set of clinical features (HPO ids); \"Uncertain\" when a variant is classified for several related diseases and it may be uncertain whether the variant causes one or several of them; and \"Co-occurring\" when a variant causes more than one disease in the same individual (this is expected to be rare).", - "enum": [ - "Novel disease", - "Uncertain", - "Co-occurring" - ] - } - }, - "additionalProperties": false, - "oneOf": [ - { - "required": [ - "condition" - ] - }, - { - "allOf": [ - { - "required": [ - "drugResponse" - ] - }, - { - "not": { - "required": [ - "multipleConditionExplanation" - ] - } - } - ] - } - ] - }, - "diplotypeSet": { - "$ref": "#/definitions/diplotypeSetType" - }, - "distinctChromosomesSet": { - "$ref": "#/definitions/distinctChromosomesSetType" - }, - "haplotypeSet": { - "$ref": "#/definitions/haplotypeSetType" - }, - "haplotypeSingleVariantSet": { - "$ref": "#/definitions/haplotypeSingleVariantSetType" - }, - "localID": { - "type": "string", - "description": "Optional, but highly recommended. The stable unique identifier your organization uses to identifiy this variant. This identifier will be public so should not include protected health information." - }, - "localKey": { - "type": "string", - "description": "Your unique local identifier for the variant-condition pair, equivalent to the Linking ID in the submission spreadsheet." - }, - "observedIn": { - "type": "array", - "minItems": 1, - "items": { + "items": + { + "type": "object", + "title": "ClinVar Submission", + "$ref": "#/definitions/baseSubmissionType", + "required": [ + "clinicalSignificance", + "observedIn", + "conditionSet" + ], + "properties": { + "clinicalSignificance": { "type": "object", + "description": "Clinical significance", "required": [ - "alleleOrigin", - "affectedStatus", - "collectionMethod" + "clinicalSignificanceDescription" ], + "$ref": "#/definitions/baseClassificationType", "properties": { - "affectedStatus": { + "clinicalSignificanceDescription": { "type": "string", - "description": "Indicates whether or not the individual(s) in each observation were affected by the condition for the interpretation", + "description": "The interpretation, or clinical significance, of the variant for the submitted condition, equivalent to Clinical significance in the submission spreadsheet.", "enum": [ - "yes", - "no", - "unknown", - "not provided", - "not applicable" + "Pathogenic", + "Likely pathogenic", + "Uncertain significance", + "Likely benign", + "Benign", + "Pathogenic, low penetrance", + "Uncertain risk allele", + "Likely pathogenic, low penetrance", + "Established risk allele", + "Likely risk allele", + "affects", + "association", + "drug response", + "confers sensitivity", + "protective", + "other", + "not provided" ] }, - "alleleOrigin": { + "modeOfInheritance": { "type": "string", - "description": "The genetic origin of the variant for individuals in each aggregate observation. For de novo variants, please indicate 'de novo', not the origin of the chromosome.", + "description": "The mode of inheritance specific to the variant-disease pair, not generally for the disease.", "enum": [ - "germline", - "somatic", - "de novo", - "unknown", - "inherited", - "maternal", - "paternal", - "biparental", - "not applicable" + "Autosomal dominant inheritance", + "Autosomal recessive inheritance", + "Mitochondrial inheritance", + "Genetic anticipation", + "Sporadic", + "Sex-limited autosomal dominant", + "X-linked recessive inheritance", + "X-linked dominant inheritance", + "Y-linked inheritance", + "Other", + "X-linked inheritance", + "Codominant", + "Semidominant inheritance", + "Autosomal unknown", + "Autosomal dominant inheritance with maternal imprinting", + "Autosomal dominant inheritance with paternal imprinting", + "Multifactorial inheritance", + "Unknown mechanism", + "Oligogenic inheritance" ] }, - "clinicalFeatures": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "description": "Clinical features that were observed by the submitter in an individual with the variant. More than one feature may be provided. Each clinical feature may be described by a database identifier or by a name, but not both. These fields are equivalent to the \"Clinical features\" column in the spreadsheet.", - "required": [ - "clinicalFeaturesAffectedStatus" - ], - "properties": { - "clinicalFeaturesAffectedStatus": { - "type": "string", - "description": "To indicate whether each clinical feature was present, absent, or not tested in the individual(s) observed. ", - "enum": [ - "present", - "absent", - "not tested" - ] - }, - "db": { - "type": "string", - "enum": [ - "HP" - ] - }, - "id": { - "type": "string", - "description": "The HPO identifier including the prefix, e.g. HP:0000815" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false, - "oneOf": [ - { - "required": [ - "id", - "db" - ] - }, - { - "required": [ - "name" - ] - } - ] - } - }, - "clinicalFeaturesComment": { - "type": "string", - "description": "To provide a free text explanation of clinical features provided in the previous column, e.g. to describe the progression of disease or diagnosis. Please use this comment to expand on the information in 'clinicalFeatures'" + "customAssertionScore": { + "type": "number", + "description": "The final score, or point value, calculated when the assertion method uses a point-based scoring system, e.g. ACMG/ClinGen CNV Guidelines, 2019 (PMID: 31690835). The assertion method must also be provided. " }, - "collectionMethod": { + "explanationOfDrugResponse": { "type": "string", - "description": "The method used to collect the data for each observation, e.g. clinical testing or research. See https://www.ncbi.nlm.nih.gov/clinvar/docs/spreadsheet/#collection", - "enum": [ - "curation", - "literature only", - "reference population", - "provider interpretation", - "phenotyping only", - "case-control", - "clinical testing", - "in vitro", - "in vivo", - "research", - "not provided" - ] - }, - "numberOfIndividuals": { - "type": "integer", - "description": "The total number of individuals with the variant observed by the submitter.", - "minimum": 0 + "description": "Required for a record with clinical significance of 'drug response'. Please provide a value describing the drug response, e.g. 'likely responsive'. This value must be short for display purposes. A longer explanation should be provided in the 'Comment on clinical significance'." }, - "structVarMethodType": { + "explanationOfOtherClinicalSignificance": { "type": "string", - "description": "The method and type of analysis used to identify a structural variant, i.e. any variant >50 nt, equivalent to \"Structural variant method/analysis type\" in the submission spreadsheet. Allowed values are enumerated in the schema. Although optional in the JSON, this field is required for variants that are >50 nt (and in scope for dbVar).", - "enum": [ - "SNP array", - "Oligo array", - "Read depth", - "Paired-end mapping", - "One end anchored assembly", - "Sequence alignment", - "Optical mapping", - "Curated,PCR" - ] + "description": "Required if 'other' is selected for clinical significance. Please provide the new value for clinical significance, e.g. pseudodeficiency allele. This value must be short for display purposes. A longer explanation should be provided in the 'Comment on clinical significance'." } }, + "unevaluatedProperties": false + }, + "conditionSet": { + "type": "object", + "description": "The condition for which the variant is interpreted. Detailed information about reporting condition is available at https://www.ncbi.nlm.nih.gov/clinvar/docs/faq_submitters/#pheno If multiple conditions are submitted for a variant, this indicates that the variant was interpreted for the combination of conditions in the same individual(s). i.e. this variant causes both condition A and condition B in the same individual. This scenario is most common for a new disease or syndrome that does not yet have a name and is described by several clinical features. If you want to indicate that the variant has been interpreted for more than one condition, please submit these as separate records. i.e. this variant causes condition A in some individuals and causes disease B in other individuals. Provide only one name or identifier for a condition; do not provide multiple names or identifiers for the same condition.", + "oneOf": [ + { + "required": ["condition"] + }, + { + "allOf": [ + {"required": ["drugResponse"]}, + {"not": { "required": ["multipleConditionExplanation"]}} + ] + } + ], + "properties": { + "multipleConditionExplanation": { + "type": "string", + "enum": [ + "Novel disease", + "Uncertain", + "Co-occurring" + ], + "description": "Variants in ClinVar are typically classified for a single condition (disease or drug response). If more than one condition is provided in the conditionSet, this field is required and explains why multiple conditions are valid. Options are \"Novel disease\" when a new disease is unnamed and only described by a set of clinical features (HPO ids); \"Uncertain\" when a variant is classified for several related diseases and it may be uncertain whether the variant causes one or several of them; and \"Co-occurring\" when a variant causes more than one disease in the same individual (this is expected to be rare)." + }, + "condition": { + "description": "The condition must be provided as either a database identifier or a name, but not both. A database identifier is preferred by ClinVar; a name should be provided only if there is no database identifier available.", + "$ref": "#/definitions/conditionType" + }, + "drugResponse": { + "description": "The drug Response evaluated specified by database ID or drug name, but not both", + "$ref": "#/definitions/drugResponseType" + } + }, "additionalProperties": false + }, + "observedIn": { + "type": "array", + "minItems": 1, + "items": + { + "type": "object", + "$ref": "#/definitions/baseObservationType", + "unevaluatedProperties": false + }, + "errors": {"minItems": "Empty list of observedIn not allowed"} } }, - "phaseUnknownSet": { - "$ref": "#/definitions/phaseUnknownSetType" + "unevaluatedProperties": false, + "if": { + "properties": { + "clinicalSignificance": { + "properties" : { + "clinicalSignificanceDescription": { "const": "drug response" } + } + } + } }, - "recordStatus": { - "type": "string", - "description": "If you include SCV accessions for 'clinvarAccession', you must indicate whether each record is novel (and accessions were reserved prior to submission) or is an update to an existing SCV record.", - "enum": [ - "novel", - "update" - ] + "then": { + "properties": { + "conditionSet": { + "required": ["drugResponse"], + "errors": {"required": "when clinicalSignificanceDescription is \"drug response\", conditionSet.drugResponse is a required property"} + } + } }, - "variantSet": { - "$ref": "#/definitions/variantSetType" + "else" : { + "properties": { + "conditionSet": { + "required": ["condition"], + "errors": {"required": "conditionSet.drugResponse is allowed only when clinicalSignificanceDescription is \"drug response\""} + } + } } }, - "additionalProperties": false, - "else": { - "properties": { - "conditionSet": { - "required": [ - "condition" - ], - "errors": { - "required": "conditionSet.drugResponse is allowed only when clinicalSignificanceDescription is \"drug response\"" - } - } - } + "errors": { + "minItems": "Empty list of clinvarSubmission not allowed", + "maxItems": "no more than 10000 clinvarSubmission allowed" + } + }, + "submissionName": { + "type": "string", + "description": "Optional. The name for this submission. If not provided, it will be the submission id." + }, + "clinvarSubmissionReleaseStatus": { + "type": "string", + "description": "\"hold until published\" allows a temporary hold on submission data being presented publicly. If no value is provided, the default is public.", + "enum": [ + "public", + "hold until published" + ] + }, + "assertionCriteria": { + "type": "object", + "description": "\"Assertion criteria\" refers to documentation of the criteria that your organization uses to classify variants. It can be provided as a database identifier, like a PubMed ID, or a file that is submitted to ClinVar, but not both. Only one document may be provided for assertion criteria. These fields are equivalent to the \"Assertion method citation\" column in the spreadsheet. Note that only one single assertion criteria (a citation or an electronic document) may be provided for a submission. This assertion criteria will be applied to all interpretations in the submission. For assertion criteria submitted as a database identifier, an assertion criteria name will be calculated based on the citation details. For assertion criteria submitted as a file, you may provide an assertion criteria name during file upload on your Organization page in Submission Portal.", + "properties": { + "db": { + "type": "string", + "enum": [ + "PubMed", + "DOI", + "pmc" + ] }, - "if": { - "properties": { - "clinicalSignificance": { - "properties": { - "clinicalSignificanceDescription": { - "const": "drug response" - } - } - } + "id": { + "type": "string", + "description": "The document identifier. Formats are: \nPubMed: the PubMed ID, digits only, e.g. 10862036\npmc: the PubMedCentral ID, digits only, e.g. 2746682\nDOI: the full DOI including prefix, forward slash, and suffix, e.g. 10.1038/gim.2015.30", + "pattern": "^[^;]+$", + "errors": { + "pattern": "The identifier value is considered an invalid citation. Please provide only one identifier as the citation for your assertion criteria." } }, - "oneOf": [ - { - "required": [ - "variantSet" - ] - }, - { - "required": [ - "haplotypeSet" - ] - }, - { - "required": [ - "haplotypeSingleVariantSet" - ] - }, - { - "required": [ - "phaseUnknownSet" - ] - }, - { - "required": [ - "distinctChromosomesSet" - ] - }, - { - "required": [ - "diplotypeSet" - ] - }, - { - "required": [ - "compoundHeterozygoteSet" - ] + "url": { + "type": "string", + "description": " The URL for a file that you have already submitted to ClinVar as assertion criteria. If you need to find this URL or if you need to submit new assertion criteria, please go to the \"View/add assertion criteria files\" tab on your Organization page in Submission Portal.", + "pattern": "^https://[qd]?submit.ncbi.nlm.nih.gov/(api/2.0/files|ft/byid)/.*", + "errors": { + "pattern": "The URL for assertion criteria must be the URL provided by ClinVar. If you need to find this URL or if you need to submit new assertion criteria, Please go to the \"View/add assertion criteria files\" tab on your Organization page in Submission Portal." } - ], - "then": { + } + }, + "additionalProperties": false, + "oneOf": [ + { + "required": [ + "url" + ] + }, + { + "required": [ + "db", + "id" + ] + } + ] + }, + "behalfOrgID": { + "type": "integer", + "minimum": 1, + "description": "Optional. When submitting on behalf of another organization, this specifies the other organization's ID" + } + }, + "definitions": { + "variantType": { + "type": "object", + "description": "type of variant", + "properties": { + "chromosomeCoordinates": { + "type": "object", + "description": "The location of the variant in chromosome coordinates. Use only 1-based coordinates, not 0-based. For large variants (> 50 nt.), if the exact coordinates (to basepair resolution) of the variant call are known, provide only the start and stop coordinates. Otherwise, use outer_start (lower value) and inner_start (upper value) to define the interval in which the call begins. Likewise, use inner_stop (lower value) and outer_stop (upper value) to define the interval in which the call ends. If only the minimal region is known, use inner_start and inner_stop. If only the maximum region is known, use outer_start and outer_stop. You must provide either one set of coordinates (start and stop, outers only, or inners only) or two sets of coordinates (inners and outers).", "properties": { - "conditionSet": { + "accession": { + "type": "string", + "description": "The accession and version number for the chromosome, e.g. NC_000007.14." + }, + "alternateAllele": { + "type": "string", + "description": "The alternate allele for the submitted variant. This is used only for small variants (up to 50 nt.)" + }, + "assembly": { + "type": "string", + "description": "The genome assembly that was used to call the variant.", + "enum": [ + "GRCh38", + "hg38", + "GRCh37", + "hg19", + "NCBI36", + "hg18" + ] + }, + "chromosome": { + "type": "string", + "description": "The chromosome for the location of the variant. Values are 1-22, X, Y, and MT. If the location is pseudoautosomal, submit on X and ClinVar will calculate the Y location.", + "enum": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "X", + "Y", + "MT" + ] + }, + "innerStart": { + "type": "integer", + "minimum": 0, + "description": "Indicate imprecise locations for structural variants. This is used only for large variants (more than 50 nt.)" + }, + "innerStop": { + "type": "integer", + "minimum": 0, + "description": "Indicate imprecise locations for structural variants. This is used only for large variants (more than 50 nt.)" + }, + "outerStart": { + "type": "integer", + "minimum": 0, + "description": "Indicate imprecise locations for structural variants. This is used only for large variants (more than 50 nt.)" + }, + "outerStop": { + "type": "integer", + "minimum": 0, + "description": "Indicate imprecise locations for structural variants. This is used only for large variants (more than 50 nt.)" + }, + "referenceAllele": { + "type": "string", + "description": "The reference allele for the submitted variant. This is used only for small variants (up to 50 nt.)" + }, + "start": { + "type": "integer", + "minimum": 0, + "description": "The start location for the reference allele in chromosome coordinates. If only start is provided for the location, stop will be presumed to be the same coordinate." + }, + "stop": { + "type": "integer", + "minimum": 0, + "description": "The stop location for the reference allele in chromosome coordinates. If only start is provided for the location, stop will be presumed to be the same coordinate." + }, + "variantLength": { + "type": "integer", + "minimum": 0, + "description": "Required for structural variants if outer start/stop is provided but inner start/stop is not provided" + } + }, + "additionalProperties": false, + "anyOf": [ + { "required": [ - "drugResponse" - ], - "errors": { - "required": "when clinicalSignificanceDescription is \"drug response\", conditionSet.drugResponse is a required property" + "assembly", + "chromosome" + ] + }, + { + "required": [ + "accession" + ] + } + ] + }, + "copyNumber": { + "type": "string", + "description": "For copy number variants, both the reference copy number and the observed copy number can be provided. The observed copy number is a string, to allow for cases where the copy number is ambiguous and a range is provided, e.g. 3,4." + }, + "gene": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "description": "Gene symbol should be provided only to indicate the gene-disease relationship supporting the variant interpretation. Gene symbol is not expected for CNVs or cytogenetic variants, except to make a statement that a specific gene within the variant has a relationship to the interpreted condition. Gene symbol can be provided as either the HGNC official symbol or as the NCBI Gene ID, but not both.", + "properties": { + "id": { + "type": "integer", + "minimum": 0, + "description": "NCBI Gene ID" + }, + "symbol": { + "type": "string", + "description": "HGNC official gene symbol." + } + }, + "additionalProperties": false, + "oneOf": [ + { + "required": [ + "id" + ] + }, + { + "required": [ + "symbol" + ] } - } - } + ] + }, + "errors": {"minItems": "Empty list of gene in variant not allowed"} + }, + "hgvs": { + "type": "string", + "description": "A single, valid HGVS expression to describe the variant on a nucleotide sequence." + }, + "referenceCopyNumber": { + "type": "integer", + "minimum": 0, + "description": "For copy number variants, both the reference copy number and the observed copy number can be provided. The reference copy number is an integer and is typically \"2\", as most genes and variants are on autosomes." + }, + "variantType": { + "type": "string", + "description": "The type of variant; provided for larger variants instead of reference and alternate alleles. Required for any variant for which the reference and alternate alleles are not specified. In practice, this will occur for structural variants and for deletions or duplications described only by genomic coordinates.", + "enum": [ + "Insertion", + "Deletion", + "Duplication", + "Tandem duplication", + "copy number loss", + "copy number gain", + "Inversion", + "Translocation", + "Complex" + ] + } + }, + "additionalProperties": false, + "oneOf": [ + { + "required": [ + "chromosomeCoordinates" + ] + }, + { + "required": [ + "hgvs" + ] } - } - }, - "clinvarSubmissionReleaseStatus": { - "type": "string", - "description": "\"hold until published\" allows a temporary hold on submission data being presented publicly. If no value is provided, the default is public.", - "enum": [ - "public", - "hold until published" ] }, - "submissionName": { - "type": "string", - "description": "Optional. The name for this submission. If not provided, it will be the submission id." - } - }, - "additionalProperties": false, - "anyOf": [ - { + "variantSetType": { + "type": "object", + "description": "A single variant that was classified; this is the most common type of set for variants in ClinVar. The interpreted variant must be described either by HGVS or by chromosome coordinates, but not both.", "required": [ - "clinvarSubmission" - ] + "variant" + ], + "properties": { + "variant": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "$ref": "#/definitions/variantType" + }, + "errors": { + "minItems": "Only allow exact one variant", + "maxItems": "Only allow exact one variant" + } + } + }, + "additionalProperties": false }, - { - "required": [ - "clinvarDeletion" - ] - } - ], - "definitions": { - "compoundHeterozygoteSetType": { + "haplotypeSetType": { "type": "object", - "description": "Complex variants on different chromosomes, affecting multiple polypeptide chains.", + "description": "A set of two or more variants on the same chromosome, typically in the same gene, that were classified together.", "required": [ "hgvs", - "variantSets" + "variants" ], "properties": { "hgvs": { "type": "string", - "description": "A single, valid HGVS expression" + "description": "A single, valid HGVS expression to describe the haplotype." }, - "variantSets": { + "starAlleleName": { + "type": "string", + "description": "The star allele name for the haplotype." + }, + "variants": { "type": "array", - "description": "Sets of variants grouped by chromosome", "minItems": 2, - "maxItems": 2, + "description": "List of variants that make up the haplotype", "items": { - "type": "object", - "properties": { - "variantSet": { - "$ref": "#/definitions/variantSetType" - } - }, - "additionalProperties": false + "$ref": "#/definitions/variantType" }, "errors": { - "minItems": "Only allow exactly two sets of variants.", - "maxItems": "Only allow exactly two sets of variants." + "minItems": "At least two variants are required." } } }, "additionalProperties": false }, - "conditionType": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "db": { - "type": "string", - "enum": [ - "OMIM", - "MedGen", - "Orphanet", - "MeSH", - "HP", - "MONDO" - ] - }, - "id": { - "type": "string", - "description": "The database identifier for the condition. Formats are:\nOMIM: the six digit OMIM number for the disease (not the gene), e.g. 300957; or the Phenotypic Series number including the PS prefix, e.g. PS200600\nMedGen: the MedGen UID, e.g. 751520.\nOrphanet: the Orphanet ID including the prefix, e.g. ORPHA71290\nMeSH: the MeSH ID, e.g. D009634\nHP: the HPO ID including the prefix, e.g. HP:0000815\nMondo: the Mondo ID including the prefix, e.g. MONDO:0100038\n" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false, - "oneOf": [ - { - "required": [ - "id", - "db" - ] - }, - { - "required": [ - "name" - ] - } - ] - }, - "errors": { - "minItems": "Empty condition not allowed" - } - }, - "diplotypeSetType": { + "haplotypeSingleVariantSetType": { "type": "object", - "description": "A genotype consisting of two haplotypes.", + "description": "A haplotype that is defined by a single variant; likely only expected for pharmacogenomic genes where a single variant may represent the haplotype across an entire gene.", "required": [ "hgvs", - "haplotypeSets" + "variants" ], "properties": { - "haplotypeSets": { - "type": "array", - "description": "A container for a combination of exactly two sets, which may be any combination of haplotypeSet and/or haplotypeSingleVariantSet", - "minItems": 2, - "maxItems": 2, - "items": { - "type": "object", - "properties": { - "haplotypeSet": { - "$ref": "#/definitions/haplotypeSetType" - }, - "haplotypeSingleVariantSet": { - "$ref": "#/definitions/haplotypeSingleVariantSetType" - } - }, - "additionalProperties": false - }, - "errors": { - "minItems": "Only allow exactly two sets of variants.", - "maxItems": "Only allow exactly two sets of variants." - } - }, "hgvs": { "type": "string", - "description": "A single, valid HGVS expression to describe the diplotype." + "description": "A single, valid HGVS expression to describe the haplotype." }, "starAlleleName": { "type": "string", - "description": "The star allele name for the diplotype" + "description": "Star allele name for haplotype." + }, + "variants": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "description": "The variant that makes up the haplotype", + "items": { + "$ref": "#/definitions/variantType" + }, + "errors": { + "minItems": "Only allow exact one variant", + "maxItems": "Only allow exact one variant" + } } }, "additionalProperties": false }, - "distinctChromosomesSetType": { + "phaseUnknownSetType": { "type": "object", - "description": "Linked variant data from more than one chromosome", + "description": "A set of two or more variants that were classified together, but the phasing has not been established", "required": [ "hgvs", "variants" @@ -671,12 +551,12 @@ "properties": { "hgvs": { "type": "string", - "description": "Set level HGVS" + "description": "A single, valid HGVS expression." }, "variants": { "type": "array", - "description": "The linked variants from more than one chromosome", "minItems": 2, + "description": "The linked variants with unknown phase", "items": { "$ref": "#/definitions/variantType" }, @@ -687,58 +567,9 @@ }, "additionalProperties": false }, - "drugResponseType": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "condition": { - "description": "The conditions for which the drug is used specified by database ID or name, but not both.", - "$ref": "#/definitions/conditionType" - }, - "db": { - "type": "string", - "enum": [ - "OMIM", - "MedGen", - "Orphanet", - "MeSH", - "HP", - "MONDO" - ] - }, - "drugName": { - "type": "string", - "description": "Name of the drug for which the response is evaluated." - }, - "id": { - "type": "string", - "description": "The MedGen UID for the drug response, e.g. 148193" - } - }, - "additionalProperties": false, - "oneOf": [ - { - "required": [ - "id", - "db" - ] - }, - { - "required": [ - "drugName" - ] - } - ] - }, - "errors": { - "minItems": "Empty drugResponse not allowed" - } - }, - "haplotypeSetType": { + "distinctChromosomesSetType": { "type": "object", - "description": "A set of two or more variants on the same chromosome, typically in the same gene, that were classified together.", + "description": "Linked variant data from more than one chromosome", "required": [ "hgvs", "variants" @@ -746,16 +577,12 @@ "properties": { "hgvs": { "type": "string", - "description": "A single, valid HGVS expression to describe the haplotype." - }, - "starAlleleName": { - "type": "string", - "description": "The star allele name for the haplotype." + "description": "Set level HGVS" }, "variants": { "type": "array", - "description": "List of variants that make up the haplotype", "minItems": 2, + "description": "The linked variants from more than one chromosome", "items": { "$ref": "#/definitions/variantType" }, @@ -766,274 +593,409 @@ }, "additionalProperties": false }, - "haplotypeSingleVariantSetType": { + "diplotypeSetType": { "type": "object", - "description": "A haplotype that is defined by a single variant; likely only expected for pharmacogenomic genes where a single variant may represent the haplotype across an entire gene.", + "description": "A genotype consisting of two haplotypes.", "required": [ "hgvs", - "variants" + "haplotypeSets" ], "properties": { "hgvs": { "type": "string", - "description": "A single, valid HGVS expression to describe the haplotype." - }, - "starAlleleName": { - "type": "string", - "description": "Star allele name for haplotype." + "description": "A single, valid HGVS expression to describe the diplotype." }, - "variants": { + "haplotypeSets": { "type": "array", - "description": "The variant that makes up the haplotype", - "minItems": 1, - "maxItems": 1, + "minItems": 2, + "maxItems": 2, + "description": "A container for a combination of exactly two sets, which may be any combination of haplotypeSet and/or haplotypeSingleVariantSet", "items": { - "$ref": "#/definitions/variantType" + "type": "object", + "properties": { + "haplotypeSet": { + "$ref": "#/definitions/haplotypeSetType" + }, + "haplotypeSingleVariantSet": { + "$ref": "#/definitions/haplotypeSingleVariantSetType" + } + }, + "additionalProperties": false }, "errors": { - "minItems": "Only allow exact one variant", - "maxItems": "Only allow exact one variant" + "minItems": "Only allow exactly two sets of variants.", + "maxItems": "Only allow exactly two sets of variants." } + }, + "starAlleleName": { + "type": "string", + "description": "The star allele name for the diplotype" } }, "additionalProperties": false }, - "phaseUnknownSetType": { + "compoundHeterozygoteSetType": { "type": "object", - "description": "A set of two or more variants that were classified together, but the phasing has not been established", + "description": "Complex variants on different chromosomes, affecting multiple polypeptide chains.", "required": [ "hgvs", - "variants" + "variantSets" ], "properties": { "hgvs": { "type": "string", - "description": "A single, valid HGVS expression." + "description": "A single, valid HGVS expression" }, - "variants": { + "variantSets": { "type": "array", - "description": "The linked variants with unknown phase", "minItems": 2, + "maxItems": 2, + "description": "Sets of variants grouped by chromosome", "items": { - "$ref": "#/definitions/variantType" + "type": "object", + "properties": { + "variantSet": { + "$ref": "#/definitions/variantSetType" + } + }, + "additionalProperties": false }, "errors": { - "minItems": "At least two variants are required." + "minItems": "Only allow exactly two sets of variants.", + "maxItems": "Only allow exactly two sets of variants." } } }, "additionalProperties": false }, - "variantSetType": { + "conditionType": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "db": { + "type": "string", + "enum": [ + "OMIM", + "MedGen", + "Orphanet", + "MeSH", + "HP", + "MONDO" + ] + }, + "id": { + "type": "string", + "description": "The database identifier for the condition. Formats are:\nOMIM: the six digit OMIM number for the disease (not the gene), e.g. 300957; or the Phenotypic Series number including the PS prefix, e.g. PS200600\nMedGen: the MedGen UID, e.g. 751520.\nOrphanet: the Orphanet ID including the prefix, e.g. ORPHA71290\nMeSH: the MeSH ID, e.g. D009634\nHP: the HPO ID including the prefix, e.g. HP:0000815\nMondo: the Mondo ID including the prefix, e.g. MONDO:0100038\n" + }, + "name": {"type": "string"} + }, + "additionalProperties": false, + "oneOf": [ + { + "required": [ + "id", + "db" + ] + }, + { + "required": ["name"] + } + ] + }, + "errors": {"minItems": "Empty condition not allowed"} + }, + "drugResponseType": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "db": { + "type": "string", + "enum": [ + "OMIM", + "MedGen", + "Orphanet", + "MeSH", + "HP", + "MONDO" + ] + }, + "id": { + "description": "The MedGen UID for the drug response, e.g. 148193", + "type": "string" + }, + "drugName": { + "description": "Name of the drug for which the response is evaluated.", + "type": "string" + }, + "condition": { + "description": "The conditions for which the drug is used specified by database ID or name, but not both.", + "$ref": "#/definitions/conditionType" + } + }, + "additionalProperties": false, + "oneOf": [ + { + "required": [ + "id", + "db" + ] + }, + { + "required": ["drugName"] + } + ] + }, + "errors": {"minItems": "Empty drugResponse not allowed"} + }, + "baseObservationType": { "type": "object", - "description": "A single variant that was classified; this is the most common type of set for variants in ClinVar. The interpreted variant must be described either by HGVS or by chromosome coordinates, but not both.", "required": [ - "variant" + "alleleOrigin", + "affectedStatus", + "collectionMethod" ], "properties": { - "variant": { - "type": "array", - "minItems": 1, - "maxItems": 1, - "items": { - "$ref": "#/definitions/variantType" - }, - "errors": { - "minItems": "Only allow exact one variant", - "maxItems": "Only allow exact one variant" - } - } - }, - "additionalProperties": false - }, - "variantType": { - "type": "object", - "description": "type of variant", - "properties": { - "chromosomeCoordinates": { + "affectedStatus": { + "type": "string", + "description": "Indicates whether or not the individual(s) in each observation were affected by the condition for the interpretation", + "enum": [ + "yes", + "no", + "unknown", + "not provided", + "not applicable" + ] + }, + "alleleOrigin": { + "type": "string", + "description": "The genetic origin of the variant for individuals in each aggregate observation. For de novo variants, please indicate 'de novo', not the origin of the chromosome.", + "enum": [ + "germline", + "somatic", + "de novo", + "unknown", + "inherited", + "maternal", + "paternal", + "biparental", + "not applicable" + ] + }, + "clinicalFeatures": { + "type": "array", + "minItems": 1, + "items": + { "type": "object", - "description": "The location of the variant in chromosome coordinates. Use only 1-based coordinates, not 0-based. For large variants (> 50 nt.), if the exact coordinates (to basepair resolution) of the variant call are known, provide only the start and stop coordinates. Otherwise, use outer_start (lower value) and inner_start (upper value) to define the interval in which the call begins. Likewise, use inner_stop (lower value) and outer_stop (upper value) to define the interval in which the call ends. If only the minimal region is known, use inner_start and inner_stop. If only the maximum region is known, use outer_start and outer_stop. You must provide either one set of coordinates (start and stop, outers only, or inners only) or two sets of coordinates (inners and outers).", + "description": "Clinical features that were observed by the submitter in an individual with the variant. More than one feature may be provided. Each clinical feature may be described by a database identifier or by a name, but not both. These fields are equivalent to the \"Clinical features\" column in the spreadsheet.", "properties": { - "accession": { - "type": "string", - "description": "The accession and version number for the chromosome, e.g. NC_000007.14." - }, - "alternateAllele": { - "type": "string", - "description": "The alternate allele for the submitted variant. This is used only for small variants (up to 50 nt.)" - }, - "assembly": { + "db": { "type": "string", - "description": "The genome assembly that was used to call the variant.", "enum": [ - "GRCh38", - "hg38", - "GRCh37", - "hg19", - "NCBI36", - "hg18" + "HP" ] }, - "chromosome": { + "id": { "type": "string", - "description": "The chromosome for the location of the variant. Values are 1-22, X, Y, and MT. If the location is pseudoautosomal, submit on X and ClinVar will calculate the Y location.", - "enum": [ - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", - "19", - "20", - "21", - "22", - "X", - "Y", - "MT" - ] - }, - "innerStart": { - "type": "integer", - "description": "Indicate imprecise locations for structural variants. This is used only for large variants (more than 50 nt.)", - "minimum": 0 - }, - "innerStop": { - "type": "integer", - "description": "Indicate imprecise locations for structural variants. This is used only for large variants (more than 50 nt.)", - "minimum": 0 - }, - "outerStart": { - "type": "integer", - "description": "Indicate imprecise locations for structural variants. This is used only for large variants (more than 50 nt.)", - "minimum": 0 + "description": "The HPO identifier including the prefix, e.g. HP:0000815" }, - "outerStop": { - "type": "integer", - "description": "Indicate imprecise locations for structural variants. This is used only for large variants (more than 50 nt.)", - "minimum": 0 + "name": { + "type": "string" }, - "referenceAllele": { + "clinicalFeaturesAffectedStatus": { "type": "string", - "description": "The reference allele for the submitted variant. This is used only for small variants (up to 50 nt.)" - }, - "start": { - "type": "integer", - "description": "The start location for the reference allele in chromosome coordinates. If only start is provided for the location, stop will be presumed to be the same coordinate.", - "minimum": 0 - }, - "stop": { - "type": "integer", - "description": "The stop location for the reference allele in chromosome coordinates. If only start is provided for the location, stop will be presumed to be the same coordinate.", - "minimum": 0 - }, - "variantLength": { - "type": "integer", - "description": "Required for structural variants if outer start/stop is provided but inner start/stop is not provided", - "minimum": 0 + "description": "To indicate whether each clinical feature was present, absent, or not tested in the individual(s) observed. ", + "enum": [ + "present", + "absent", + "not tested" + ] } }, + "required": [ + "clinicalFeaturesAffectedStatus" + ], "additionalProperties": false, - "anyOf": [ + "oneOf": [ { "required": [ - "assembly", - "chromosome" + "id", + "db" ] }, { "required": [ - "accession" + "name" ] } ] }, - "copyNumber": { + "errors": {"minItems": "Empty list of clinicalFeatures in observedIn not allowed"} + }, + "clinicalFeaturesComment": { "type": "string", - "description": "For copy number variants, both the reference copy number and the observed copy number can be provided. The observed copy number is a string, to allow for cases where the copy number is ambiguous and a range is provided, e.g. 3,4." + "description": "To provide a free text explanation of clinical features provided in the previous column, e.g. to describe the progression of disease or diagnosis. Please use this comment to expand on the information in 'clinicalFeatures'" }, - "gene": { + "collectionMethod": { + "type": "string", + "description": "The method used to collect the data for each observation, e.g. clinical testing or research. See https://www.ncbi.nlm.nih.gov/clinvar/docs/spreadsheet/#collection", + "enum": [ + "curation", + "literature only", + "reference population", + "provider interpretation", + "phenotyping only", + "case-control", + "clinical testing", + "in vitro", + "in vivo", + "research", + "not provided" + ] + }, + "numberOfIndividuals": { + "type": "integer", + "minimum": 0, + "description": "The total number of individuals with the variant observed by the submitter." + }, + "structVarMethodType": { + "type": "string", + "description": "The method and type of analysis used to identify a structural variant, i.e. any variant >50 nt, equivalent to \"Structural variant method/analysis type\" in the submission spreadsheet. Allowed values are enumerated in the schema. Although optional in the JSON, this field is required for variants that are >50 nt (and in scope for dbVar).", + "enum": [ + "SNP array", + "Oligo array", + "Read depth", + "Paired-end mapping", + "One end anchored assembly", + "Sequence alignment", + "Optical mapping", + "Curated,PCR" + ] + } + } + }, + "baseSubmissionType": { + "type": "object", + "title": "Common fields for differnet types of ClinVar variant submission", + "description": "Submissions to ClinVar are considered 'variant-level' (not case-level or patient-specific), because they are focused on the variant or set of variants that was interpreted. One of variantSet, haplotypeSet, haplotypeSingleVariantSet, phaseUnknownSet, distinctChromosomesSet, diplotypeSet, compoundHeterozygoteSet is required to define the variant or set of variants that was interpreted.", + "required": [ + "recordStatus" + ], + "oneOf": [ + {"required": ["variantSet"]}, + {"required": ["haplotypeSet"]}, + {"required": ["haplotypeSingleVariantSet"]}, + {"required": ["phaseUnknownSet"]}, + {"required": ["distinctChromosomesSet"]}, + {"required": ["diplotypeSet"]}, + {"required": ["compoundHeterozygoteSet"]} + ], + "properties": { + "clinvarAccession": { + "type": "string", + "description": "Required for updated records and for novel records if accession numbers were reserved. Provide the SCV number for your submitted record (not the RCV number), e.g. SCV000123456." + }, + "localID": { + "type": "string", + "description": "Optional, but highly recommended. The stable unique identifier your organization uses to identifiy this variant. This identifier will be public so should not include protected health information." + }, + "localKey": { + "type": "string", + "description": "Your unique local identifier for the variant-condition pair, equivalent to the Linking ID in the submission spreadsheet." + }, + "recordStatus": { + "type": "string", + "description": "If you include SCV accessions for 'clinvarAccession', you must indicate whether each record is novel (and accessions were reserved prior to submission) or is an update to an existing SCV record.", + "enum": [ + "novel", + "update" + ] + }, + "variantSet": { + "$ref": "#/definitions/variantSetType" + }, + "haplotypeSet": { + "$ref": "#/definitions/haplotypeSetType" + }, + "haplotypeSingleVariantSet": { + "$ref": "#/definitions/haplotypeSingleVariantSetType" + }, + "phaseUnknownSet": { + "$ref": "#/definitions/phaseUnknownSetType" + }, + "distinctChromosomesSet": { + "$ref": "#/definitions/distinctChromosomesSetType" + }, + "diplotypeSet": { + "$ref": "#/definitions/diplotypeSetType" + }, + "compoundHeterozygoteSet": { + "$ref": "#/definitions/compoundHeterozygoteSetType" + } + } + }, + "baseClassificationType": { + "type": "object", + "description": "common classification fields", + "properties": { + "citation": { "type": "array", "minItems": 1, - "items": { + "items": + { "type": "object", - "description": "Gene symbol should be provided only to indicate the gene-disease relationship supporting the variant interpretation. Gene symbol is not expected for CNVs or cytogenetic variants, except to make a statement that a specific gene within the variant has a relationship to the interpreted condition. Gene symbol can be provided as either the HGNC official symbol or as the NCBI Gene ID, but not both.", + "description": "Citations that were used by the submitter to evaluate the classification of the variant. More than one citation may be provided. Each citation can be provided as a database identifier, like a PubMed ID, or a URL, but not both.", "properties": { + "db": { + "type": "string", + "enum": [ + "PubMed", + "BookShelf", + "DOI", + "pmc" + ] + }, "id": { - "type": "integer", - "description": "NCBI Gene ID", - "minimum": 0 + "description": "The document identifier. Formats are: \nPubMed: the PubMed ID, digits only, e.g. 10862036\npmc: the PubMedCentral ID, digits only, e.g. 2746682\nDOI: the full DOI including prefix, forward slash, and suffix, e.g. 10.1038/gim.2015.30\nBookShelf: the Bookshelf ID including the prefix, e.g. NBK1384", + "type": "string" }, - "symbol": { - "type": "string", - "description": "HGNC official gene symbol." + "url": { + "type": "string" } }, "additionalProperties": false, "oneOf": [ { "required": [ + "db", "id" ] }, - { + { "required": [ - "symbol" + "url" ] + } ] - } + }, + "errors": {"minItems": "Empty list of citation in clinicalSignificance not allowed"} }, - "hgvs": { + "comment": { "type": "string", - "description": "A single, valid HGVS expression to describe the variant on a nucleotide sequence." + "description": "Optional, but highly encouraged. Free text describing the rationale for the classification." }, - "referenceCopyNumber": { - "type": "integer", - "description": "For copy number variants, both the reference copy number and the observed copy number can be provided. The reference copy number is an integer and is typically \"2\", as most genes and variants are on autosomes.", - "minimum": 0 - }, - "variantType": { + "dateLastEvaluated": { "type": "string", - "description": "The type of variant; provided for larger variants instead of reference and alternate alleles. Required for any variant for which the reference and alternate alleles are not specified. In practice, this will occur for structural variants and for deletions or duplications described only by genomic coordinates.", - "enum": [ - "Insertion", - "Deletion", - "Duplication", - "Tandem duplication", - "copy number loss", - "copy number gain", - "Inversion", - "Translocation", - "Complex" - ] + "pattern": "^[1-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]$", + "description": "The date that the classification was last evaluated by the submitter (not the date the phenotype of the patient was evaluated), equivalent to Date last evaluated in the submission spreadsheet. Use the format yyyy-mm-dd. If only month/year is known, use the first day of the month. If only year is known, use Jan. 1." } - }, - "additionalProperties": false, - "oneOf": [ - { - "required": [ - "chromosomeCoordinates" - ] - }, - { - "required": [ - "hgvs" - ] - } - ] + } } - } -} + }, + "additionalProperties": false +} \ No newline at end of file diff --git a/preClinVar/validate.py b/preClinVar/validate.py index c5c41ed..3786132 100644 --- a/preClinVar/validate.py +++ b/preClinVar/validate.py @@ -1,25 +1,21 @@ import json import logging +from typing import List, Tuple + +from jsonschema import Draft7Validator, validate -from jsonschema import Draft3Validator, validate from preClinVar.resources import subm_schema_path LOG = logging.getLogger("uvicorn.access") -def validate_submission(submission_dict): - """Validate a submission dictionary against the ClinVar submission schema - - Args: - submission_dict(dict): a dictionary corresponding to an API submission file - - Returns: - a tuple => False, [] or True, [error str, error str] - """ +def validate_submission(submission_dict: dict) -> Tuple[bool, List[str]]: + """Validate a submission dictionary against the ClinVar submission schema.""" errors = [] with open(subm_schema_path) as schema_file: schema = json.load(schema_file) - v = Draft3Validator(schema) + + v = Draft7Validator(schema) for error in sorted(v.iter_errors(submission_dict), key=str): errors.append(error.message) diff --git a/pyproject.toml b/pyproject.toml index ed6f145..ec78267 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ gunicorn = "^20.1.0" isort = "^5.10.1" black = "^22.6.0" python-multipart = "^0.0.7" -jsonschema = "^4.6.1" +jsonschema = "^4.21.1" responses = "^0.21.0" httpx = "^0.27.0" diff --git a/tests/test_main.py b/tests/test_main.py index 3ee37e2..8e3dc4d 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -3,8 +3,10 @@ import json from tempfile import NamedTemporaryFile +import pytest import responses from fastapi.testclient import TestClient + from preClinVar.__version__ import VERSION from preClinVar.constants import DRY_RUN_SUBMISSION_URL, VALIDATE_SUBMISSION_URL from preClinVar.demo import ( @@ -72,16 +74,16 @@ def test_csv_2_json_malformed_file(): # GIVEN a POST request to the endpoint with multipart-encoded files: # (https://requests.readthedocs.io/en/latest/user/advanced/#post-multiple-multipart-encoded-files) files = [ - ("files", (variants_hgvs_csv, open(variants_old_csv_path, "rb"))), + ("files", (variants_hgvs_csv, open(casedata_snv_csv_path, "rb"))), # files are switched ( "files", - (casedata_old_csv, open(variants_old_csv_path, "rb")), - ), # GIVEN that file is wrong (should be casedata_csv_path) + (casedata_snv_csv, open(variants_hgvs_csv_path, "rb")), + ), ] response = client.post("/csv_2_json", files=files) # THEN the endpoint should return error assert response.status_code == 400 - assert "Created json file contains validation errors" in response.json()["message"] + assert response.json()["message"] def test_csv_2_json_old_format(): @@ -110,7 +112,8 @@ def test_csv_2_json_old_format(): def test_tsv_2_json_old_format(): """Test the function that sends a request to the app to convert 2 tab separated cvs files (CaseData.tsv, Variant.tsv) - into one json API submission object. Variant.tsv file in old format contains assertion criteria fields""" + into one json API submission object. Variant.tsv file in old format contains assertion criteria fields + """ # GIVEN Variant.csv and CaseData.csv temporary files based on the demo CSV files, but are tab-separated with NamedTemporaryFile( @@ -184,7 +187,10 @@ def test_csv_2_json_SV_breakpoints(): # GIVEN a POST request to the endpoint with multipart-encoded files: # (https://requests.readthedocs.io/en/latest/user/advanced/#post-multiple-multipart-encoded-files) files = [ - ("files", (variants_sv_breakpoints_csv, open(variants_sv_breakpoints_csv_path, "rb"))), + ( + "files", + (variants_sv_breakpoints_csv, open(variants_sv_breakpoints_csv_path, "rb")), + ), ("files", (casedata_sv_csv, open(casedata_sv_csv_path, "rb"))), ] @@ -214,7 +220,13 @@ def test_csv_2_json_SV_range_coords(): # GIVEN a POST request to the endpoint with multipart-encoded files: # (https://requests.readthedocs.io/en/latest/user/advanced/#post-multiple-multipart-encoded-files) files = [ - ("files", (variants_sv_range_coords_csv, open(variants_sv_range_coords_csv_path, "rb"))), + ( + "files", + ( + variants_sv_range_coords_csv, + open(variants_sv_range_coords_csv_path, "rb"), + ), + ), ("files", (casedata_sv_csv, open(casedata_sv_csv_path, "rb"))), ] @@ -231,7 +243,14 @@ def test_csv_2_json_SV_range_coords(): subm_coords = json_resp["clinvarSubmission"][0]["variantSet"]["variant"][0][ "chromosomeCoordinates" ] - for item in ["assembly", "chromosome", "innerStart", "innerStop", "outerStart", "outerStop"]: + for item in [ + "assembly", + "chromosome", + "innerStart", + "innerStop", + "outerStart", + "outerStop", + ]: assert item in subm_coords assert json_resp["clinvarSubmission"][0]["variantSet"]["variant"][0]["variantType"] assert json_resp["clinvarSubmission"][0]["variantSet"]["variant"][0]["referenceCopyNumber"] diff --git a/tests/test_validate.py b/tests/test_validate.py new file mode 100644 index 0000000..8e3b5d2 --- /dev/null +++ b/tests/test_validate.py @@ -0,0 +1,15 @@ +import json +from preClinVar.validate import validate_submission +from preClinVar.demo import subm_json_path + + +def test_validate_submission(): + """Test the function that validates a json submission against the ClinVar API submission schema,""" + + # GIVEN a valid json file + assert json.load(open(subm_json_path)) + + # THEN the submission should be validated and return no errors when validated against the ClinVar Schema + with open(subm_json_path) as json_file: + submission_dict = json.load(json_file) + assert validate_submission(submission_dict=submission_dict) == (True, [])