diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index 9fc5654..3b87ef1 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -4,7 +4,7 @@ name: Generate on: push: branches-ignore: - - main + - '**' workflow_dispatch: {} jobs: diff --git a/package-lock.json b/package-lock.json index df68a02..cfd49e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "@seamapi/python", "devDependencies": { - "@seamapi/nextlove-sdk-generator": "1.11.0", + "@seamapi/nextlove-sdk-generator": "1.11.1", "@seamapi/types": "1.172.0", "del": "^7.1.0", "prettier": "^3.2.5" @@ -416,9 +416,9 @@ } }, "node_modules/@seamapi/nextlove-sdk-generator": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@seamapi/nextlove-sdk-generator/-/nextlove-sdk-generator-1.11.0.tgz", - "integrity": "sha512-eaBaTri2n961aLr32DU36iM4rMjpBIyikJe5yk1aueol96Ks5tIFtIh+T4XZvEU6IWwSI1aG43MQFeocLKSOXA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@seamapi/nextlove-sdk-generator/-/nextlove-sdk-generator-1.11.1.tgz", + "integrity": "sha512-Na6ZTUMecOBA8UEqWSITiHfI7k+tUadqK3CVaThmqrKZ+OtHsQZS0zbN/oBUWpzY3SmjhQ7woxL8RELafNkOEg==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index d85a577..aaed178 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "format": "prettier --write --ignore-path .gitignore ." }, "devDependencies": { - "@seamapi/nextlove-sdk-generator": "1.11.0", + "@seamapi/nextlove-sdk-generator": "1.11.1", "@seamapi/types": "1.172.0", "del": "^7.1.0", "prettier": "^3.2.5" diff --git a/poetry.lock b/poetry.lock index 3f3b685..3516b8a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "annotated-types" @@ -71,17 +71,6 @@ d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] -[[package]] -name = "certifi" -version = "2024.2.2" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, -] - [[package]] name = "charset-normalizer" version = "3.3.2" @@ -338,15 +327,26 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + [[package]] name = "idna" -version = "3.6" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] @@ -374,6 +374,94 @@ files = [ [package.extras] colors = ["colorama (>=0.4.6)"] +[[package]] +name = "jh2" +version = "5.0.3" +description = "HTTP/2 State-Machine based protocol implementation" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jh2-5.0.3-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:764acdd572413198eb7a1299d08d32b0819c33220604f76ba7ea722443c3b929"}, + {file = "jh2-5.0.3-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:f83bdbbae9fac7766e2edcac9a275af5a70e8e7188296c84cbeb552e1f1f2e8d"}, + {file = "jh2-5.0.3-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:a921112bbafaea4d5ef9e2a25f03cacdaa1795b6a961f0fe430b8de15b939b3a"}, + {file = "jh2-5.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18cdf52edf8e636f3a4a74d92eb62bc6692a2c78e288b0724341c82b078bb261"}, + {file = "jh2-5.0.3-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ccb5fc490722b5ca0966a2402ae90a7bc70ec8a4a9bce224948db211f5fa2a9"}, + {file = "jh2-5.0.3-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7c7dcecef260a792da2b7653011d09bcad5e1455e38fd194ee07fcb01a803fc3"}, + {file = "jh2-5.0.3-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aa0af8f8a1a27dc7e166840fbdda46abc673d5cd8e2319ac08a3c7d5e9e9920"}, + {file = "jh2-5.0.3-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78228b1a255581e93144d52feda6e8605fcfbfae7aa289def8879a7be6ca8a74"}, + {file = "jh2-5.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2be4f69c7c8d87d28948065a038d84555a0784acf3886e9c18707f34ceb7c1b"}, + {file = "jh2-5.0.3-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f83206f4e18d4836ec9de573c9c0c27c02e277b59685d9d490f7187968b780fa"}, + {file = "jh2-5.0.3-cp37-abi3-musllinux_1_1_armv7l.whl", hash = "sha256:be4e8c8ccb401cbd6386a406c21a87f690d68f1fdcc1698dcc813429bf5a9ce3"}, + {file = "jh2-5.0.3-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:b6facef13abe549d70fd722ab668fae822cfdcade6199a12e7ec06fe0ba44326"}, + {file = "jh2-5.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:3d2e48899378c3026d3640f1be1a043038af74f4076f1fb0c1b7bc13fb9c0619"}, + {file = "jh2-5.0.3-cp37-abi3-win_arm64.whl", hash = "sha256:2faaf1792220ffd5dcae8e88dd8f3b2b72771589121dbabc92fb503f488021c2"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:72db414df9a49a3498b7e083002cd9a3eefc4bce33789d7ae31d0e1c92229f0e"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6fa5629d6e18c6be93cc17da6b31a21511405e443df0a6936a0795807bf949f2"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a5d5326a15eed6b4dd64598522b741b65168093705e4276f964627ada3281f48"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af39530c7173dd41383ac9910164695768418bd5910bc1e8e628383d82656881"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c091dd40414b028793d3867968842a55c09e26bcbbba76e6daf8080b47384fd"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9e4b981ddce810d7a691f535c150212bef8a70c61081007c13b19ab30e44409b"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57f8d46fac15bbe1fe6c576b00ef2aaf616c359cc2fb8a468d46b05e19495bf5"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7b3476e3f13ce6751a45a82861a5fd64b38ef166c40974d0c97a0762293e12"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498a7e463f2be67ec1085833e99582bcb1e3ea1c2933f640f7c4896e307673eb"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:37e9d6f59e2c305f33793ea24fb588300828a83f9f51d47671e8335fc49a59e0"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:09b89d2700e9530f13b10dd1b8cb0e5389e3da833b6aa7d0bef74ef39229c7ba"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:a68cf6e7baf185f831b3eccdbfe91b7d48ad6af78b4b929d6df89d92d9a4ca62"}, + {file = "jh2-5.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7669f95cfac416a3e97b224d214c9838bb5b6b9e35a1892637337fe774d0406b"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:af5560b7856c6a1e17071d86e16e288f6ca3f465a29fd683347f84cf4ad8a99b"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:769f569fd7dfbe027ddf28c5c73dda48494bb3ffef0be6f60d5661fa6c754da9"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-macosx_11_0_arm64.whl", hash = "sha256:48befaf5dd60aa3b623e8cfafdb097516820f9b5c2ae38d399b6e4eed1cfdb46"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac6259ba5591120b3663089ac1ba9a521249794d753343c59447808b744e2755"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dc1f2442d6eb9ab8f54d328ec938918ca273290d1e99329387967dd74e1b054e"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:557c40acd62c51001cdad2674c5a9d400127796ce7fbe8d82698ff8bec478092"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0e175649572bc2a7c60a7e03d8bd1d42d0f64634d31d0d7930b65e1b31f8e43d"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0125bbc6d41bd55f088e952fbfec0652eb0ac45632604d6644c45e2ccb83507b"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ecdf049246a0bc01bd404737b1506770577e982802872539f7734368877623a"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:70a401591577502f3efb2fb247378fa5a0adfd48578e15f7365d6db656447e66"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3ba6a00394c6cb5d1409fbb910eba2ff2a216bb553af198ccc8f64af63133f67"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:4eb16b0f95181c7bb19115446b5987b694727c6afd618ee900e895a54d101188"}, + {file = "jh2-5.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:e967d4a1bdb7a8726e0349dea82eba530dbed8fed4cad118f81e867f84c0446e"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:2fcc906639e5987ee0eacb12ba5a7678ac76677986dbeeb41dc7d1b44926ac43"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:39dbcd14e8313370c83287080ddac77a42cace50ef223852d6b0bea73df8ac3e"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0ceddd1be2a9153d5eec25ac3aca846f35bc171325e549509cac75ecd26930d"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8aa14f5b3077526fed01464e4400860c9f88f73b0499f87e50e4cbf0d851def"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:89cec07a5e15660c10c29537d6df2b61daf9673cbd014971664b50d3c5eedc34"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:fc81fe2ef8a2c011a67468a169790973d0595731599c7c21d0d223b29c886d43"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:024862bbaa795549823386bc30b0bb7c1807df5df75b4e5ce97f216812796fca"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7417bd01c897c5afe9da8270ca4fc0485378a05bee0d4c0ad435c48aee841ad"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f67738cb9e669c3b28ab1f7c611df0c3e5cb6da06df5a7f303e8510b890764a"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fa6d7060c225d2f1c888ecb8e834a4685d4468fe11968d56a5eb3376e45d287c"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:32f0700ecca8707b9561328705efa9ad1626ca829b2c4964e753d579337d53c2"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:969f62d321bd82207be836f99bbbb854ec5596ca82a2c905c404fed5e4a9289c"}, + {file = "jh2-5.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:1d1194a66b25fea05f34e0bd1cf5ffc72ec67fd3e584d4c1293e9962815ec180"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:b1b47bba88666287ad998dd561292dbe38ad767072a4ecdfe90a98f2f2e95579"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:97a57f39f6fbfb96966edf0d6879afed5784582573644cd5c2f58907f6e45759"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0ab31da34be3c726acda1eed2fd9ad9daf14f4f45bb15fdce7ed877ce82f677"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:090755e41a0c0b7021dfdfda46970e3920d6524a528d0456a0759310b2cd3a30"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e8903186182de97107260540796f6579b7322cb82d7d3e8aca11fd09c2847fe"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:85714f220fbd7ab7d17ab83cbbdac4d43e0fc699738da06b018a9aa01adad5f0"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d59abb4b1adfd9e7f0b6df22f4f6ea260128d7605110a39bab29dbed32a5ab28"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe75dbd44d1c53341acd5505afd29af8172e7ce67a7d21fd4466d7db26be3766"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c58aafe13f208769f16fa612095a64aed27b35a241eaffcef10c105b5c48c03"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:83fa9a815edbe52b6c0c096a20c1bb3f9669b706e8a69775dae63c973a60b2ea"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:b4d6d2e8a14526951b15cbeaae89625838570affb429ab90df32b6a34a7d417b"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ea555676ce7eb72d5be9b5107286c83c72cc12bf7dbdcc9d2381672451c077a4"}, + {file = "jh2-5.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ac1e1db4a92fa1b4625e57de2ad36b6376dfcc53be6298afbd82ee96f172d80f"}, + {file = "jh2-5.0.3-py3-none-any.whl", hash = "sha256:4ac75f013a1600d8111306fa5d3b35ce08bbbd8fde2aca096a0ddf6a415e999f"}, + {file = "jh2-5.0.3.tar.gz", hash = "sha256:c13d97a3f82a02e6a2a89606f1ffe1771670266dc7746140e00e66c4dad12b14"}, +] + +[[package]] +name = "kiss-headers" +version = "2.4.3" +description = "Object-oriented HTTP and IMAP (structured) headers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "kiss_headers-2.4.3-py3-none-any.whl", hash = "sha256:9d800b77532068e8748be9f96f30eaeb547cdc5345e4689ddf07b77071256239"}, + {file = "kiss_headers-2.4.3.tar.gz", hash = "sha256:70c689ce167ac83146f094ea916b40a3767d67c2e05a4cb95b0fd2e33bf243f1"}, +] + [[package]] name = "markdown-it-py" version = "3.0.0" @@ -450,6 +538,30 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "niquests" +version = "3.6.4" +description = "Niquests is a simple, yet elegant, HTTP library. It is a drop-in replacement for Requests, which is under feature freeze." +optional = false +python-versions = ">=3.7" +files = [ + {file = "niquests-3.6.4-py3-none-any.whl", hash = "sha256:fd26b1e4d757f3cce4200cc2a540d99b46d8c3c0129c0ce23b86b52b1a96d7a4"}, + {file = "niquests-3.6.4.tar.gz", hash = "sha256:275095fe027c5112bf8cc7b9c93fb09cf2221b0d22875f05d06493235b9e7a75"}, +] + +[package.dependencies] +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +kiss-headers = ">=2,<4" +urllib3-future = ">=2.7.905,<3" +wassima = ">=1.0.1,<2" + +[package.extras] +http3 = ["urllib3-future[qh3]"] +ocsp = ["urllib3-future[qh3]"] +socks = ["urllib3-future[socks]"] +speedups = ["orjson (>=3,<4)", "urllib3-future[brotli,zstd]"] + [[package]] name = "packaging" version = "24.0" @@ -643,8 +755,8 @@ astroid = ">=3.1.0,<=3.2.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" @@ -729,26 +841,80 @@ pytest = ">=2.6.4" watchdog = ">=0.6.0" [[package]] -name = "requests" -version = "2.31.0" -description = "Python HTTP for Humans." +name = "qh3" +version = "1.0.7" +description = "A lightway and fast implementation of QUIC and HTTP/3" optional = false python-versions = ">=3.7" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "qh3-1.0.7-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:392cbfc95c832f78b840a5b17d743d4dcf8d47d7217d17370b939a8717939fa6"}, + {file = "qh3-1.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:75bea34952369975a646379aa2b6438f557b4da7a76ddb59973000d96ea8063e"}, + {file = "qh3-1.0.7-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:9d40552d28eaa89c819edfc3bc3752ed3d7da59119840d8fe09790b9c76f5819"}, + {file = "qh3-1.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f1283bbab24b26565fb9b90278ea96c7940396d31ee9fac169e9c7e1b36fd96"}, + {file = "qh3-1.0.7-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0f7f910a1523b1d2f16e20034452b63335f90431868365bee0fe29d8e6473438"}, + {file = "qh3-1.0.7-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:92d87664b758bc1f8b4bcfa60cce866c1e96938d59af3de25189661e263cc510"}, + {file = "qh3-1.0.7-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6f56c34e8d7009596a61a800c80f478a9e9ceccfdc11b28544b59ad904a5ff6"}, + {file = "qh3-1.0.7-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4da2ba491c7fb240556a996b0a10cf7b6ce17816a9c2a53a02b08a40eb2fa37"}, + {file = "qh3-1.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586cfd89068fd44e5471b31bd7d4c4b01b80a85ac28e26b14da6ede4583e8017"}, + {file = "qh3-1.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:1835f149b1d359a9de915207bc0543004edcb3077390614bca5d52c637914ad3"}, + {file = "qh3-1.0.7-cp37-abi3-musllinux_1_1_armv7l.whl", hash = "sha256:1e7618c6059a5f838b858ea834ef6bc66d1e95bdeb8ea466217d74aedf471415"}, + {file = "qh3-1.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ebf612690cfefc66d19648f67bd0a7a83112230c322e21245a5536ca05aa9564"}, + {file = "qh3-1.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:7ef77f2663f60ac3b46fc13ad67076dcff8dfe37886c1793fa7411c50385b061"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4fb6c73399313881b80708354af6ac5d837cf9733189476f919d7c9b88e5ccba"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4bbd1a4a5b49cbcfd02a57b07eab729cec7b4a75f2180a03fa0d200d46833cbb"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:0ccbcf47a1311deece090ac6c83918741be4b568f7018748d3f3762c70a45c3c"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6e5871df72c6303e9c68e8ab50d25152fc4d4ee0d8ebdced20724922fbaeb53"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:981725de5210eb8f902fa5015b029072a532c4dd44770bc6d2b45b569b91212a"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4018dc5023738b4da756297787e6606a771777b576d61da95226c2ec0d5d50ef"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:debbcd38adf35bb2589095f78ef59690f507b1fd6aa71440c80ad17a15485fbc"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c83a719c48dbd3d8d592193e83360c11657a5c1bda31e519a8b8d7b1f60ae627"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6487edea20ac7bea0e820bafb9bd4957d80a341facd7d64163953adcf560bf95"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e70de70904cca4f53dec7ddbc15e8d2fe0e4cad01c05063cddb1087460a367a"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8e03f81f60ef0772e2a32e3e56fbcc907f111f4057909fbb013e2f65516b5799"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:89ece443484baff18ce12d08cbcf5fa8bcfbfbc6517e1f2e020666c6adf003e9"}, + {file = "qh3-1.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0ce94a6fbd6bd2715e66d28560af8c41bd99bd419bb89abc45f761932dc8cb54"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:6c8b427f31c486fc63898ec15b5d12636f29d09275e186da5cacbf4296143e7d"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:8bf1b4f50639ee5277e4baef3740c4790f59760c4a537cef9e8096b2c7c2ca69"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-macosx_11_0_arm64.whl", hash = "sha256:acb42fc6d6251ee9af39a4330c9fe3a4958517b76ee7f4c66787a8b099bdf0f4"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5a807d4bac257e1e68e690464444361320ce730f68d8d1821a1e70a3cd795cf"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1d51d9402d5544540363424cfe9c06f7c1e7e0b1bfaaa7128e5034d27a0f2cef"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:fbcb8a29285b8a9d1587948b30f2520bc564d0341f860c2fc57a5d53a77a2e23"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0753e77e9bbb6140c05adb3fbd19dbba6b2f5f27598e608e2a543165ede4b337"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25a1e9a27efd7fe55e521f4f68b9bc7a4ef6b1a0f51cb8a98134fcf6e9bec6ab"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f6ad8a4c31b5579b65482172e7e7f945ec7b29030046ce29d7fce396246fbb7"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:43911c6f206ac2654b857bef14dda7394509f9746f145ccb4e496f32a9d67422"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:bda728efcf03e49ec16d1f0a8d3953fcc113df5d3055b63c838d7dc7834c357e"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:03f7ea1cedacbfe6252f202ac65d0040a8942ce627df241bf74a0f2ad7c4a73f"}, + {file = "qh3-1.0.7-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:5f82a48b9c06b51ab482fedd4b0476b0c0ce0f4a0d47c5fef924adc8cd795a89"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:091247b9bb24e6abb055772a502ea70857e7dabdf1dd993053db680c7bdd3718"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c73458b6a79652a63a64b715d8047f07d7f61ab091a87f32c2303f9cb9d77bbd"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:733553159d65b447bf7c7aa84cde6b158e057025b602192c43b41083f3e06b4a"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308154b300b28436a415f2163b942e0c809f8cbeede1a940be563d64462e35b2"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5db32a2a9ea4210bb5a3c6c037e02d11f6709be38e077eee77cdf0e626dc7f7"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:57d3013bb1f03cf1a2c8a1bb7d536722eaa059c58d3f6918fc5b62f8469d4f6c"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaca92cfbaabf2a8792325243e63cf7512c4760aed2371a5fc9ce32612245bfe"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7da2e218fed81602d4f1034cd9698afee2c56270b1520cfde09e14d47dbdb2d2"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04a0005c4ccf5d9510491d5e731021af1f764c23e2bb456f3b5674311a126e90"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:15b54ed14df131266e65d7ef09b7bb3f1fb4d74d4fb632b51d233c58be050368"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:bf675b50dbf971d21e8fc4ccf6fc18c77942f6ac20358ac6ca3a98857e467f42"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:a438f7cb5923ec519c3a1bd4e8db67067abe5d1d3d0499bffd19213b52ee654f"}, + {file = "qh3-1.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:53ccddf58ea50250609da3753977ad501783fa0cf2dc15960add5c15e2313b47"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:168bd4f481c6b7f780e4f46f399d6c7faadebe4227b5130d0d7c335d10dc13e3"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:188ef7bd33b1b85af93058ce365ff7b65377a99580fdc37bf9d18de98ac90ebd"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:63407c2c680ac4a713f502a23658e9e26818133312b78765bb5efe21978feb02"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:703775328761d10a6ba2e412a6c44304e28b4d05799765496c7a21569ac7f732"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ffe51161a782c99cfe792100af43f8577ac3f9fcc247e80a860981cd8e4bc8f7"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:567a2a76b2c5ef42a2c9adef9596c8ebbdb614660363bcd020096ea38969bede"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9aa47c11d2d4c2ed75506333fd83c481017f6da7f45002e24e391842d8dc989a"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67433e71e5bf6a76f41f1bde9c69aaf017ae3b4ae5e9f3e4a123a45619dc5783"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2569550be0faa50e723a1bbf3a9061b66a7546d514fea81bb9125e16f6a7d37"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a5aea4ed5b8880210aa34957c33b4c576b2e68b9cbc48013974d34a41d71d17f"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:be0675ced825a4a659888541060031621b575a99bee4efc1e435ffa7815a696d"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ecf9eb27fcbbd9c8cf4a374c5e0d034ec0c3e576f1ed028f7ce84a3484fb06fa"}, + {file = "qh3-1.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:89f00a47cef7197ea6367bb0a1ecb9517aeaf8c8dd26202cfbf3e3346d0f4aeb"}, + {file = "qh3-1.0.7.tar.gz", hash = "sha256:eb527d8317746209509b9c575527577cdc9b3cfb0f49294fc1cd109b0570362c"}, ] -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - [[package]] name = "rich" version = "13.7.1" @@ -924,22 +1090,114 @@ mypy-extensions = ">=0.3.0" typing-extensions = ">=3.7.4" [[package]] -name = "urllib3" -version = "2.2.1" -description = "HTTP library with thread-safe connection pooling, file post, and more." +name = "urllib3-future" +version = "2.7.908" +description = "urllib3.future is a powerful HTTP 1.1, 2, and 3 client with both sync and async interfaces" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3_future-2.7.908-py3-none-any.whl", hash = "sha256:c35af8521f5a833b3664c6574893a30e73608d3e070e920296400ab698a60b4c"}, + {file = "urllib3_future-2.7.908.tar.gz", hash = "sha256:2ab62b2a20dcf66cb5e02f0454c81cf5858f6e7064d7760dc19bedcbbd7523be"}, ] +[package.dependencies] +h11 = ">=0.11.0,<1.0.0" +jh2 = ">=5.0.3,<6.0.0" +qh3 = {version = ">=1.0.3,<2.0.0", markers = "(platform_system == \"Darwin\" or platform_system == \"Windows\" or platform_system == \"Linux\") and (platform_machine == \"x86_64\" or platform_machine == \"s390x\" or platform_machine == \"aarch64\" or platform_machine == \"armv7l\" or platform_machine == \"ppc64le\" or platform_machine == \"ppc64\" or platform_machine == \"AMD64\" or platform_machine == \"arm64\") and (platform_python_implementation == \"CPython\" or (platform_python_implementation == \"PyPy\" and python_version < \"3.11\"))"} + [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +qh3 = ["qh3 (>=1.0.3,<2.0.0)"] +socks = ["python-socks (>=2.0,<3.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "wassima" +version = "1.1.1" +description = "Access your OS root certificates with the atmost ease" +optional = false +python-versions = ">=3.7" +files = [ + {file = "wassima-1.1.1-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:1f6f5198ddb3d68d7b6fe9229c55a2c83cb56232b72dcdd4b2ebc7540138aa20"}, + {file = "wassima-1.1.1-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:583e9e510cb88f067e9a48b39ac58549a258623d1e07eb6bb0512280a10c0e8f"}, + {file = "wassima-1.1.1-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:59c73287561dcbd0102ff897b136af0ef5e5879192f0908c597d85b8269701b0"}, + {file = "wassima-1.1.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50afde20c335c18c39a47ff9c9d1c481864275e6ec1fb50b23ff4d693428b4fd"}, + {file = "wassima-1.1.1-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2edfdc6ec4f07a35fd4b84c2b282f856062a832ced48eddce1a44c82525f275"}, + {file = "wassima-1.1.1-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f41980d3d83bc446e28822c2f4a395f787814273f623811e4ed1035dfde7b267"}, + {file = "wassima-1.1.1-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a04100cdd5ad8f7d1e85b1b679bc7b5db95c788d24aed6e8b63a8ad47fccf62e"}, + {file = "wassima-1.1.1-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af205bfad17f814a05341bc1889ff61c40f44b37139c58c9c47aa593e83e2f"}, + {file = "wassima-1.1.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdba17f5d0844468c8bb7b5103505985bdedcad5dd90cd722475386f115332d2"}, + {file = "wassima-1.1.1-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:32bca7ed733a94c32d6c78d10c902dd4dc2dcf5785b560d82915de1544e076ce"}, + {file = "wassima-1.1.1-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ae474c2458addbe1b657ee080dc73a52ef002504c055f71176a246aecf2b714f"}, + {file = "wassima-1.1.1-cp37-abi3-musllinux_1_1_armv7l.whl", hash = "sha256:c2baa1316b40044caecb9fd5f574527784673b809515668bb7d9631c29f03d39"}, + {file = "wassima-1.1.1-cp37-abi3-musllinux_1_1_i686.whl", hash = "sha256:bc2d94894c6c270787b010b12243ce4a2ffe6a62b1f5682c912ea4540fe5d6df"}, + {file = "wassima-1.1.1-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:8f81f8dc770e7988321003776b2d3fff65339de4216e6f9b39d831333390c728"}, + {file = "wassima-1.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:878ae83bb9130b0c86426fc7682b397e6c8fd7a0457c277485e96b792f7f12b1"}, + {file = "wassima-1.1.1-cp37-abi3-win_arm64.whl", hash = "sha256:491d0541b5995618efc85c9b249f1a9fa33744973e42bd523bf52c01adcd078e"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:84a1607d508024febacc192414797daa0bce64bbf24e7ae93e182aecadaf200a"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a63866dec44e5d0ef9606b43a33d3017d0de7d931a128a3d1b0c28ad5714e8ce"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:85244bda65f8a39ad700aa941f1f0123f588933c79afbb4f65f600fa6c83863d"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:665f0b4a424b56e907bd579d8144b339f1383a6dd53bd4ebdd6b6f2653cd6d3e"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:41630a1f13b356f19cda2ab406ca93185a426fc65ba608d58000c125f07cdf2e"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:028f07252188a7b6a1e73c955959b3028d6f5633e798eb6b27ee96716c62ab31"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec076533caed061bdec324b0536bf01b704edf4a6bfd022462bc64233d9660e2"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c99e98dd7960d7dd7342f5fa569a4cfcd5e9333f74f1a9115a483fa6c03a5f8"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1aa554e79832c8f94fbedc77a53ff4207cfce45ebd0c3a550d6c0eb8fbd82118"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7cac5cc91a6dc12b675c6749e5e0a36f35b4976dd37df36d50246fd8c3707866"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2763d8f5cc58c4a9ee986c39709d3af91a9dc215c8a8895b992783a828a35824"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8d2d8cbec28a9f810207ca2647a0cf6c674b95162f2269d35846421d5948a1e6"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-musllinux_1_1_i686.whl", hash = "sha256:0353ba99c1db703902d084a81875ed3e06a3831f3eb039240607198e8f6bbb5c"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:95d1b7144286c090b943fc42711da922384f7e4e629a5dd2e8f05b66d008cf76"}, + {file = "wassima-1.1.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bdb76ee185736ed98ed92b8200b380b732b4e3df08219ea9491c6c7c9a983778"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:1f7d14d3019f179b5747168282fcd4c0cc3a2363eb974bcbc532b546a4513c24"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e26e96df5d5358f093314ac162aed33ae3c04d80e9bdd1c1c2cd07c8e0109f36"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-macosx_11_0_arm64.whl", hash = "sha256:18857ddbc6d257541027ffc59dc6e87c21bf0ba5a10abde5073d01cec0352faf"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86fc536580e31c81717212751fab16ff962f16302f71a71a2786a4c743ac1e1a"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f2ce27271a38fd21e2dc3cc5167431a63473ebeec1c02975e4000c95d04e35a9"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4ed19ff2afc209ea837fefbfe9eec01eaa6b8af46fe8dbdb8a692a894646013b"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c08969d10347b71b25c31e9ce73416002ff9d27fa22aa1e652ecd8cffda0a92"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c24eea8459388db8ec524c32eca1e06fff2ea274b2ca92431f5a9a5b05b4b6e6"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cb04b797b1cc0504d0c34625b1e939c236e001a73db0615825c0b1f9b926992"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e289c87ef4a738593bc0ce455c564e1c17d4acffab27d010751cd60b47c235cd"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:797200152716971b9d7f06bf1bcc3767b2998afa73bb1515c3bdc7828e70a711"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0b080a60c5019dcd11e4dd2870479a1876d09c1caa2f1d2cfb9645a10e7880b8"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-musllinux_1_1_i686.whl", hash = "sha256:b870df6e1166b86522298d5a3d945ce65743be2d16586b9d2eabbb49ec7dbf2c"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:14d8395e06d0db4a54f99058bf00818420d4cfda8fbcc48b56e8ca73d5f2551a"}, + {file = "wassima-1.1.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:5166da190adff31bdc432d4675e75945e88341a2334e5420a50f0f9758fb55b9"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:dfe2cc6069aa074f2262ef128ad31d4212d850ea3c5c793525ed93a29b356658"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:829c11682c5ef7a90bc248a56ef50ef1290335b554626c1221f8a8c244d69cbb"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:e22c247574d35c2f450ede7662e630d9fd07e2230434aea142afd3cf819a3f3b"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e996e4772a41edffcce071360bcc2359deae3e6dd23ad1b101f4bb5168e7d0c6"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:49cf2bc1f7e4cd622600bfbbb709320d5b60469dfaeef5493cc464771ffd027a"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8866a5f401b790f47fb084227e6c8576c25f48b1e50161a50705d603b67147cb"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9ab2757fdbf1ea4c6623c575866b8c6c0ea1c8c99470e2e3c67ffae63f73f85"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9a45b6986634634404da64c34386a71130666ac930e9a84be4050b8777ba8b9d"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:890121a09213b98755eab091c72d9e2fdfe7f659d153051dc8a8adeef366e36f"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:36194a67632b472f455a36b89efff7b9e1b521df4d24a3ba2789b2bb322ac81e"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:856ffd4b95ae31518e7c7109796feef27801da79c40ee1c75f166c9655934cd2"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:6b0142f9121095b5807159621d6c37cf1defb409a6cd245d0f496d40072f67c1"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-musllinux_1_1_i686.whl", hash = "sha256:0612efb6f2e9339a3748fa8dc622f0be5f71b95b4471e1c1fbf5006a7e98a060"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:18cdae934705ec6a8df947f25c5230d6da812717ac23b5f51ad570c63bf7e3d7"}, + {file = "wassima-1.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:21e87777709d5c7d60503c589deef6a214ff8b94fa3e75ad5ff19518aeb0d4b1"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3565a0a206003acfa9eade388c7374add98800025bb04f568e57e11be27167ee"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:29b55e43836bf64c7f2a022e8dd358abdab05894cb444a4ad5d550ac0f8869d3"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:929216bccf041e21ad27e28aff46e9744f001792eb5ef2868a826a18fa2f58c7"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd201e7ba92dfb919b5200b844536133015e8f231954160e2d57ebf6e54d3cc2"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9f6cb1b86329dd39d4e097d5d5abae9da47ce41485a4fd138c631b6e07389b8c"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:39511a31adbd988ec9706459f162b0258ef8be231837cf3e1adfce80858484ec"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fd1f0d44b4a9274c89faa2cb2dc193d7e71e263cdd82184cb34bcabd6acfdbfd"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1736dd1a018dc4a9a71c51de7a3dd1bed76b31d35c7360de974c73542ea47e8"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36a5b0eb6713803ff0034ee5317950a36f2edcde73be8ecdcc959c2fb5e1fc39"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:83352eef88ce33fd7729215f4aea0bece6f05cb9226c710cf4fa4cd0a6a69e93"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:824af089a281d6cfb15d12708eed3cae211a15bbf3a0925d52fa242c10672091"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:5298e90f925205b037e44efcd843d2414aad720d6755fa8d604b1385272d0f9e"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-musllinux_1_1_i686.whl", hash = "sha256:eafece652771c9e7d1922348e67c57481a1a488faa98235ff0f3bdd6732a7fbe"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b00e2db17d32c2b97ce1429fd25e868c2dc0380ecf55ffae9949ff866053364c"}, + {file = "wassima-1.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e8d67bb4ba6941fa16418e9af884aa2f3b002af1edb25c82dbdc0f96fc7ad594"}, + {file = "wassima-1.1.1-py3-none-any.whl", hash = "sha256:b5b67d9128d728d35a0dd5b0ed071a0feaf2c7e0a7416660864f180b752623df"}, + {file = "wassima-1.1.1.tar.gz", hash = "sha256:b673f31051fd1b9292bd6e05853016b401ac703c377a7d0657242eb41ce6121b"}, +] + [[package]] name = "watchdog" version = "4.0.0" @@ -984,4 +1242,4 @@ watchmedo = ["PyYAML (>=3.10)"] [metadata] lock-version = "2.0" python-versions = "^3.9.0" -content-hash = "52cb0df4fecd9e307c6cfb9617f66e90f3d305468a33ae6646705d809a39e996" +content-hash = "9d9ab727a4d522a566ad2e05e3a936578e254b40f541d539bf9e9285a05dda98" diff --git a/pyproject.toml b/pyproject.toml index 563ff22..23a0a15 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ repository = "https://github.com/seamapi/python-next" [tool.poetry.dependencies] python = "^3.9.0" dataclasses-json = "^0.6.4" -requests = "^2.26.0" +niquests = "^3.6.4" [tool.poetry.group.dev.dependencies] black = "^24.3.0" diff --git a/seam/__init__.py b/seam/__init__.py index e6a9dbe..f1bd0d4 100644 --- a/seam/__init__.py +++ b/seam/__init__.py @@ -1,12 +1,12 @@ # flake8: noqa # type: ignore -from seam.seam import Seam -from seam.types import SeamHttpApiError -from seam.seam_multi_workspace import SeamMultiWorkspace -from seam.options import SeamHttpInvalidOptionsError -from seam.auth import SeamHttpInvalidTokenError -from seam.routes.action_attempts import ( +from .seam import Seam +from .seam_multi_workspace import SeamMultiWorkspace +from .options import SeamHttpInvalidOptionsError +from .auth import SeamHttpInvalidTokenError +from .exceptions import ( + SeamHttpApiError, SeamActionAttemptError, SeamActionAttemptFailedError, SeamActionAttemptTimeoutError, diff --git a/seam/auth.py b/seam/auth.py index 90c4605..0daf860 100644 --- a/seam/auth.py +++ b/seam/auth.py @@ -1,10 +1,10 @@ from typing import Optional -from seam.options import ( +from .options import ( SeamHttpInvalidOptionsError, is_seam_http_options_with_api_key, is_seam_http_options_with_personal_access_token, ) -from seam.token import ( +from .token import ( is_jwt, is_access_token, is_client_session_token, diff --git a/seam/exceptions.py b/seam/exceptions.py new file mode 100644 index 0000000..33fbd15 --- /dev/null +++ b/seam/exceptions.py @@ -0,0 +1,43 @@ +from niquests import Response +from .routes.models import ActionAttempt + + +# HTTP +class SeamHttpApiError(Exception): + def __init__( + self, + response: Response, + ): + self.status_code = response.status_code + self.request_id = response.headers.get("seam-request-id", None) + + self.metadata = None + if "application/json" in response.headers["content-type"]: + parsed_response = response.json() + self.metadata = parsed_response.get("error", None) + + super().__init__( + f"SeamApiException: status={self.status_code}, request_id={self.request_id}, metadata={self.metadata}" + ) + + +# Action Attempt +class SeamActionAttemptError(Exception): + def __init__(self, message: str, action_attempt: ActionAttempt): + super().__init__(message) + self.name = self.__class__.__name__ + self.action_attempt = action_attempt + + +class SeamActionAttemptFailedError(SeamActionAttemptError): + def __init__(self, action_attempt: ActionAttempt): + super().__init__(action_attempt.error.message, action_attempt) + self.name = self.__class__.__name__ + self.code = action_attempt.error.type + + +class SeamActionAttemptTimeoutError(SeamActionAttemptError): + def __init__(self, action_attempt: ActionAttempt, timeout: str): + message = f"Timed out waiting for action attempt after {timeout}s" + super().__init__(message, action_attempt) + self.name = self.__class__.__name__ diff --git a/seam/types.py b/seam/models.py similarity index 72% rename from seam/types.py rename to seam/models.py index 6c6be79..0dbd803 100644 --- a/seam/types.py +++ b/seam/models.py @@ -1,35 +1,26 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Dict, List, Optional, Union +import niquests as requests from typing_extensions import Self import abc -from seam.routes.types import AbstractRoutes, Workspace +from .routes.models import AbstractRoutes, Workspace -class SeamHttpApiError(Exception): - def __init__( - self, - response, - ): - self.status_code = response.status_code - self.request_id = response.headers.get("seam-request-id", None) - - self.metadata = None - if "application/json" in response.headers["content-type"]: - parsed_response = response.json() - self.metadata = parsed_response.get("error", None) - - super().__init__( - f"SeamHttpApiError: status={self.status_code}, request_id={self.request_id}, metadata={self.metadata}" - ) +class AbstractSeamHttpClient(abc.ABC): + @abc.abstractmethod + def __init__(self, base_url: str, auth_headers: Dict[str, str], **kwargs): + raise NotImplementedError + @abc.abstractmethod + def request(self, method: str, url: str, *args, **kwargs): + raise NotImplementedError -class AbstractRequestMixin(abc.ABC): @abc.abstractmethod - def make_request(self, method: str, path: str, **kwargs): + def _handle_response(self, response: requests.Response): raise NotImplementedError -class AbstractSeam(AbstractRoutes, AbstractRequestMixin): +class AbstractSeam(AbstractRoutes): lts_version: str wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] @@ -89,7 +80,7 @@ def list( raise NotImplementedError() -class AbstractSeamMultiWorkspace(AbstractRequestMixin): +class AbstractSeamMultiWorkspace: lts_version: str wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] diff --git a/seam/options.py b/seam/options.py index e7b5ba7..c9b0a1f 100644 --- a/seam/options.py +++ b/seam/options.py @@ -1,7 +1,7 @@ import os from typing import Optional -from seam.constants import DEFAULT_ENDPOINT +from .constants import DEFAULT_ENDPOINT def get_endpoint(endpoint: Optional[str] = None): diff --git a/seam/parse_options.py b/seam/parse_options.py index 4e40ca8..afd0e56 100644 --- a/seam/parse_options.py +++ b/seam/parse_options.py @@ -1,8 +1,8 @@ import os from typing import Optional -from seam.auth import get_auth_headers -from seam.options import get_endpoint +from .auth import get_auth_headers +from .options import get_endpoint def parse_options( diff --git a/seam/request.py b/seam/request.py index df6ac5e..d28cb0a 100644 --- a/seam/request.py +++ b/seam/request.py @@ -1,43 +1,35 @@ -import requests +from typing import Dict +from urllib.parse import urljoin +import niquests as requests from importlib.metadata import version -from seam.types import AbstractRequestMixin, SeamHttpApiError - - -class RequestMixin(AbstractRequestMixin): - def make_request(self, method: str, path: str, **kwargs): - """ - Makes a request to the API - - Parameters - ---------- - method : str - Request method - path : str - Request path - **kwargs - Keyword arguments passed to requests.request - - Raises - ------ - SeamHttpApiError: If the response status code is not successful. - """ - - url = self._endpoint + path - sdk_version = version("seam") - headers = { - **self._auth_headers, - "Content-Type": "application/json", - "User-Agent": "Python SDK v" - + sdk_version - + " (https://github.com/seamapi/python-next)", - "seam-sdk-name": "seamapi/python", - "seam-sdk-version": sdk_version, - "seam-lts-version": self.lts_version, - } - - response = requests.request(method, url, headers=headers, **kwargs) +from .constants import LTS_VERSION +from .exceptions import SeamHttpApiError +from .models import AbstractSeamHttpClient +SDK_HEADERS = { + "seam-sdk-name": "seamapi/python", + "seam-sdk-version": version("seam"), + "seam-lts-version": LTS_VERSION, +} + + +class SeamHttpClient(requests.Session, AbstractSeamHttpClient): + def __init__(self, base_url: str, auth_headers: Dict[str, str], **kwargs): + super().__init__(**kwargs) + + self.base_url = base_url + headers = {**auth_headers, **kwargs.get("headers", {}), **SDK_HEADERS} + + self.headers.update(headers) + + def request(self, method, url, *args, **kwargs): + url = urljoin(self.base_url, url) + response = super().request(method, url, *args, **kwargs) + + return self._handle_response(response) + + def _handle_response(self, response: requests.Response): if response.status_code != 200: raise SeamHttpApiError(response) diff --git a/seam/routes/routes.py b/seam/routes/__init__.py similarity index 97% rename from seam/routes/routes.py rename to seam/routes/__init__.py index 35ba96e..cda43ec 100644 --- a/seam/routes/routes.py +++ b/seam/routes/__init__.py @@ -1,4 +1,4 @@ -from .types import AbstractRoutes +from .models import AbstractRoutes from .access_codes import AccessCodes from .acs import Acs from .action_attempts import ActionAttempts diff --git a/seam/routes/access_codes.py b/seam/routes/access_codes.py index d0f1abb..eea2106 100644 --- a/seam/routes/access_codes.py +++ b/seam/routes/access_codes.py @@ -1,8 +1,8 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractAccessCodes, AccessCode from typing import Optional, Any, List, Dict, Union -from seam.routes.access_codes_simulate import AccessCodesSimulate -from seam.routes.access_codes_unmanaged import AccessCodesUnmanaged +from ..models import AbstractSeam as Seam +from .models import AbstractAccessCodes, AccessCode +from .access_codes_simulate import AccessCodesSimulate +from .access_codes_unmanaged import AccessCodesUnmanaged class AccessCodes(AbstractAccessCodes): @@ -78,7 +78,7 @@ def create( if use_offline_access_code is not None: json_payload["use_offline_access_code"] = use_offline_access_code - res = self.seam.make_request("POST", "/access_codes/create", json=json_payload) + res = self.seam.client.post("/access_codes/create", json=json_payload) return AccessCode.from_dict(res["access_code"]) @@ -141,9 +141,7 @@ def create_multiple( if use_offline_access_code is not None: json_payload["use_offline_access_code"] = use_offline_access_code - res = self.seam.make_request( - "POST", "/access_codes/create_multiple", json=json_payload - ) + res = self.seam.client.post("/access_codes/create_multiple", json=json_payload) return [AccessCode.from_dict(item) for item in res["access_codes"]] @@ -163,7 +161,7 @@ def delete( if sync is not None: json_payload["sync"] = sync - self.seam.make_request("POST", "/access_codes/delete", json=json_payload) + self.seam.client.post("/access_codes/delete", json=json_payload) return None @@ -173,9 +171,7 @@ def generate_code(self, *, device_id: str) -> AccessCode: if device_id is not None: json_payload["device_id"] = device_id - res = self.seam.make_request( - "POST", "/access_codes/generate_code", json=json_payload - ) + res = self.seam.client.post("/access_codes/generate_code", json=json_payload) return AccessCode.from_dict(res["generated_code"]) @@ -195,7 +191,7 @@ def get( if device_id is not None: json_payload["device_id"] = device_id - res = self.seam.make_request("POST", "/access_codes/get", json=json_payload) + res = self.seam.client.post("/access_codes/get", json=json_payload) return AccessCode.from_dict(res["access_code"]) @@ -215,7 +211,7 @@ def list( if user_identifier_key is not None: json_payload["user_identifier_key"] = user_identifier_key - res = self.seam.make_request("POST", "/access_codes/list", json=json_payload) + res = self.seam.client.post("/access_codes/list", json=json_payload) return [AccessCode.from_dict(item) for item in res["access_codes"]] @@ -225,8 +221,9 @@ def pull_backup_access_code(self, *, access_code_id: str) -> AccessCode: if access_code_id is not None: json_payload["access_code_id"] = access_code_id - res = self.seam.make_request( - "POST", "/access_codes/pull_backup_access_code", json=json_payload + res = self.seam.client.post( + "/access_codes/pull_backup_access_code", + json=json_payload, ) return AccessCode.from_dict(res["backup_access_code"]) @@ -294,6 +291,6 @@ def update( if use_offline_access_code is not None: json_payload["use_offline_access_code"] = use_offline_access_code - self.seam.make_request("POST", "/access_codes/update", json=json_payload) + self.seam.client.post("/access_codes/update", json=json_payload) return None diff --git a/seam/routes/access_codes_simulate.py b/seam/routes/access_codes_simulate.py index 00ecb28..f376d0f 100644 --- a/seam/routes/access_codes_simulate.py +++ b/seam/routes/access_codes_simulate.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractAccessCodesSimulate, UnmanagedAccessCode from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractAccessCodesSimulate, UnmanagedAccessCode class AccessCodesSimulate(AbstractAccessCodesSimulate): @@ -21,8 +21,7 @@ def create_unmanaged_access_code( if name is not None: json_payload["name"] = name - res = self.seam.make_request( - "POST", + res = self.seam.client.post( "/access_codes/simulate/create_unmanaged_access_code", json=json_payload, ) diff --git a/seam/routes/access_codes_unmanaged.py b/seam/routes/access_codes_unmanaged.py index 05243d1..b78ffd7 100644 --- a/seam/routes/access_codes_unmanaged.py +++ b/seam/routes/access_codes_unmanaged.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractAccessCodesUnmanaged, UnmanagedAccessCode from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractAccessCodesUnmanaged, UnmanagedAccessCode class AccessCodesUnmanaged(AbstractAccessCodesUnmanaged): @@ -33,8 +33,9 @@ def convert_to_managed( if sync is not None: json_payload["sync"] = sync - self.seam.make_request( - "POST", "/access_codes/unmanaged/convert_to_managed", json=json_payload + self.seam.client.post( + "/access_codes/unmanaged/convert_to_managed", + json=json_payload, ) return None @@ -47,9 +48,7 @@ def delete(self, *, access_code_id: str, sync: Optional[bool] = None) -> None: if sync is not None: json_payload["sync"] = sync - self.seam.make_request( - "POST", "/access_codes/unmanaged/delete", json=json_payload - ) + self.seam.client.post("/access_codes/unmanaged/delete", json=json_payload) return None @@ -69,9 +68,7 @@ def get( if device_id is not None: json_payload["device_id"] = device_id - res = self.seam.make_request( - "POST", "/access_codes/unmanaged/get", json=json_payload - ) + res = self.seam.client.post("/access_codes/unmanaged/get", json=json_payload) return UnmanagedAccessCode.from_dict(res["access_code"]) @@ -85,9 +82,7 @@ def list( if user_identifier_key is not None: json_payload["user_identifier_key"] = user_identifier_key - res = self.seam.make_request( - "POST", "/access_codes/unmanaged/list", json=json_payload - ) + res = self.seam.client.post("/access_codes/unmanaged/list", json=json_payload) return [UnmanagedAccessCode.from_dict(item) for item in res["access_codes"]] @@ -115,8 +110,6 @@ def update( is_external_modification_allowed ) - self.seam.make_request( - "POST", "/access_codes/unmanaged/update", json=json_payload - ) + self.seam.client.post("/access_codes/unmanaged/update", json=json_payload) return None diff --git a/seam/routes/acs.py b/seam/routes/acs.py index c99783a..52c878e 100644 --- a/seam/routes/acs.py +++ b/seam/routes/acs.py @@ -1,15 +1,15 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractAcs from typing import Optional, Any, List, Dict, Union -from seam.routes.acs_access_groups import AcsAccessGroups -from seam.routes.acs_credential_pools import AcsCredentialPools -from seam.routes.acs_credential_provisioning_automations import ( +from ..models import AbstractSeam as Seam +from .models import AbstractAcs +from .acs_access_groups import AcsAccessGroups +from .acs_credential_pools import AcsCredentialPools +from .acs_credential_provisioning_automations import ( AcsCredentialProvisioningAutomations, ) -from seam.routes.acs_credentials import AcsCredentials -from seam.routes.acs_entrances import AcsEntrances -from seam.routes.acs_systems import AcsSystems -from seam.routes.acs_users import AcsUsers +from .acs_credentials import AcsCredentials +from .acs_entrances import AcsEntrances +from .acs_systems import AcsSystems +from .acs_users import AcsUsers class Acs(AbstractAcs): diff --git a/seam/routes/acs_access_groups.py b/seam/routes/acs_access_groups.py index 897eb64..8e06e2f 100644 --- a/seam/routes/acs_access_groups.py +++ b/seam/routes/acs_access_groups.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractAcsAccessGroups, AcsAccessGroup, AcsUser from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractAcsAccessGroups, AcsAccessGroup, AcsUser class AcsAccessGroups(AbstractAcsAccessGroups): @@ -17,7 +17,7 @@ def add_user(self, *, acs_access_group_id: str, acs_user_id: str) -> None: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request("POST", "/acs/access_groups/add_user", json=json_payload) + self.seam.client.post("/acs/access_groups/add_user", json=json_payload) return None @@ -27,9 +27,7 @@ def get(self, *, acs_access_group_id: str) -> AcsAccessGroup: if acs_access_group_id is not None: json_payload["acs_access_group_id"] = acs_access_group_id - res = self.seam.make_request( - "POST", "/acs/access_groups/get", json=json_payload - ) + res = self.seam.client.post("/acs/access_groups/get", json=json_payload) return AcsAccessGroup.from_dict(res["acs_access_group"]) @@ -43,9 +41,7 @@ def list( if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - res = self.seam.make_request( - "POST", "/acs/access_groups/list", json=json_payload - ) + res = self.seam.client.post("/acs/access_groups/list", json=json_payload) return [AcsAccessGroup.from_dict(item) for item in res["acs_access_groups"]] @@ -55,9 +51,7 @@ def list_users(self, *, acs_access_group_id: str) -> List[AcsUser]: if acs_access_group_id is not None: json_payload["acs_access_group_id"] = acs_access_group_id - res = self.seam.make_request( - "POST", "/acs/access_groups/list_users", json=json_payload - ) + res = self.seam.client.post("/acs/access_groups/list_users", json=json_payload) return [AcsUser.from_dict(item) for item in res["acs_users"]] @@ -69,8 +63,6 @@ def remove_user(self, *, acs_access_group_id: str, acs_user_id: str) -> None: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request( - "POST", "/acs/access_groups/remove_user", json=json_payload - ) + self.seam.client.post("/acs/access_groups/remove_user", json=json_payload) return None diff --git a/seam/routes/acs_credential_pools.py b/seam/routes/acs_credential_pools.py index c0764b6..97aa73b 100644 --- a/seam/routes/acs_credential_pools.py +++ b/seam/routes/acs_credential_pools.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractAcsCredentialPools, AcsCredentialPool from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractAcsCredentialPools, AcsCredentialPool class AcsCredentialPools(AbstractAcsCredentialPools): @@ -15,9 +15,7 @@ def list(self, *, acs_system_id: str) -> List[AcsCredentialPool]: if acs_system_id is not None: json_payload["acs_system_id"] = acs_system_id - res = self.seam.make_request( - "POST", "/acs/credential_pools/list", json=json_payload - ) + res = self.seam.client.post("/acs/credential_pools/list", json=json_payload) return [ AcsCredentialPool.from_dict(item) for item in res["acs_credential_pools"] diff --git a/seam/routes/acs_credential_provisioning_automations.py b/seam/routes/acs_credential_provisioning_automations.py index df0214c..413e881 100644 --- a/seam/routes/acs_credential_provisioning_automations.py +++ b/seam/routes/acs_credential_provisioning_automations.py @@ -1,9 +1,9 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import ( +from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import ( AbstractAcsCredentialProvisioningAutomations, AcsCredentialProvisioningAutomation, ) -from typing import Optional, Any, List, Dict, Union class AcsCredentialProvisioningAutomations( @@ -42,8 +42,9 @@ def launch( credential_manager_acs_user_id ) - res = self.seam.make_request( - "POST", "/acs/credential_provisioning_automations/launch", json=json_payload + res = self.seam.client.post( + "/acs/credential_provisioning_automations/launch", + json=json_payload, ) return AcsCredentialProvisioningAutomation.from_dict( diff --git a/seam/routes/acs_credentials.py b/seam/routes/acs_credentials.py index abc9289..3ee27eb 100644 --- a/seam/routes/acs_credentials.py +++ b/seam/routes/acs_credentials.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractAcsCredentials, AcsCredential from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractAcsCredentials, AcsCredential class AcsCredentials(AbstractAcsCredentials): @@ -17,7 +17,7 @@ def assign(self, *, acs_credential_id: str, acs_user_id: str) -> None: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request("POST", "/acs/credentials/assign", json=json_payload) + self.seam.client.post("/acs/credentials/assign", json=json_payload) return None @@ -59,9 +59,7 @@ def create( if visionline_metadata is not None: json_payload["visionline_metadata"] = visionline_metadata - res = self.seam.make_request( - "POST", "/acs/credentials/create", json=json_payload - ) + res = self.seam.client.post("/acs/credentials/create", json=json_payload) return AcsCredential.from_dict(res["acs_credential"]) @@ -71,7 +69,7 @@ def delete(self, *, acs_credential_id: str) -> None: if acs_credential_id is not None: json_payload["acs_credential_id"] = acs_credential_id - self.seam.make_request("POST", "/acs/credentials/delete", json=json_payload) + self.seam.client.post("/acs/credentials/delete", json=json_payload) return None @@ -81,7 +79,7 @@ def get(self, *, acs_credential_id: str) -> AcsCredential: if acs_credential_id is not None: json_payload["acs_credential_id"] = acs_credential_id - res = self.seam.make_request("POST", "/acs/credentials/get", json=json_payload) + res = self.seam.client.post("/acs/credentials/get", json=json_payload) return AcsCredential.from_dict(res["acs_credential"]) @@ -106,7 +104,7 @@ def list( is_multi_phone_sync_credential ) - res = self.seam.make_request("POST", "/acs/credentials/list", json=json_payload) + res = self.seam.client.post("/acs/credentials/list", json=json_payload) return [AcsCredential.from_dict(item) for item in res["acs_credentials"]] @@ -118,7 +116,7 @@ def unassign(self, *, acs_credential_id: str, acs_user_id: str) -> None: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request("POST", "/acs/credentials/unassign", json=json_payload) + self.seam.client.post("/acs/credentials/unassign", json=json_payload) return None @@ -138,6 +136,6 @@ def update( if ends_at is not None: json_payload["ends_at"] = ends_at - self.seam.make_request("POST", "/acs/credentials/update", json=json_payload) + self.seam.client.post("/acs/credentials/update", json=json_payload) return None diff --git a/seam/routes/acs_entrances.py b/seam/routes/acs_entrances.py index dd976ad..be980b2 100644 --- a/seam/routes/acs_entrances.py +++ b/seam/routes/acs_entrances.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractAcsEntrances, AcsEntrance, AcsCredential from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractAcsEntrances, AcsEntrance, AcsCredential class AcsEntrances(AbstractAcsEntrances): @@ -15,7 +15,7 @@ def get(self, *, acs_entrance_id: str) -> AcsEntrance: if acs_entrance_id is not None: json_payload["acs_entrance_id"] = acs_entrance_id - res = self.seam.make_request("POST", "/acs/entrances/get", json=json_payload) + res = self.seam.client.post("/acs/entrances/get", json=json_payload) return AcsEntrance.from_dict(res["acs_entrance"]) @@ -27,7 +27,7 @@ def grant_access(self, *, acs_entrance_id: str, acs_user_id: str) -> None: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request("POST", "/acs/entrances/grant_access", json=json_payload) + self.seam.client.post("/acs/entrances/grant_access", json=json_payload) return None @@ -44,7 +44,7 @@ def list( if acs_system_id is not None: json_payload["acs_system_id"] = acs_system_id - res = self.seam.make_request("POST", "/acs/entrances/list", json=json_payload) + res = self.seam.client.post("/acs/entrances/list", json=json_payload) return [AcsEntrance.from_dict(item) for item in res["acs_entrances"]] @@ -58,8 +58,9 @@ def list_credentials_with_access( if include_if is not None: json_payload["include_if"] = include_if - res = self.seam.make_request( - "POST", "/acs/entrances/list_credentials_with_access", json=json_payload + res = self.seam.client.post( + "/acs/entrances/list_credentials_with_access", + json=json_payload, ) return [AcsCredential.from_dict(item) for item in res["acs_credentials"]] diff --git a/seam/routes/acs_systems.py b/seam/routes/acs_systems.py index 9896ebd..421fc75 100644 --- a/seam/routes/acs_systems.py +++ b/seam/routes/acs_systems.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractAcsSystems, AcsSystem from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractAcsSystems, AcsSystem class AcsSystems(AbstractAcsSystems): @@ -15,7 +15,7 @@ def get(self, *, acs_system_id: str) -> AcsSystem: if acs_system_id is not None: json_payload["acs_system_id"] = acs_system_id - res = self.seam.make_request("POST", "/acs/systems/get", json=json_payload) + res = self.seam.client.post("/acs/systems/get", json=json_payload) return AcsSystem.from_dict(res["acs_system"]) @@ -25,7 +25,23 @@ def list(self, *, connected_account_id: Optional[str] = None) -> List[AcsSystem] if connected_account_id is not None: json_payload["connected_account_id"] = connected_account_id - res = self.seam.make_request("POST", "/acs/systems/list", json=json_payload) + res = self.seam.client.post("/acs/systems/list", json=json_payload) + + return [AcsSystem.from_dict(item) for item in res["acs_systems"]] + + def list_compatible_credential_manager_acs_systems( + self, *, acs_system_id: str + ) -> List[AcsSystem]: + json_payload = {} + + if acs_system_id is not None: + json_payload["acs_system_id"] = acs_system_id + + res = self.seam.client.post( + self.seam.endpoint + + "/acs/systems/list_compatible_credential_manager_acs_systems", + json=json_payload, + ) return [AcsSystem.from_dict(item) for item in res["acs_systems"]] diff --git a/seam/routes/acs_users.py b/seam/routes/acs_users.py index 01c3ef5..fe5e8a4 100644 --- a/seam/routes/acs_users.py +++ b/seam/routes/acs_users.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractAcsUsers, AcsUser, AcsEntrance from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractAcsUsers, AcsUser, AcsEntrance class AcsUsers(AbstractAcsUsers): @@ -19,9 +19,7 @@ def add_to_access_group( if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request( - "POST", "/acs/users/add_to_access_group", json=json_payload - ) + self.seam.client.post("/acs/users/add_to_access_group", json=json_payload) return None @@ -56,7 +54,7 @@ def create( if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id - res = self.seam.make_request("POST", "/acs/users/create", json=json_payload) + res = self.seam.client.post("/acs/users/create", json=json_payload) return AcsUser.from_dict(res["acs_user"]) @@ -66,7 +64,7 @@ def delete(self, *, acs_user_id: str) -> None: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request("POST", "/acs/users/delete", json=json_payload) + self.seam.client.post("/acs/users/delete", json=json_payload) return None @@ -76,7 +74,7 @@ def get(self, *, acs_user_id: str) -> AcsUser: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - res = self.seam.make_request("POST", "/acs/users/get", json=json_payload) + res = self.seam.client.post("/acs/users/get", json=json_payload) return AcsUser.from_dict(res["acs_user"]) @@ -99,7 +97,7 @@ def list( if user_identity_phone_number is not None: json_payload["user_identity_phone_number"] = user_identity_phone_number - res = self.seam.make_request("POST", "/acs/users/list", json=json_payload) + res = self.seam.client.post("/acs/users/list", json=json_payload) return [AcsUser.from_dict(item) for item in res["acs_users"]] @@ -109,8 +107,9 @@ def list_accessible_entrances(self, *, acs_user_id: str) -> List[AcsEntrance]: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - res = self.seam.make_request( - "POST", "/acs/users/list_accessible_entrances", json=json_payload + res = self.seam.client.post( + "/acs/users/list_accessible_entrances", + json=json_payload, ) return [AcsEntrance.from_dict(item) for item in res["acs_entrances"]] @@ -125,8 +124,9 @@ def remove_from_access_group( if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request( - "POST", "/acs/users/remove_from_access_group", json=json_payload + self.seam.client.post( + "/acs/users/remove_from_access_group", + json=json_payload, ) return None @@ -137,8 +137,9 @@ def revoke_access_to_all_entrances(self, *, acs_user_id: str) -> None: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request( - "POST", "/acs/users/revoke_access_to_all_entrances", json=json_payload + self.seam.client.post( + "/acs/users/revoke_access_to_all_entrances", + json=json_payload, ) return None @@ -149,7 +150,7 @@ def suspend(self, *, acs_user_id: str) -> None: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request("POST", "/acs/users/suspend", json=json_payload) + self.seam.client.post("/acs/users/suspend", json=json_payload) return None @@ -159,7 +160,7 @@ def unsuspend(self, *, acs_user_id: str) -> None: if acs_user_id is not None: json_payload["acs_user_id"] = acs_user_id - self.seam.make_request("POST", "/acs/users/unsuspend", json=json_payload) + self.seam.client.post("/acs/users/unsuspend", json=json_payload) return None @@ -191,6 +192,6 @@ def update( if phone_number is not None: json_payload["phone_number"] = phone_number - self.seam.make_request("POST", "/acs/users/update", json=json_payload) + self.seam.client.post("/acs/users/update", json=json_payload) return None diff --git a/seam/routes/action_attempts.py b/seam/routes/action_attempts.py index a9e110c..8ea5d25 100644 --- a/seam/routes/action_attempts.py +++ b/seam/routes/action_attempts.py @@ -1,29 +1,9 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractActionAttempts, ActionAttempt from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractActionAttempts, ActionAttempt import time - - -class SeamActionAttemptError(Exception): - def __init__(self, message: str, action_attempt: ActionAttempt): - super().__init__(message) - self.name = self.__class__.__name__ - self.action_attempt = action_attempt - - -class SeamActionAttemptFailedError(SeamActionAttemptError): - def __init__(self, action_attempt: ActionAttempt): - super().__init__(action_attempt.error.message, action_attempt) - self.name = self.__class__.__name__ - self.code = action_attempt.error.type - - -class SeamActionAttemptTimeoutError(SeamActionAttemptError): - def __init__(self, action_attempt: ActionAttempt, timeout: str): - message = f"Timed out waiting for action attempt after {timeout}s" - super().__init__(message, action_attempt) - self.name = self.__class__.__name__ +from ..exceptions import SeamActionAttemptFailedError, SeamActionAttemptTimeoutError class ActionAttempts(AbstractActionAttempts): @@ -36,14 +16,14 @@ def get( self, *, action_attempt_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None ) -> ActionAttempt: json_payload = {} if action_attempt_id is not None: json_payload["action_attempt_id"] = action_attempt_id - res = self.seam.make_request("POST", "/action_attempts/get", json=json_payload) + res = self.seam.client.post("/action_attempts/get", json=json_payload) return self.seam.action_attempts.decide_and_wait( action_attempt=ActionAttempt.from_dict(res["action_attempt"]), @@ -56,7 +36,7 @@ def list(self, *, action_attempt_ids: List[str]) -> List[ActionAttempt]: if action_attempt_ids is not None: json_payload["action_attempt_ids"] = action_attempt_ids - res = self.seam.make_request("POST", "/action_attempts/list", json=json_payload) + res = self.seam.client.post("/action_attempts/list", json=json_payload) return [ActionAttempt.from_dict(item) for item in res["action_attempts"]] @@ -65,7 +45,7 @@ def poll_until_ready( *, action_attempt_id: str, timeout: Optional[float] = 5.0, - polling_interval: Optional[float] = 0.5, + polling_interval: Optional[float] = 0.5 ) -> ActionAttempt: seam = self.seam time_waiting = 0.0 @@ -95,7 +75,7 @@ def decide_and_wait( self, *, action_attempt: ActionAttempt, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None ) -> ActionAttempt: wait_decision = ( self.seam.wait_for_action_attempt diff --git a/seam/routes/client_sessions.py b/seam/routes/client_sessions.py index 9b14ad4..3a9b800 100644 --- a/seam/routes/client_sessions.py +++ b/seam/routes/client_sessions.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractClientSessions, ClientSession from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractClientSessions, ClientSession class ClientSessions(AbstractClientSessions): @@ -31,9 +31,7 @@ def create( if user_identity_ids is not None: json_payload["user_identity_ids"] = user_identity_ids - res = self.seam.make_request( - "POST", "/client_sessions/create", json=json_payload - ) + res = self.seam.client.post("/client_sessions/create", json=json_payload) return ClientSession.from_dict(res["client_session"]) @@ -43,7 +41,7 @@ def delete(self, *, client_session_id: str) -> None: if client_session_id is not None: json_payload["client_session_id"] = client_session_id - self.seam.make_request("POST", "/client_sessions/delete", json=json_payload) + self.seam.client.post("/client_sessions/delete", json=json_payload) return None @@ -60,7 +58,7 @@ def get( if user_identifier_key is not None: json_payload["user_identifier_key"] = user_identifier_key - res = self.seam.make_request("POST", "/client_sessions/get", json=json_payload) + res = self.seam.client.post("/client_sessions/get", json=json_payload) return ClientSession.from_dict(res["client_session"]) @@ -86,9 +84,7 @@ def get_or_create( if user_identity_ids is not None: json_payload["user_identity_ids"] = user_identity_ids - res = self.seam.make_request( - "POST", "/client_sessions/get_or_create", json=json_payload - ) + res = self.seam.client.post("/client_sessions/get_or_create", json=json_payload) return ClientSession.from_dict(res["client_session"]) @@ -114,9 +110,7 @@ def grant_access( if user_identity_ids is not None: json_payload["user_identity_ids"] = user_identity_ids - self.seam.make_request( - "POST", "/client_sessions/grant_access", json=json_payload - ) + self.seam.client.post("/client_sessions/grant_access", json=json_payload) return None @@ -142,7 +136,7 @@ def list( if without_user_identifier_key is not None: json_payload["without_user_identifier_key"] = without_user_identifier_key - res = self.seam.make_request("POST", "/client_sessions/list", json=json_payload) + res = self.seam.client.post("/client_sessions/list", json=json_payload) return [ClientSession.from_dict(item) for item in res["client_sessions"]] @@ -152,6 +146,6 @@ def revoke(self, *, client_session_id: str) -> None: if client_session_id is not None: json_payload["client_session_id"] = client_session_id - self.seam.make_request("POST", "/client_sessions/revoke", json=json_payload) + self.seam.client.post("/client_sessions/revoke", json=json_payload) return None diff --git a/seam/routes/connect_webviews.py b/seam/routes/connect_webviews.py index bdc2fd9..4eaae36 100644 --- a/seam/routes/connect_webviews.py +++ b/seam/routes/connect_webviews.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractConnectWebviews, ConnectWebview from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractConnectWebviews, ConnectWebview class ConnectWebviews(AbstractConnectWebviews): @@ -42,9 +42,7 @@ def create( if wait_for_device_creation is not None: json_payload["wait_for_device_creation"] = wait_for_device_creation - res = self.seam.make_request( - "POST", "/connect_webviews/create", json=json_payload - ) + res = self.seam.client.post("/connect_webviews/create", json=json_payload) return ConnectWebview.from_dict(res["connect_webview"]) @@ -54,7 +52,7 @@ def delete(self, *, connect_webview_id: str) -> None: if connect_webview_id is not None: json_payload["connect_webview_id"] = connect_webview_id - self.seam.make_request("POST", "/connect_webviews/delete", json=json_payload) + self.seam.client.post("/connect_webviews/delete", json=json_payload) return None @@ -64,7 +62,7 @@ def get(self, *, connect_webview_id: str) -> ConnectWebview: if connect_webview_id is not None: json_payload["connect_webview_id"] = connect_webview_id - res = self.seam.make_request("POST", "/connect_webviews/get", json=json_payload) + res = self.seam.client.post("/connect_webviews/get", json=json_payload) return ConnectWebview.from_dict(res["connect_webview"]) @@ -81,8 +79,6 @@ def list( if user_identifier_key is not None: json_payload["user_identifier_key"] = user_identifier_key - res = self.seam.make_request( - "POST", "/connect_webviews/list", json=json_payload - ) + res = self.seam.client.post("/connect_webviews/list", json=json_payload) return [ConnectWebview.from_dict(item) for item in res["connect_webviews"]] diff --git a/seam/routes/connected_accounts.py b/seam/routes/connected_accounts.py index 2f6bc96..328822f 100644 --- a/seam/routes/connected_accounts.py +++ b/seam/routes/connected_accounts.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractConnectedAccounts, ConnectedAccount from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractConnectedAccounts, ConnectedAccount class ConnectedAccounts(AbstractConnectedAccounts): @@ -17,7 +17,7 @@ def delete(self, *, connected_account_id: str, sync: Optional[bool] = None) -> N if sync is not None: json_payload["sync"] = sync - self.seam.make_request("POST", "/connected_accounts/delete", json=json_payload) + self.seam.client.post("/connected_accounts/delete", json=json_payload) return None @@ -31,9 +31,7 @@ def get( if email is not None: json_payload["email"] = email - res = self.seam.make_request( - "POST", "/connected_accounts/get", json=json_payload - ) + res = self.seam.client.post("/connected_accounts/get", json=json_payload) return ConnectedAccount.from_dict(res["connected_account"]) @@ -45,9 +43,7 @@ def list( if custom_metadata_has is not None: json_payload["custom_metadata_has"] = custom_metadata_has - res = self.seam.make_request( - "POST", "/connected_accounts/list", json=json_payload - ) + res = self.seam.client.post("/connected_accounts/list", json=json_payload) return [ConnectedAccount.from_dict(item) for item in res["connected_accounts"]] @@ -69,8 +65,6 @@ def update( if custom_metadata is not None: json_payload["custom_metadata"] = custom_metadata - res = self.seam.make_request( - "POST", "/connected_accounts/update", json=json_payload - ) + res = self.seam.client.post("/connected_accounts/update", json=json_payload) return ConnectedAccount.from_dict(res["connected_account"]) diff --git a/seam/routes/devices.py b/seam/routes/devices.py index 98156b8..6311049 100644 --- a/seam/routes/devices.py +++ b/seam/routes/devices.py @@ -1,8 +1,8 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractDevices, Device, DeviceProvider from typing import Optional, Any, List, Dict, Union -from seam.routes.devices_simulate import DevicesSimulate -from seam.routes.devices_unmanaged import DevicesUnmanaged +from ..models import AbstractSeam as Seam +from .models import AbstractDevices, Device, DeviceProvider +from .devices_simulate import DevicesSimulate +from .devices_unmanaged import DevicesUnmanaged class Devices(AbstractDevices): @@ -27,7 +27,7 @@ def delete(self, *, device_id: str) -> None: if device_id is not None: json_payload["device_id"] = device_id - self.seam.make_request("POST", "/devices/delete", json=json_payload) + self.seam.client.post("/devices/delete", json=json_payload) return None @@ -41,7 +41,7 @@ def get( if name is not None: json_payload["name"] = name - res = self.seam.make_request("POST", "/devices/get", json=json_payload) + res = self.seam.client.post("/devices/get", json=json_payload) return Device.from_dict(res["device"]) @@ -91,7 +91,7 @@ def list( if user_identifier_key is not None: json_payload["user_identifier_key"] = user_identifier_key - res = self.seam.make_request("POST", "/devices/list", json=json_payload) + res = self.seam.client.post("/devices/list", json=json_payload) return [Device.from_dict(item) for item in res["devices"]] @@ -103,9 +103,7 @@ def list_device_providers( if provider_category is not None: json_payload["provider_category"] = provider_category - res = self.seam.make_request( - "POST", "/devices/list_device_providers", json=json_payload - ) + res = self.seam.client.post("/devices/list_device_providers", json=json_payload) return [DeviceProvider.from_dict(item) for item in res["device_providers"]] @@ -131,6 +129,6 @@ def update( if properties is not None: json_payload["properties"] = properties - self.seam.make_request("POST", "/devices/update", json=json_payload) + self.seam.client.post("/devices/update", json=json_payload) return None diff --git a/seam/routes/devices_simulate.py b/seam/routes/devices_simulate.py index 537125a..054e6b4 100644 --- a/seam/routes/devices_simulate.py +++ b/seam/routes/devices_simulate.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractDevicesSimulate from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractDevicesSimulate class DevicesSimulate(AbstractDevicesSimulate): @@ -15,6 +15,6 @@ def remove(self, *, device_id: str) -> None: if device_id is not None: json_payload["device_id"] = device_id - self.seam.make_request("POST", "/devices/simulate/remove", json=json_payload) + self.seam.client.post("/devices/simulate/remove", json=json_payload) return None diff --git a/seam/routes/devices_unmanaged.py b/seam/routes/devices_unmanaged.py index f68f940..fa6e53f 100644 --- a/seam/routes/devices_unmanaged.py +++ b/seam/routes/devices_unmanaged.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractDevicesUnmanaged, UnmanagedDevice from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractDevicesUnmanaged, UnmanagedDevice class DevicesUnmanaged(AbstractDevicesUnmanaged): @@ -19,9 +19,7 @@ def get( if name is not None: json_payload["name"] = name - res = self.seam.make_request( - "POST", "/devices/unmanaged/get", json=json_payload - ) + res = self.seam.client.post("/devices/unmanaged/get", json=json_payload) return UnmanagedDevice.from_dict(res["device"]) @@ -71,9 +69,7 @@ def list( if user_identifier_key is not None: json_payload["user_identifier_key"] = user_identifier_key - res = self.seam.make_request( - "POST", "/devices/unmanaged/list", json=json_payload - ) + res = self.seam.client.post("/devices/unmanaged/list", json=json_payload) return [UnmanagedDevice.from_dict(item) for item in res["devices"]] @@ -85,6 +81,6 @@ def update(self, *, device_id: str, is_managed: bool) -> None: if is_managed is not None: json_payload["is_managed"] = is_managed - self.seam.make_request("POST", "/devices/unmanaged/update", json=json_payload) + self.seam.client.post("/devices/unmanaged/update", json=json_payload) return None diff --git a/seam/routes/events.py b/seam/routes/events.py index bc56b8e..c099ed8 100644 --- a/seam/routes/events.py +++ b/seam/routes/events.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractEvents, Event from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractEvents, Event class Events(AbstractEvents): @@ -25,7 +25,7 @@ def get( if event_type is not None: json_payload["event_type"] = event_type - res = self.seam.make_request("POST", "/events/get", json=json_payload) + res = self.seam.client.post("/events/get", json=json_payload) return Event.from_dict(res["event"]) @@ -66,6 +66,6 @@ def list( if since is not None: json_payload["since"] = since - res = self.seam.make_request("POST", "/events/list", json=json_payload) + res = self.seam.client.post("/events/list", json=json_payload) return [Event.from_dict(item) for item in res["events"]] diff --git a/seam/routes/locks.py b/seam/routes/locks.py index afc19a6..38bf0bc 100644 --- a/seam/routes/locks.py +++ b/seam/routes/locks.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractLocks, Device, ActionAttempt from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractLocks, Device, ActionAttempt class Locks(AbstractLocks): @@ -19,7 +19,7 @@ def get( if name is not None: json_payload["name"] = name - res = self.seam.make_request("POST", "/locks/get", json=json_payload) + res = self.seam.client.post("/locks/get", json=json_payload) return Device.from_dict(res["device"]) @@ -69,7 +69,7 @@ def list( if user_identifier_key is not None: json_payload["user_identifier_key"] = user_identifier_key - res = self.seam.make_request("POST", "/locks/list", json=json_payload) + res = self.seam.client.post("/locks/list", json=json_payload) return [Device.from_dict(item) for item in res["devices"]] @@ -87,7 +87,7 @@ def lock_door( if sync is not None: json_payload["sync"] = sync - res = self.seam.make_request("POST", "/locks/lock_door", json=json_payload) + res = self.seam.client.post("/locks/lock_door", json=json_payload) return self.seam.action_attempts.decide_and_wait( action_attempt=ActionAttempt.from_dict(res["action_attempt"]), @@ -108,7 +108,7 @@ def unlock_door( if sync is not None: json_payload["sync"] = sync - res = self.seam.make_request("POST", "/locks/unlock_door", json=json_payload) + res = self.seam.client.post("/locks/unlock_door", json=json_payload) return self.seam.action_attempts.decide_and_wait( action_attempt=ActionAttempt.from_dict(res["action_attempt"]), diff --git a/seam/routes/types.py b/seam/routes/models.py similarity index 99% rename from seam/routes/types.py rename to seam/routes/models.py index 5219144..71d8be9 100644 --- a/seam/routes/types.py +++ b/seam/routes/models.py @@ -2,7 +2,7 @@ from typing_extensions import Self import abc from dataclasses import dataclass -from seam.routes.utils.deep_attr_dict import DeepAttrDict +from ..utils.deep_attr_dict import DeepAttrDict @dataclass diff --git a/seam/routes/networks.py b/seam/routes/networks.py index 325e82d..18ee48b 100644 --- a/seam/routes/networks.py +++ b/seam/routes/networks.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractNetworks, Network from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractNetworks, Network class Networks(AbstractNetworks): @@ -15,7 +15,7 @@ def get(self, *, network_id: str) -> Network: if network_id is not None: json_payload["network_id"] = network_id - res = self.seam.make_request("POST", "/networks/get", json=json_payload) + res = self.seam.client.post("/networks/get", json=json_payload) return Network.from_dict(res["network"]) @@ -24,6 +24,6 @@ def list( ) -> List[Network]: json_payload = {} - res = self.seam.make_request("POST", "/networks/list", json=json_payload) + res = self.seam.client.post("/networks/list", json=json_payload) return [Network.from_dict(item) for item in res["networks"]] diff --git a/seam/routes/noise_sensors.py b/seam/routes/noise_sensors.py index afbd775..fefabef 100644 --- a/seam/routes/noise_sensors.py +++ b/seam/routes/noise_sensors.py @@ -1,8 +1,8 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractNoiseSensors from typing import Optional, Any, List, Dict, Union -from seam.routes.noise_sensors_noise_thresholds import NoiseSensorsNoiseThresholds -from seam.routes.noise_sensors_simulate import NoiseSensorsSimulate +from ..models import AbstractSeam as Seam +from .models import AbstractNoiseSensors +from .noise_sensors_noise_thresholds import NoiseSensorsNoiseThresholds +from .noise_sensors_simulate import NoiseSensorsSimulate class NoiseSensors(AbstractNoiseSensors): diff --git a/seam/routes/noise_sensors_noise_thresholds.py b/seam/routes/noise_sensors_noise_thresholds.py index 09aca91..588ecab 100644 --- a/seam/routes/noise_sensors_noise_thresholds.py +++ b/seam/routes/noise_sensors_noise_thresholds.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractNoiseSensorsNoiseThresholds, NoiseThreshold from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractNoiseSensorsNoiseThresholds, NoiseThreshold class NoiseSensorsNoiseThresholds(AbstractNoiseSensorsNoiseThresholds): @@ -37,8 +37,9 @@ def create( if sync is not None: json_payload["sync"] = sync - res = self.seam.make_request( - "POST", "/noise_sensors/noise_thresholds/create", json=json_payload + res = self.seam.client.post( + "/noise_sensors/noise_thresholds/create", + json=json_payload, ) return NoiseThreshold.from_dict(res["noise_threshold"]) @@ -55,8 +56,9 @@ def delete( if sync is not None: json_payload["sync"] = sync - self.seam.make_request( - "POST", "/noise_sensors/noise_thresholds/delete", json=json_payload + self.seam.client.post( + "/noise_sensors/noise_thresholds/delete", + json=json_payload, ) return None @@ -67,8 +69,9 @@ def get(self, *, noise_threshold_id: str) -> NoiseThreshold: if noise_threshold_id is not None: json_payload["noise_threshold_id"] = noise_threshold_id - res = self.seam.make_request( - "POST", "/noise_sensors/noise_thresholds/get", json=json_payload + res = self.seam.client.post( + "/noise_sensors/noise_thresholds/get", + json=json_payload, ) return NoiseThreshold.from_dict(res["noise_threshold"]) @@ -83,8 +86,9 @@ def list( if is_programmed is not None: json_payload["is_programmed"] = is_programmed - res = self.seam.make_request( - "POST", "/noise_sensors/noise_thresholds/list", json=json_payload + res = self.seam.client.post( + "/noise_sensors/noise_thresholds/list", + json=json_payload, ) return [NoiseThreshold.from_dict(item) for item in res["noise_thresholds"]] @@ -120,8 +124,9 @@ def update( if sync is not None: json_payload["sync"] = sync - self.seam.make_request( - "POST", "/noise_sensors/noise_thresholds/update", json=json_payload + self.seam.client.post( + "/noise_sensors/noise_thresholds/update", + json=json_payload, ) return None diff --git a/seam/routes/noise_sensors_simulate.py b/seam/routes/noise_sensors_simulate.py index 001fcb6..c79c548 100644 --- a/seam/routes/noise_sensors_simulate.py +++ b/seam/routes/noise_sensors_simulate.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractNoiseSensorsSimulate from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractNoiseSensorsSimulate class NoiseSensorsSimulate(AbstractNoiseSensorsSimulate): @@ -15,8 +15,9 @@ def trigger_noise_threshold(self, *, device_id: str) -> None: if device_id is not None: json_payload["device_id"] = device_id - self.seam.make_request( - "POST", "/noise_sensors/simulate/trigger_noise_threshold", json=json_payload + self.seam.client.post( + "/noise_sensors/simulate/trigger_noise_threshold", + json=json_payload, ) return None diff --git a/seam/routes/phones.py b/seam/routes/phones.py index 8350159..b957f5e 100644 --- a/seam/routes/phones.py +++ b/seam/routes/phones.py @@ -1,7 +1,7 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractPhones, Phone from typing import Optional, Any, List, Dict, Union -from seam.routes.phones_simulate import PhonesSimulate +from ..models import AbstractSeam as Seam +from .models import AbstractPhones, Phone +from .phones_simulate import PhonesSimulate class Phones(AbstractPhones): @@ -21,7 +21,7 @@ def deactivate(self, *, device_id: str) -> None: if device_id is not None: json_payload["device_id"] = device_id - self.seam.make_request("POST", "/phones/deactivate", json=json_payload) + self.seam.client.post("/phones/deactivate", json=json_payload) return None @@ -31,6 +31,6 @@ def list(self, *, owner_user_identity_id: Optional[str] = None) -> List[Phone]: if owner_user_identity_id is not None: json_payload["owner_user_identity_id"] = owner_user_identity_id - res = self.seam.make_request("POST", "/phones/list", json=json_payload) + res = self.seam.client.post("/phones/list", json=json_payload) return [Phone.from_dict(item) for item in res["phones"]] diff --git a/seam/routes/phones_simulate.py b/seam/routes/phones_simulate.py index f302435..4e383f0 100644 --- a/seam/routes/phones_simulate.py +++ b/seam/routes/phones_simulate.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractPhonesSimulate, Phone from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractPhonesSimulate, Phone class PhonesSimulate(AbstractPhonesSimulate): @@ -28,8 +28,9 @@ def create_sandbox_phone( if phone_metadata is not None: json_payload["phone_metadata"] = phone_metadata - res = self.seam.make_request( - "POST", "/phones/simulate/create_sandbox_phone", json=json_payload + res = self.seam.client.post( + "/phones/simulate/create_sandbox_phone", + json=json_payload, ) return Phone.from_dict(res["phone"]) diff --git a/seam/routes/thermostats.py b/seam/routes/thermostats.py index b54fddc..3543b2e 100644 --- a/seam/routes/thermostats.py +++ b/seam/routes/thermostats.py @@ -1,9 +1,7 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractThermostats, ActionAttempt, Device from typing import Optional, Any, List, Dict, Union -from seam.routes.thermostats_climate_setting_schedules import ( - ThermostatsClimateSettingSchedules, -) +from ..models import AbstractSeam as Seam +from .models import AbstractThermostats, ActionAttempt, Device +from .thermostats_climate_setting_schedules import ThermostatsClimateSettingSchedules class Thermostats(AbstractThermostats): @@ -37,7 +35,7 @@ def cool( if sync is not None: json_payload["sync"] = sync - res = self.seam.make_request("POST", "/thermostats/cool", json=json_payload) + res = self.seam.client.post("/thermostats/cool", json=json_payload) return self.seam.action_attempts.decide_and_wait( action_attempt=ActionAttempt.from_dict(res["action_attempt"]), @@ -54,7 +52,7 @@ def get( if name is not None: json_payload["name"] = name - res = self.seam.make_request("POST", "/thermostats/get", json=json_payload) + res = self.seam.client.post("/thermostats/get", json=json_payload) return Device.from_dict(res["thermostat"]) @@ -78,7 +76,7 @@ def heat( if sync is not None: json_payload["sync"] = sync - res = self.seam.make_request("POST", "/thermostats/heat", json=json_payload) + res = self.seam.client.post("/thermostats/heat", json=json_payload) return self.seam.action_attempts.decide_and_wait( action_attempt=ActionAttempt.from_dict(res["action_attempt"]), @@ -111,9 +109,7 @@ def heat_cool( if sync is not None: json_payload["sync"] = sync - res = self.seam.make_request( - "POST", "/thermostats/heat_cool", json=json_payload - ) + res = self.seam.client.post("/thermostats/heat_cool", json=json_payload) return self.seam.action_attempts.decide_and_wait( action_attempt=ActionAttempt.from_dict(res["action_attempt"]), @@ -166,7 +162,7 @@ def list( if user_identifier_key is not None: json_payload["user_identifier_key"] = user_identifier_key - res = self.seam.make_request("POST", "/thermostats/list", json=json_payload) + res = self.seam.client.post("/thermostats/list", json=json_payload) return [Device.from_dict(item) for item in res["thermostats"]] @@ -184,7 +180,7 @@ def off( if sync is not None: json_payload["sync"] = sync - res = self.seam.make_request("POST", "/thermostats/off", json=json_payload) + res = self.seam.client.post("/thermostats/off", json=json_payload) return self.seam.action_attempts.decide_and_wait( action_attempt=ActionAttempt.from_dict(res["action_attempt"]), @@ -211,9 +207,7 @@ def set_fan_mode( if sync is not None: json_payload["sync"] = sync - res = self.seam.make_request( - "POST", "/thermostats/set_fan_mode", json=json_payload - ) + res = self.seam.client.post("/thermostats/set_fan_mode", json=json_payload) return self.seam.action_attempts.decide_and_wait( action_attempt=ActionAttempt.from_dict(res["action_attempt"]), @@ -230,6 +224,6 @@ def update( if device_id is not None: json_payload["device_id"] = device_id - self.seam.make_request("POST", "/thermostats/update", json=json_payload) + self.seam.client.post("/thermostats/update", json=json_payload) return None diff --git a/seam/routes/thermostats_climate_setting_schedules.py b/seam/routes/thermostats_climate_setting_schedules.py index 30e6a03..b9e9b26 100644 --- a/seam/routes/thermostats_climate_setting_schedules.py +++ b/seam/routes/thermostats_climate_setting_schedules.py @@ -1,9 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import ( - AbstractThermostatsClimateSettingSchedules, - ClimateSettingSchedule, -) from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractThermostatsClimateSettingSchedules, ClimateSettingSchedule class ThermostatsClimateSettingSchedules(AbstractThermostatsClimateSettingSchedules): @@ -58,8 +55,9 @@ def create( if schedule_type is not None: json_payload["schedule_type"] = schedule_type - res = self.seam.make_request( - "POST", "/thermostats/climate_setting_schedules/create", json=json_payload + res = self.seam.client.post( + "/thermostats/climate_setting_schedules/create", + json=json_payload, ) return ClimateSettingSchedule.from_dict(res["climate_setting_schedule"]) @@ -70,8 +68,9 @@ def delete(self, *, climate_setting_schedule_id: str) -> None: if climate_setting_schedule_id is not None: json_payload["climate_setting_schedule_id"] = climate_setting_schedule_id - self.seam.make_request( - "POST", "/thermostats/climate_setting_schedules/delete", json=json_payload + self.seam.client.post( + "/thermostats/climate_setting_schedules/delete", + json=json_payload, ) return None @@ -89,8 +88,9 @@ def get( if device_id is not None: json_payload["device_id"] = device_id - res = self.seam.make_request( - "POST", "/thermostats/climate_setting_schedules/get", json=json_payload + res = self.seam.client.post( + "/thermostats/climate_setting_schedules/get", + json=json_payload, ) return ClimateSettingSchedule.from_dict(res["climate_setting_schedule"]) @@ -105,8 +105,9 @@ def list( if user_identifier_key is not None: json_payload["user_identifier_key"] = user_identifier_key - res = self.seam.make_request( - "POST", "/thermostats/climate_setting_schedules/list", json=json_payload + res = self.seam.client.post( + "/thermostats/climate_setting_schedules/list", + json=json_payload, ) return [ @@ -160,8 +161,9 @@ def update( if schedule_type is not None: json_payload["schedule_type"] = schedule_type - self.seam.make_request( - "POST", "/thermostats/climate_setting_schedules/update", json=json_payload + self.seam.client.post( + "/thermostats/climate_setting_schedules/update", + json=json_payload, ) return None diff --git a/seam/routes/user_identities.py b/seam/routes/user_identities.py index fe186c9..fe06462 100644 --- a/seam/routes/user_identities.py +++ b/seam/routes/user_identities.py @@ -1,15 +1,7 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import ( - AbstractUserIdentities, - UserIdentity, - Device, - AcsSystem, - AcsUser, -) from typing import Optional, Any, List, Dict, Union -from seam.routes.user_identities_enrollment_automations import ( - UserIdentitiesEnrollmentAutomations, -) +from ..models import AbstractSeam as Seam +from .models import AbstractUserIdentities, UserIdentity, Device, AcsSystem, AcsUser +from .user_identities_enrollment_automations import UserIdentitiesEnrollmentAutomations class UserIdentities(AbstractUserIdentities): @@ -31,9 +23,7 @@ def add_acs_user(self, *, acs_user_id: str, user_identity_id: str) -> None: if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id - self.seam.make_request( - "POST", "/user_identities/add_acs_user", json=json_payload - ) + self.seam.client.post("/user_identities/add_acs_user", json=json_payload) return None @@ -56,9 +46,7 @@ def create( if user_identity_key is not None: json_payload["user_identity_key"] = user_identity_key - res = self.seam.make_request( - "POST", "/user_identities/create", json=json_payload - ) + res = self.seam.client.post("/user_identities/create", json=json_payload) return UserIdentity.from_dict(res["user_identity"]) @@ -68,7 +56,7 @@ def delete(self, *, user_identity_id: str) -> None: if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id - self.seam.make_request("POST", "/user_identities/delete", json=json_payload) + self.seam.client.post("/user_identities/delete", json=json_payload) return None @@ -85,7 +73,7 @@ def get( if user_identity_key is not None: json_payload["user_identity_key"] = user_identity_key - res = self.seam.make_request("POST", "/user_identities/get", json=json_payload) + res = self.seam.client.post("/user_identities/get", json=json_payload) return UserIdentity.from_dict(res["user_identity"]) @@ -97,8 +85,9 @@ def grant_access_to_device(self, *, device_id: str, user_identity_id: str) -> No if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id - self.seam.make_request( - "POST", "/user_identities/grant_access_to_device", json=json_payload + self.seam.client.post( + "/user_identities/grant_access_to_device", + json=json_payload, ) return None @@ -113,7 +102,7 @@ def list( credential_manager_acs_system_id ) - res = self.seam.make_request("POST", "/user_identities/list", json=json_payload) + res = self.seam.client.post("/user_identities/list", json=json_payload) return [UserIdentity.from_dict(item) for item in res["user_identities"]] @@ -123,8 +112,9 @@ def list_accessible_devices(self, *, user_identity_id: str) -> List[Device]: if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id - res = self.seam.make_request( - "POST", "/user_identities/list_accessible_devices", json=json_payload + res = self.seam.client.post( + "/user_identities/list_accessible_devices", + json=json_payload, ) return [Device.from_dict(item) for item in res["devices"]] @@ -135,8 +125,8 @@ def list_acs_systems(self, *, user_identity_id: str) -> List[AcsSystem]: if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id - res = self.seam.make_request( - "POST", "/user_identities/list_acs_systems", json=json_payload + res = self.seam.client.post( + "/user_identities/list_acs_systems", json=json_payload ) return [AcsSystem.from_dict(item) for item in res["acs_systems"]] @@ -147,8 +137,8 @@ def list_acs_users(self, *, user_identity_id: str) -> List[AcsUser]: if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id - res = self.seam.make_request( - "POST", "/user_identities/list_acs_users", json=json_payload + res = self.seam.client.post( + "/user_identities/list_acs_users", json=json_payload ) return [AcsUser.from_dict(item) for item in res["acs_users"]] @@ -161,9 +151,7 @@ def remove_acs_user(self, *, acs_user_id: str, user_identity_id: str) -> None: if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id - self.seam.make_request( - "POST", "/user_identities/remove_acs_user", json=json_payload - ) + self.seam.client.post("/user_identities/remove_acs_user", json=json_payload) return None @@ -175,8 +163,9 @@ def revoke_access_to_device(self, *, device_id: str, user_identity_id: str) -> N if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id - self.seam.make_request( - "POST", "/user_identities/revoke_access_to_device", json=json_payload + self.seam.client.post( + "/user_identities/revoke_access_to_device", + json=json_payload, ) return None @@ -203,6 +192,6 @@ def update( if user_identity_key is not None: json_payload["user_identity_key"] = user_identity_key - self.seam.make_request("POST", "/user_identities/update", json=json_payload) + self.seam.client.post("/user_identities/update", json=json_payload) return None diff --git a/seam/routes/user_identities_enrollment_automations.py b/seam/routes/user_identities_enrollment_automations.py index dce3940..04e0151 100644 --- a/seam/routes/user_identities_enrollment_automations.py +++ b/seam/routes/user_identities_enrollment_automations.py @@ -1,9 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import ( - AbstractUserIdentitiesEnrollmentAutomations, - EnrollmentAutomation, -) from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractUserIdentitiesEnrollmentAutomations, EnrollmentAutomation class UserIdentitiesEnrollmentAutomations(AbstractUserIdentitiesEnrollmentAutomations): @@ -18,8 +15,9 @@ def delete(self, *, enrollment_automation_id: str) -> None: if enrollment_automation_id is not None: json_payload["enrollment_automation_id"] = enrollment_automation_id - self.seam.make_request( - "POST", "/user_identities/enrollment_automations/delete", json=json_payload + self.seam.client.post( + "/user_identities/enrollment_automations/delete", + json=json_payload, ) return None @@ -30,8 +28,9 @@ def get(self, *, enrollment_automation_id: str) -> EnrollmentAutomation: if enrollment_automation_id is not None: json_payload["enrollment_automation_id"] = enrollment_automation_id - res = self.seam.make_request( - "POST", "/user_identities/enrollment_automations/get", json=json_payload + res = self.seam.client.post( + "/user_identities/enrollment_automations/get", + json=json_payload, ) return EnrollmentAutomation.from_dict(res["enrollment_automation"]) @@ -64,8 +63,9 @@ def launch( credential_manager_acs_user_id ) - self.seam.make_request( - "POST", "/user_identities/enrollment_automations/launch", json=json_payload + self.seam.client.post( + "/user_identities/enrollment_automations/launch", + json=json_payload, ) return None @@ -76,8 +76,9 @@ def list(self, *, user_identity_id: str) -> List[EnrollmentAutomation]: if user_identity_id is not None: json_payload["user_identity_id"] = user_identity_id - res = self.seam.make_request( - "POST", "/user_identities/enrollment_automations/list", json=json_payload + res = self.seam.client.post( + "/user_identities/enrollment_automations/list", + json=json_payload, ) return [ diff --git a/seam/routes/webhooks.py b/seam/routes/webhooks.py index d764eff..d6b2959 100644 --- a/seam/routes/webhooks.py +++ b/seam/routes/webhooks.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractWebhooks, Webhook from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractWebhooks, Webhook class Webhooks(AbstractWebhooks): @@ -17,7 +17,7 @@ def create(self, *, url: str, event_types: Optional[List[str]] = None) -> Webhoo if event_types is not None: json_payload["event_types"] = event_types - res = self.seam.make_request("POST", "/webhooks/create", json=json_payload) + res = self.seam.client.post("/webhooks/create", json=json_payload) return Webhook.from_dict(res["webhook"]) @@ -27,7 +27,7 @@ def delete(self, *, webhook_id: str) -> None: if webhook_id is not None: json_payload["webhook_id"] = webhook_id - self.seam.make_request("POST", "/webhooks/delete", json=json_payload) + self.seam.client.post("/webhooks/delete", json=json_payload) return None @@ -37,7 +37,7 @@ def get(self, *, webhook_id: str) -> Webhook: if webhook_id is not None: json_payload["webhook_id"] = webhook_id - res = self.seam.make_request("POST", "/webhooks/get", json=json_payload) + res = self.seam.client.post("/webhooks/get", json=json_payload) return Webhook.from_dict(res["webhook"]) @@ -46,7 +46,7 @@ def list( ) -> List[Webhook]: json_payload = {} - res = self.seam.make_request("POST", "/webhooks/list", json=json_payload) + res = self.seam.client.post("/webhooks/list", json=json_payload) return [Webhook.from_dict(item) for item in res["webhooks"]] @@ -58,6 +58,6 @@ def update(self, *, event_types: List[str], webhook_id: str) -> None: if webhook_id is not None: json_payload["webhook_id"] = webhook_id - self.seam.make_request("POST", "/webhooks/update", json=json_payload) + self.seam.client.post("/webhooks/update", json=json_payload) return None diff --git a/seam/routes/workspaces.py b/seam/routes/workspaces.py index 660d94b..e2a13d5 100644 --- a/seam/routes/workspaces.py +++ b/seam/routes/workspaces.py @@ -1,6 +1,6 @@ -from seam.types import AbstractSeam as Seam -from seam.routes.types import AbstractWorkspaces, Workspace, ActionAttempt from typing import Optional, Any, List, Dict, Union +from ..models import AbstractSeam as Seam +from .models import AbstractWorkspaces, Workspace, ActionAttempt class Workspaces(AbstractWorkspaces): @@ -31,7 +31,7 @@ def create( if webview_primary_button_color is not None: json_payload["webview_primary_button_color"] = webview_primary_button_color - res = self.seam.make_request("POST", "/workspaces/create", json=json_payload) + res = self.seam.client.post("/workspaces/create", json=json_payload) return Workspace.from_dict(res["workspace"]) @@ -40,7 +40,7 @@ def get( ) -> Workspace: json_payload = {} - res = self.seam.make_request("POST", "/workspaces/get", json=json_payload) + res = self.seam.client.post("/workspaces/get", json=json_payload) return Workspace.from_dict(res["workspace"]) @@ -49,7 +49,7 @@ def list( ) -> List[Workspace]: json_payload = {} - res = self.seam.make_request("POST", "/workspaces/list", json=json_payload) + res = self.seam.client.post("/workspaces/list", json=json_payload) return [Workspace.from_dict(item) for item in res["workspaces"]] @@ -58,9 +58,7 @@ def reset_sandbox( ) -> ActionAttempt: json_payload = {} - res = self.seam.make_request( - "POST", "/workspaces/reset_sandbox", json=json_payload - ) + res = self.seam.client.post("/workspaces/reset_sandbox", json=json_payload) return self.seam.action_attempts.decide_and_wait( action_attempt=ActionAttempt.from_dict(res["action_attempt"]), diff --git a/seam/seam.py b/seam/seam.py index 3cb5cb8..ea1b181 100644 --- a/seam/seam.py +++ b/seam/seam.py @@ -1,14 +1,16 @@ -from typing import Optional, Union, Dict +from typing import Any, Optional, Union, Dict +import niquests as requests from typing_extensions import Self from .constants import LTS_VERSION from .parse_options import parse_options -from .request import RequestMixin -from .routes.routes import Routes -from .types import AbstractSeam +from .routes import Routes +from .models import AbstractSeam +from .request import SeamHttpClient +from .routes import Routes -class Seam(AbstractSeam, RequestMixin): +class Seam(AbstractSeam): """ Initial Seam class used to interact with Seam API """ @@ -23,6 +25,8 @@ def __init__( workspace_id: Optional[str] = None, endpoint: Optional[str] = None, wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = False, + client: Optional[requests.Session] = None, + client_options: Optional[Dict[str, Any]] = None, ): """ Parameters @@ -37,6 +41,10 @@ def __init__( The API endpoint to which the request should be sent. wait_for_action_attempt : bool or dict, optional Controls whether to wait for an action attempt to complete, either as a boolean or as a dictionary specifying `timeout` and `poll_interval`. Defaults to `False`. + client : requests.Session, optional + A pre-configured requests session to be used for making HTTP requests. If not provided, a new `SeamHttpClient` instance will be created using the `client_options` and other relevant parameters. + client_options : dict, optional + A dictionary of options that will be passed to the `SeamHttpClient` constructor when initializing a new requests session client. This allows for customization of the HTTP client, such as setting additional headers or configuring timeouts. For detailed information on available options, refer to the niquests library [repo](https://github.com/jawah/niquests). If client is provided, this parameter will be ignored. """ Routes.__init__(self) @@ -49,8 +57,13 @@ def __init__( workspace_id=workspace_id, endpoint=endpoint, ) - self._auth_headers = auth_headers - self._endpoint = endpoint + + if client_options is None: + client_options = {} + + self.client = client or SeamHttpClient( + base_url=endpoint, auth_headers=auth_headers, **client_options + ) @classmethod def from_api_key( diff --git a/seam/seam_multi_workspace.py b/seam/seam_multi_workspace.py index d5e240f..ee30b21 100644 --- a/seam/seam_multi_workspace.py +++ b/seam/seam_multi_workspace.py @@ -1,11 +1,12 @@ -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Union +import niquests as requests from typing_extensions import Self from .auth import get_auth_headers_for_multi_workspace_personal_access_token from .constants import LTS_VERSION from .options import get_endpoint -from .request import RequestMixin -from .types import AbstractSeamMultiWorkspace +from .request import SeamHttpClient +from .models import AbstractSeamMultiWorkspace from .routes.workspaces import Workspaces @@ -22,7 +23,7 @@ def create(self, **kwargs): return self._workspaces.create(**kwargs) -class SeamMultiWorkspace(AbstractSeamMultiWorkspace, RequestMixin): +class SeamMultiWorkspace(AbstractSeamMultiWorkspace): """ Seam class used to interact with Seam API without being scoped to any specific workspace. """ @@ -35,6 +36,8 @@ def __init__( *, endpoint: Optional[str] = None, wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = False, + client: Optional[requests.Session] = None, + client_options: Optional[Dict[str, Any]] = None, ): """ Parameters @@ -45,14 +48,25 @@ def __init__( The API endpoint to which the request should be sent. wait_for_action_attempt : bool or dict, optional Controls whether to wait for an action attempt to complete, either as a boolean or as a dictionary specifying `timeout` and `poll_interval`. Defaults to `False`. + client : requests.Session, optional + A pre-configured requests session to be used for making HTTP requests. If not provided, a new `SeamHttpClient` instance will be created using the `client_options` and other relevant parameters. + client_options : dict, optional + A dictionary of options that will be passed to the `SeamHttpClient` constructor when initializing a new requests session client. This allows for customization of the HTTP client, such as setting additional headers or configuring timeouts. For detailed information on available options, refer to the niquests library [repo](https://github.com/jawah/niquests). If client is provided, this parameter will be ignored. """ self.lts_version = SeamMultiWorkspace.lts_version self.wait_for_action_attempt = wait_for_action_attempt - self._auth_headers = get_auth_headers_for_multi_workspace_personal_access_token( + auth_headers = get_auth_headers_for_multi_workspace_personal_access_token( personal_access_token ) - self._endpoint = get_endpoint(endpoint) + endpoint = get_endpoint(endpoint) + + if client_options is None: + client_options = {} + + self.client = client or SeamHttpClient( + base_url=endpoint, auth_headers=auth_headers, **client_options + ) self._workspaces = Workspaces(seam=self) self.workspaces = WorkspacesProxy(self._workspaces) diff --git a/seam/routes/utils/deep_attr_dict.py b/seam/utils/deep_attr_dict.py similarity index 100% rename from seam/routes/utils/deep_attr_dict.py rename to seam/utils/deep_attr_dict.py diff --git a/test/access_codes/test_access_codes.py b/test/access_codes/test_access_codes.py index f077e3e..e1697a1 100644 --- a/test/access_codes/test_access_codes.py +++ b/test/access_codes/test_access_codes.py @@ -1,5 +1,4 @@ -from seam import Seam -from seam.types import SeamHttpApiError +from seam import Seam, SeamHttpApiError import pytest diff --git a/test/connected_accounts/test_connected_accounts.py b/test/connected_accounts/test_connected_accounts.py index 5ee9ccb..89d0fd0 100644 --- a/test/connected_accounts/test_connected_accounts.py +++ b/test/connected_accounts/test_connected_accounts.py @@ -1,5 +1,4 @@ -from seam import Seam -from seam.types import SeamHttpApiError +from seam import Seam, SeamHttpApiError EMAIL = "john@example.com" diff --git a/test/devices/test_devices.py b/test/devices/test_devices.py index 83eaf42..3dc48c9 100644 --- a/test/devices/test_devices.py +++ b/test/devices/test_devices.py @@ -1,5 +1,4 @@ -from seam import Seam -from seam.types import SeamHttpApiError +from seam import Seam, SeamHttpApiError def test_devices(seam: Seam): diff --git a/test/events/test_events.py b/test/events/test_events.py index b860909..3b1ecc3 100644 --- a/test/events/test_events.py +++ b/test/events/test_events.py @@ -1,7 +1,5 @@ -import time -from seam import Seam +from seam import Seam, SeamHttpApiError -from seam.types import SeamHttpApiError SINCE = "2021-01-01T00:00:00.000Z" EVENT_TYPE = "device.connected" diff --git a/test/noise_sensors/noise_thresholds/test_noise_thresholds.py b/test/noise_sensors/noise_thresholds/test_noise_thresholds.py index bc8102c..01357b7 100644 --- a/test/noise_sensors/noise_thresholds/test_noise_thresholds.py +++ b/test/noise_sensors/noise_thresholds/test_noise_thresholds.py @@ -1,7 +1,4 @@ -import time from seam import Seam -from seam.types import SeamHttpApiError -import pytest def test_noise_thresholds(seam: Seam): diff --git a/test/utils/test_deep_attr_dict.py b/test/utils/test_deep_attr_dict.py index 48767fe..afdc331 100644 --- a/test/utils/test_deep_attr_dict.py +++ b/test/utils/test_deep_attr_dict.py @@ -1,4 +1,4 @@ -from seam.routes.utils.deep_attr_dict import DeepAttrDict +from seam.utils.deep_attr_dict import DeepAttrDict def test_deep_attr_dict(): diff --git a/test/workspaces/test_workspaces_create.py b/test/workspaces/test_workspaces_create.py index f755022..1f5ebdf 100644 --- a/test/workspaces/test_workspaces_create.py +++ b/test/workspaces/test_workspaces_create.py @@ -1,7 +1,6 @@ import random import string -from seam import Seam -from seam.seam_multi_workspace import SeamMultiWorkspace +from seam import Seam, SeamMultiWorkspace def test_workspaces_create(seam: Seam):