diff --git a/Pipfile b/Pipfile index 590da12..30bbc83 100644 --- a/Pipfile +++ b/Pipfile @@ -5,6 +5,8 @@ name = "pypi" [packages] sentry-sdk = "*" +requests = "*" + [dev-packages] bandit = "*" @@ -14,6 +16,8 @@ flake8 = "*" isort = "*" mypy = "*" pytest = "*" +requests-mock = "*" +types-requests = "*" [requires] python_version = "3.9" diff --git a/Pipfile.lock b/Pipfile.lock index 97ef04f..3d8aa40 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "deace4d7b00d7e265c99030fdc88b9eeea820f245701f01153a510446ff93e8c" + "sha256": "be10cb27051fdb39e8d57d4f5c2fd7d3a16f2f1fb2b13c0e7870129c388b02ca" }, "pipfile-spec": 6, "requires": { @@ -18,37 +18,146 @@ "default": { "certifi": { "hashes": [ - "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d", - "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412" + "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", + "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" ], "markers": "python_version >= '3.6'", - "version": "==2022.6.15" + "version": "==2022.12.7" + }, + "charset-normalizer": { + "hashes": [ + "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b", + "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42", + "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d", + "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b", + "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a", + "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59", + "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154", + "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1", + "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c", + "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a", + "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d", + "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6", + "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b", + "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b", + "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783", + "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5", + "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918", + "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555", + "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639", + "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786", + "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e", + "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed", + "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820", + "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8", + "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3", + "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541", + "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14", + "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be", + "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e", + "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76", + "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b", + "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c", + "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b", + "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3", + "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc", + "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6", + "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59", + "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4", + "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d", + "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d", + "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3", + "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a", + "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea", + "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6", + "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e", + "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603", + "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24", + "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a", + "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58", + "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678", + "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a", + "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c", + "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6", + "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18", + "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174", + "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317", + "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f", + "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc", + "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837", + "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41", + "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c", + "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579", + "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753", + "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8", + "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291", + "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087", + "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866", + "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3", + "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d", + "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1", + "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca", + "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e", + "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db", + "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72", + "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d", + "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc", + "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539", + "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d", + "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af", + "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b", + "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602", + "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f", + "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478", + "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c", + "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e", + "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479", + "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7", + "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8" + ], + "version": "==3.0.1" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" + }, + "requests": { + "hashes": [ + "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa", + "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf" + ], + "index": "pypi", + "version": "==2.28.2" }, "sentry-sdk": { "hashes": [ - "sha256:60b13757d6344a94bf0ccb3c0a006c4de77daab09871b30fbbd05d5ec24e54fb", - "sha256:f185c53496d79b280fe5d9d21e6572aee1ab802d3354eb12314d216cfbaa8d30" + "sha256:273fe05adf052b40fd19f6d4b9a5556316807246bd817e5e3482930730726bb0", + "sha256:72c00322217d813cf493fe76590b23a757e063ff62fec59299f4af7201dd4448" ], "index": "pypi", - "version": "==1.9.0" + "version": "==1.14.0" }, "urllib3": { "hashes": [ - "sha256:c33ccba33c819596124764c23a97d25f32b28433ba0dedeb77d873a38722c9bc", - "sha256:ea6e8fb210b19d950fab93b60c9009226c63a28808bc8386e05301e25883ac0a" + "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", + "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'", - "version": "==1.26.11" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.14" } }, "develop": { "attrs": { "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" + "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836", + "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99" ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" + "markers": "python_version >= '3.6'", + "version": "==22.2.0" }, "bandit": { "hashes": [ @@ -60,32 +169,122 @@ }, "black": { "hashes": [ - "sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90", - "sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c", - "sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78", - "sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4", - "sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee", - "sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e", - "sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e", - "sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6", - "sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9", - "sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c", - "sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256", - "sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f", - "sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2", - "sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c", - "sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b", - "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807", - "sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf", - "sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def", - "sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad", - "sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d", - "sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849", - "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69", - "sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666" + "sha256:101c69b23df9b44247bd88e1d7e90154336ac4992502d4197bdac35dd7ee3320", + "sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351", + "sha256:1f58cbe16dfe8c12b7434e50ff889fa479072096d79f0a7f25e4ab8e94cd8350", + "sha256:229351e5a18ca30f447bf724d007f890f97e13af070bb6ad4c0a441cd7596a2f", + "sha256:436cc9167dd28040ad90d3b404aec22cedf24a6e4d7de221bec2730ec0c97bcf", + "sha256:559c7a1ba9a006226f09e4916060982fd27334ae1998e7a38b3f33a37f7a2148", + "sha256:7412e75863aa5c5411886804678b7d083c7c28421210180d67dfd8cf1221e1f4", + "sha256:77d86c9f3db9b1bf6761244bc0b3572a546f5fe37917a044e02f3166d5aafa7d", + "sha256:82d9fe8fee3401e02e79767016b4907820a7dc28d70d137eb397b92ef3cc5bfc", + "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d", + "sha256:c116eed0efb9ff870ded8b62fe9f28dd61ef6e9ddd28d83d7d264a38417dcee2", + "sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f" ], "index": "pypi", - "version": "==22.6.0" + "version": "==22.12.0" + }, + "certifi": { + "hashes": [ + "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", + "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + ], + "markers": "python_version >= '3.6'", + "version": "==2022.12.7" + }, + "charset-normalizer": { + "hashes": [ + "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b", + "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42", + "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d", + "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b", + "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a", + "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59", + "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154", + "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1", + "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c", + "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a", + "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d", + "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6", + "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b", + "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b", + "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783", + "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5", + "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918", + "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555", + "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639", + "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786", + "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e", + "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed", + "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820", + "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8", + "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3", + "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541", + "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14", + "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be", + "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e", + "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76", + "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b", + "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c", + "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b", + "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3", + "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc", + "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6", + "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59", + "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4", + "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d", + "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d", + "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3", + "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a", + "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea", + "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6", + "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e", + "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603", + "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24", + "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a", + "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58", + "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678", + "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a", + "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c", + "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6", + "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18", + "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174", + "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317", + "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f", + "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc", + "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837", + "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41", + "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c", + "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579", + "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753", + "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8", + "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291", + "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087", + "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866", + "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3", + "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d", + "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1", + "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca", + "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e", + "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db", + "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72", + "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d", + "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc", + "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539", + "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d", + "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af", + "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b", + "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602", + "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f", + "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478", + "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c", + "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e", + "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479", + "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7", + "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8" + ], + "version": "==3.0.1" }, "click": { "hashes": [ @@ -97,89 +296,116 @@ }, "coverage": { "hashes": [ - "sha256:0895ea6e6f7f9939166cc835df8fa4599e2d9b759b02d1521b574e13b859ac32", - "sha256:0f211df2cba951ffcae210ee00e54921ab42e2b64e0bf2c0befc977377fb09b7", - "sha256:147605e1702d996279bb3cc3b164f408698850011210d133a2cb96a73a2f7996", - "sha256:24b04d305ea172ccb21bee5bacd559383cba2c6fcdef85b7701cf2de4188aa55", - "sha256:25b7ec944f114f70803d6529394b64f8749e93cbfac0fe6c5ea1b7e6c14e8a46", - "sha256:2b20286c2b726f94e766e86a3fddb7b7e37af5d0c635bdfa7e4399bc523563de", - "sha256:2dff52b3e7f76ada36f82124703f4953186d9029d00d6287f17c68a75e2e6039", - "sha256:2f8553878a24b00d5ab04b7a92a2af50409247ca5c4b7a2bf4eabe94ed20d3ee", - "sha256:3def6791adf580d66f025223078dc84c64696a26f174131059ce8e91452584e1", - "sha256:422fa44070b42fef9fb8dabd5af03861708cdd6deb69463adc2130b7bf81332f", - "sha256:4f89d8e03c8a3757aae65570d14033e8edf192ee9298303db15955cadcff0c63", - "sha256:5336e0352c0b12c7e72727d50ff02557005f79a0b8dcad9219c7c4940a930083", - "sha256:54d8d0e073a7f238f0666d3c7c0d37469b2aa43311e4024c925ee14f5d5a1cbe", - "sha256:5ef42e1db047ca42827a85e34abe973971c635f83aed49611b7f3ab49d0130f0", - "sha256:5f65e5d3ff2d895dab76b1faca4586b970a99b5d4b24e9aafffc0ce94a6022d6", - "sha256:6c3ccfe89c36f3e5b9837b9ee507472310164f352c9fe332120b764c9d60adbe", - "sha256:6d0b48aff8e9720bdec315d67723f0babd936a7211dc5df453ddf76f89c59933", - "sha256:6fe75dcfcb889b6800f072f2af5a331342d63d0c1b3d2bf0f7b4f6c353e8c9c0", - "sha256:79419370d6a637cb18553ecb25228893966bd7935a9120fa454e7076f13b627c", - "sha256:7bb00521ab4f99fdce2d5c05a91bddc0280f0afaee0e0a00425e28e209d4af07", - "sha256:80db4a47a199c4563d4a25919ff29c97c87569130375beca3483b41ad5f698e8", - "sha256:866ebf42b4c5dbafd64455b0a1cd5aa7b4837a894809413b930026c91e18090b", - "sha256:8af6c26ba8df6338e57bedbf916d76bdae6308e57fc8f14397f03b5da8622b4e", - "sha256:a13772c19619118903d65a91f1d5fea84be494d12fd406d06c849b00d31bf120", - "sha256:a697977157adc052284a7160569b36a8bbec09db3c3220642e6323b47cec090f", - "sha256:a9032f9b7d38bdf882ac9f66ebde3afb8145f0d4c24b2e600bc4c6304aafb87e", - "sha256:b5e28db9199dd3833cc8a07fa6cf429a01227b5d429facb56eccd765050c26cd", - "sha256:c77943ef768276b61c96a3eb854eba55633c7a3fddf0a79f82805f232326d33f", - "sha256:d230d333b0be8042ac34808ad722eabba30036232e7a6fb3e317c49f61c93386", - "sha256:d4548be38a1c810d79e097a38107b6bf2ff42151900e47d49635be69943763d8", - "sha256:d4e7ced84a11c10160c0697a6cc0b214a5d7ab21dfec1cd46e89fbf77cc66fae", - "sha256:d56f105592188ce7a797b2bd94b4a8cb2e36d5d9b0d8a1d2060ff2a71e6b9bbc", - "sha256:d714af0bdba67739598849c9f18efdcc5a0412f4993914a0ec5ce0f1e864d783", - "sha256:d774d9e97007b018a651eadc1b3970ed20237395527e22cbeb743d8e73e0563d", - "sha256:e0524adb49c716ca763dbc1d27bedce36b14f33e6b8af6dba56886476b42957c", - "sha256:e2618cb2cf5a7cc8d698306e42ebcacd02fb7ef8cfc18485c59394152c70be97", - "sha256:e36750fbbc422c1c46c9d13b937ab437138b998fe74a635ec88989afb57a3978", - "sha256:edfdabe7aa4f97ed2b9dd5dde52d2bb29cb466993bb9d612ddd10d0085a683cf", - "sha256:f22325010d8824594820d6ce84fa830838f581a7fd86a9235f0d2ed6deb61e29", - "sha256:f23876b018dfa5d3e98e96f5644b109090f16a4acb22064e0f06933663005d39", - "sha256:f7bd0ffbcd03dc39490a1f40b2669cc414fae0c4e16b77bb26806a4d0b7d1452" + "sha256:04481245ef966fbd24ae9b9e537ce899ae584d521dfbe78f89cad003c38ca2ab", + "sha256:0c45948f613d5d18c9ec5eaa203ce06a653334cf1bd47c783a12d0dd4fd9c851", + "sha256:10188fe543560ec4874f974b5305cd1a8bdcfa885ee00ea3a03733464c4ca265", + "sha256:218fe982371ac7387304153ecd51205f14e9d731b34fb0568181abaf7b443ba0", + "sha256:29571503c37f2ef2138a306d23e7270687c0efb9cab4bd8038d609b5c2393a3a", + "sha256:2a60d6513781e87047c3e630b33b4d1e89f39836dac6e069ffee28c4786715f5", + "sha256:2bf1d5f2084c3932b56b962a683074a3692bce7cabd3aa023c987a2a8e7612f6", + "sha256:3164d31078fa9efe406e198aecd2a02d32a62fecbdef74f76dad6a46c7e48311", + "sha256:32df215215f3af2c1617a55dbdfb403b772d463d54d219985ac7cd3bf124cada", + "sha256:33d1ae9d4079e05ac4cc1ef9e20c648f5afabf1a92adfaf2ccf509c50b85717f", + "sha256:33ff26d0f6cc3ca8de13d14fde1ff8efe1456b53e3f0273e63cc8b3c84a063d8", + "sha256:38da2db80cc505a611938d8624801158e409928b136c8916cd2e203970dde4dc", + "sha256:3b155caf3760408d1cb903b21e6a97ad4e2bdad43cbc265e3ce0afb8e0057e73", + "sha256:3b946bbcd5a8231383450b195cfb58cb01cbe7f8949f5758566b881df4b33baf", + "sha256:3baf5f126f30781b5e93dbefcc8271cb2491647f8283f20ac54d12161dff080e", + "sha256:4b14d5e09c656de5038a3f9bfe5228f53439282abcab87317c9f7f1acb280352", + "sha256:51b236e764840a6df0661b67e50697aaa0e7d4124ca95e5058fa3d7cbc240b7c", + "sha256:63ffd21aa133ff48c4dff7adcc46b7ec8b565491bfc371212122dd999812ea1c", + "sha256:6a43c7823cd7427b4ed763aa7fb63901ca8288591323b58c9cd6ec31ad910f3c", + "sha256:755e89e32376c850f826c425ece2c35a4fc266c081490eb0a841e7c1cb0d3bda", + "sha256:7a726d742816cb3a8973c8c9a97539c734b3a309345236cd533c4883dda05b8d", + "sha256:7c7c0d0827e853315c9bbd43c1162c006dd808dbbe297db7ae66cd17b07830f0", + "sha256:7ed681b0f8e8bcbbffa58ba26fcf5dbc8f79e7997595bf071ed5430d8c08d6f3", + "sha256:7ee5c9bb51695f80878faaa5598040dd6c9e172ddcf490382e8aedb8ec3fec8d", + "sha256:8361be1c2c073919500b6601220a6f2f98ea0b6d2fec5014c1d9cfa23dd07038", + "sha256:8ae125d1134bf236acba8b83e74c603d1b30e207266121e76484562bc816344c", + "sha256:9817733f0d3ea91bea80de0f79ef971ae94f81ca52f9b66500c6a2fea8e4b4f8", + "sha256:98b85dd86514d889a2e3dd22ab3c18c9d0019e696478391d86708b805f4ea0fa", + "sha256:9ccb092c9ede70b2517a57382a601619d20981f56f440eae7e4d7eaafd1d1d09", + "sha256:9d58885215094ab4a86a6aef044e42994a2bd76a446dc59b352622655ba6621b", + "sha256:b643cb30821e7570c0aaf54feaf0bfb630b79059f85741843e9dc23f33aaca2c", + "sha256:bc7c85a150501286f8b56bd8ed3aa4093f4b88fb68c0843d21ff9656f0009d6a", + "sha256:beeb129cacea34490ffd4d6153af70509aa3cda20fdda2ea1a2be870dfec8d52", + "sha256:c31b75ae466c053a98bf26843563b3b3517b8f37da4d47b1c582fdc703112bc3", + "sha256:c4e4881fa9e9667afcc742f0c244d9364d197490fbc91d12ac3b5de0bf2df146", + "sha256:c5b15ed7644ae4bee0ecf74fee95808dcc34ba6ace87e8dfbf5cb0dc20eab45a", + "sha256:d12d076582507ea460ea2a89a8c85cb558f83406c8a41dd641d7be9a32e1274f", + "sha256:d248cd4a92065a4d4543b8331660121b31c4148dd00a691bfb7a5cdc7483cfa4", + "sha256:d47dd659a4ee952e90dc56c97d78132573dc5c7b09d61b416a9deef4ebe01a0c", + "sha256:d4a5a5879a939cb84959d86869132b00176197ca561c664fc21478c1eee60d75", + "sha256:da9b41d4539eefd408c46725fb76ecba3a50a3367cafb7dea5f250d0653c1040", + "sha256:db61a79c07331e88b9a9974815c075fbd812bc9dbc4dc44b366b5368a2936063", + "sha256:ddb726cb861c3117a553f940372a495fe1078249ff5f8a5478c0576c7be12050", + "sha256:ded59300d6330be27bc6cf0b74b89ada58069ced87c48eaf9344e5e84b0072f7", + "sha256:e2617759031dae1bf183c16cef8fcfb3de7617f394c813fa5e8e46e9b82d4222", + "sha256:e5cdbb5cafcedea04924568d990e20ce7f1945a1dd54b560f879ee2d57226912", + "sha256:ec8e767f13be637d056f7e07e61d089e555f719b387a7070154ad80a0ff31801", + "sha256:ef382417db92ba23dfb5864a3fc9be27ea4894e86620d342a116b243ade5d35d", + "sha256:f2cba5c6db29ce991029b5e4ac51eb36774458f0a3b8d3137241b32d1bb91f06", + "sha256:f5b4198d85a3755d27e64c52f8c95d6333119e49fd001ae5798dac872c95e0f8", + "sha256:ffeeb38ee4a80a30a6877c5c4c359e5498eec095878f1581453202bfacc8fbc2" ], "index": "pypi", - "version": "==6.4.2" + "version": "==7.1.0" + }, + "exceptiongroup": { + "hashes": [ + "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e", + "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23" + ], + "markers": "python_version < '3.11'", + "version": "==1.1.0" }, "flake8": { "hashes": [ - "sha256:93aa565ae2f0316b95bb57a354f2b2d55ee8508e1fe1cb13b77b9c195b4a2537", - "sha256:b27fd7faa8d90aaae763664a489012292990388e5d3604f383b290caefbbc922" + "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7", + "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181" ], "index": "pypi", - "version": "==5.0.3" + "version": "==6.0.0" }, "gitdb": { "hashes": [ - "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd", - "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa" + "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a", + "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7" ], - "markers": "python_version >= '3.6'", - "version": "==4.0.9" + "markers": "python_version >= '3.7'", + "version": "==4.0.10" }, "gitpython": { "hashes": [ - "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704", - "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d" + "sha256:769c2d83e13f5d938b7688479da374c4e3d49f71549aaf462b646db9602ea6f8", + "sha256:cd455b0000615c60e286208ba540271af9fe531fa6a87cc590a7298785ab2882" ], "markers": "python_version >= '3.7'", - "version": "==3.1.27" + "version": "==3.1.30" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" }, "iniconfig": { "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" + "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", + "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" ], - "version": "==1.1.1" + "markers": "python_version >= '3.7'", + "version": "==2.0.0" }, "isort": { "hashes": [ - "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", - "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951" + "sha256:6db30c5ded9815d813932c04c2f85a360bcdd35fed496f4d8f35495ef0a261b6", + "sha256:c033fd0edb91000a7f09527fe5c75321878f98322a77ddcc81adbd83724afb7b" ], "index": "pypi", - "version": "==5.10.1" + "version": "==5.11.4" }, "mccabe": { "hashes": [ @@ -191,32 +417,39 @@ }, "mypy": { "hashes": [ - "sha256:02ef476f6dcb86e6f502ae39a16b93285fef97e7f1ff22932b657d1ef1f28655", - "sha256:0d054ef16b071149917085f51f89555a576e2618d5d9dd70bd6eea6410af3ac9", - "sha256:19830b7dba7d5356d3e26e2427a2ec91c994cd92d983142cbd025ebe81d69cf3", - "sha256:1f7656b69974a6933e987ee8ffb951d836272d6c0f81d727f1d0e2696074d9e6", - "sha256:23488a14a83bca6e54402c2e6435467a4138785df93ec85aeff64c6170077fb0", - "sha256:23c7ff43fff4b0df93a186581885c8512bc50fc4d4910e0f838e35d6bb6b5e58", - "sha256:25c5750ba5609a0c7550b73a33deb314ecfb559c350bb050b655505e8aed4103", - "sha256:2ad53cf9c3adc43cf3bea0a7d01a2f2e86db9fe7596dfecb4496a5dda63cbb09", - "sha256:3fa7a477b9900be9b7dd4bab30a12759e5abe9586574ceb944bc29cddf8f0417", - "sha256:40b0f21484238269ae6a57200c807d80debc6459d444c0489a102d7c6a75fa56", - "sha256:4b21e5b1a70dfb972490035128f305c39bc4bc253f34e96a4adf9127cf943eb2", - "sha256:5a361d92635ad4ada1b1b2d3630fc2f53f2127d51cf2def9db83cba32e47c856", - "sha256:77a514ea15d3007d33a9e2157b0ba9c267496acf12a7f2b9b9f8446337aac5b0", - "sha256:855048b6feb6dfe09d3353466004490b1872887150c5bb5caad7838b57328cc8", - "sha256:9796a2ba7b4b538649caa5cecd398d873f4022ed2333ffde58eaf604c4d2cb27", - "sha256:98e02d56ebe93981c41211c05adb630d1d26c14195d04d95e49cd97dbc046dc5", - "sha256:b793b899f7cf563b1e7044a5c97361196b938e92f0a4343a5d27966a53d2ec71", - "sha256:d1ea5d12c8e2d266b5fb8c7a5d2e9c0219fedfeb493b7ed60cd350322384ac27", - "sha256:d2022bfadb7a5c2ef410d6a7c9763188afdb7f3533f22a0a32be10d571ee4bbe", - "sha256:d3348e7eb2eea2472db611486846742d5d52d1290576de99d59edeb7cd4a42ca", - "sha256:d744f72eb39f69312bc6c2abf8ff6656973120e2eb3f3ec4f758ed47e414a4bf", - "sha256:ef943c72a786b0f8d90fd76e9b39ce81fb7171172daf84bf43eaf937e9f220a9", - "sha256:f2899a3cbd394da157194f913a931edfd4be5f274a88041c9dc2d9cdcb1c315c" + "sha256:0714258640194d75677e86c786e80ccf294972cc76885d3ebbb560f11db0003d", + "sha256:0c8f3be99e8a8bd403caa8c03be619544bc2c77a7093685dcf308c6b109426c6", + "sha256:0cca5adf694af539aeaa6ac633a7afe9bbd760df9d31be55ab780b77ab5ae8bf", + "sha256:1c8cd4fb70e8584ca1ed5805cbc7c017a3d1a29fb450621089ffed3e99d1857f", + "sha256:1f7d1a520373e2272b10796c3ff721ea1a0712288cafaa95931e66aa15798813", + "sha256:209ee89fbb0deed518605edddd234af80506aec932ad28d73c08f1400ef80a33", + "sha256:26efb2fcc6b67e4d5a55561f39176821d2adf88f2745ddc72751b7890f3194ad", + "sha256:37bd02ebf9d10e05b00d71302d2c2e6ca333e6c2a8584a98c00e038db8121f05", + "sha256:3a700330b567114b673cf8ee7388e949f843b356a73b5ab22dd7cff4742a5297", + "sha256:3c0165ba8f354a6d9881809ef29f1a9318a236a6d81c690094c5df32107bde06", + "sha256:3d80e36b7d7a9259b740be6d8d906221789b0d836201af4234093cae89ced0cd", + "sha256:4175593dc25d9da12f7de8de873a33f9b2b8bdb4e827a7cae952e5b1a342e243", + "sha256:4307270436fd7694b41f913eb09210faff27ea4979ecbcd849e57d2da2f65305", + "sha256:5e80e758243b97b618cdf22004beb09e8a2de1af481382e4d84bc52152d1c476", + "sha256:641411733b127c3e0dab94c45af15fea99e4468f99ac88b39efb1ad677da5711", + "sha256:652b651d42f155033a1967739788c436491b577b6a44e4c39fb340d0ee7f0d70", + "sha256:6d7464bac72a85cb3491c7e92b5b62f3dcccb8af26826257760a552a5e244aa5", + "sha256:74e259b5c19f70d35fcc1ad3d56499065c601dfe94ff67ae48b85596b9ec1461", + "sha256:7d17e0a9707d0772f4a7b878f04b4fd11f6f5bcb9b3813975a9b13c9332153ab", + "sha256:901c2c269c616e6cb0998b33d4adbb4a6af0ac4ce5cd078afd7bc95830e62c1c", + "sha256:98e781cd35c0acf33eb0295e8b9c55cdbef64fcb35f6d3aa2186f289bed6e80d", + "sha256:a12c56bf73cdab116df96e4ff39610b92a348cc99a1307e1da3c3768bbb5b135", + "sha256:ac6e503823143464538efda0e8e356d871557ef60ccd38f8824a4257acc18d93", + "sha256:b8472f736a5bfb159a5e36740847808f6f5b659960115ff29c7cecec1741c648", + "sha256:b86ce2c1866a748c0f6faca5232059f881cda6dda2a893b9a8373353cfe3715a", + "sha256:bc9ec663ed6c8f15f4ae9d3c04c989b744436c16d26580eaa760ae9dd5d662eb", + "sha256:c9166b3f81a10cdf9b49f2d594b21b31adadb3d5e9db9b834866c3258b695be3", + "sha256:d13674f3fb73805ba0c45eb6c0c3053d218aa1f7abead6e446d474529aafc372", + "sha256:de32edc9b0a7e67c2775e574cb061a537660e51210fbf6006b0b36ea695ae9bb", + "sha256:e62ebaad93be3ad1a828a11e90f0e76f15449371ffeecca4a0a0b9adc99abcef" ], "index": "pypi", - "version": "==0.971" + "version": "==0.991" }, "mypy-extensions": { "hashes": [ @@ -227,34 +460,35 @@ }, "packaging": { "hashes": [ - "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" + "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2", + "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97" ], - "markers": "python_version >= '3.6'", - "version": "==21.3" + "markers": "python_version >= '3.7'", + "version": "==23.0" }, "pathspec": { "hashes": [ - "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a", - "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1" + "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229", + "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc" ], - "version": "==0.9.0" + "markers": "python_version >= '3.7'", + "version": "==0.11.0" }, "pbr": { "hashes": [ - "sha256:e547125940bcc052856ded43be8e101f63828c2d94239ffbe2b327ba3d5ccf0a", - "sha256:e8dca2f4b43560edef58813969f52a56cef023146cbb8931626db80e6c1c4308" + "sha256:567f09558bae2b3ab53cb3c1e2e33e726ff3338e7bae3db5dc954b3a44eef12b", + "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3" ], "markers": "python_version >= '2.6'", - "version": "==5.9.0" + "version": "==5.11.1" }, "platformdirs": { "hashes": [ - "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", - "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" + "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490", + "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2" ], "markers": "python_version >= '3.7'", - "version": "==2.5.2" + "version": "==2.6.2" }, "pluggy": { "hashes": [ @@ -264,48 +498,33 @@ "markers": "python_version >= '3.6'", "version": "==1.0.0" }, - "py": { - "hashes": [ - "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.11.0" - }, "pycodestyle": { "hashes": [ - "sha256:289cdc0969d589d90752582bef6dff57c5fbc6949ee8b013ad6d6449a8ae9437", - "sha256:beaba44501f89d785be791c9462553f06958a221d166c64e1f107320f839acc2" + "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053", + "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610" ], "markers": "python_version >= '3.6'", - "version": "==2.9.0" + "version": "==2.10.0" }, "pyflakes": { "hashes": [ - "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2", - "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3" + "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf", + "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd" ], "markers": "python_version >= '3.6'", - "version": "==2.5.0" - }, - "pyparsing": { - "hashes": [ - "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", - "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" - ], - "markers": "python_full_version >= '3.6.8'", - "version": "==3.0.9" + "version": "==3.0.1" }, "pytest": { "hashes": [ - "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c", - "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45" + "sha256:c7c6ca206e93355074ae32f7403e8ea12163b1163c976fee7d4d84027c162be5", + "sha256:d45e0952f3727241918b8fd0f376f5ff6b301cc0777c6f9a556935c92d8a7d42" ], "index": "pypi", - "version": "==7.1.2" + "version": "==7.2.1" }, "pyyaml": { "hashes": [ + "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", @@ -317,32 +536,62 @@ "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", + "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", + "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", + "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", + "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", + "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", + "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" ], "markers": "python_version >= '3.6'", "version": "==6.0" }, + "requests": { + "hashes": [ + "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa", + "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf" + ], + "index": "pypi", + "version": "==2.28.2" + }, + "requests-mock": { + "hashes": [ + "sha256:2fdbb637ad17ee15c06f33d31169e71bf9fe2bdb7bc9da26185be0dd8d842699", + "sha256:59c9c32419a9fb1ae83ec242d98e889c45bd7d7a65d48375cc243ec08441658b" + ], + "index": "pypi", + "version": "==1.10.0" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, "smmap": { "hashes": [ "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94", @@ -353,27 +602,50 @@ }, "stevedore": { "hashes": [ - "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8", - "sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786" + "sha256:7f8aeb6e3f90f96832c301bff21a7eb5eefbe894c88c506483d355565d88cc1a", + "sha256:aa6436565c069b2946fe4ebff07f5041e0c8bf18c7376dd29edf80cf7d524e4e" ], "markers": "python_version >= '3.8'", - "version": "==4.0.0" + "version": "==4.1.1" }, "tomli": { "hashes": [ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==2.0.1" }, + "types-requests": { + "hashes": [ + "sha256:61960554baca0008ae7e2db2bd3b322ca9a144d3e80ce270f5fb640817e40994", + "sha256:e67424525f84adfbeab7268a159d3c633862dafae15c5b19547ce1b55954f0a3" + ], + "index": "pypi", + "version": "==2.28.11.8" + }, + "types-urllib3": { + "hashes": [ + "sha256:ed6b9e8a8be488796f72306889a06a3fc3cb1aa99af02ab8afb50144d7317e49", + "sha256:eec5556428eec862b1ac578fb69aab3877995a99ffec9e5a12cf7fbd0cc9daee" + ], + "version": "==1.26.25.4" + }, "typing-extensions": { "hashes": [ - "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02", - "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6" + "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", + "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" + ], + "markers": "python_version >= '3.7'", + "version": "==4.4.0" + }, + "urllib3": { + "hashes": [ + "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", + "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" ], - "markers": "python_version < '3.10'", - "version": "==4.3.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.14" } } } diff --git a/requirements.txt b/requirements.txt index fb32700..5e90064 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,6 @@ # -i https://pypi.org/simple -certifi==2022.6.15; python_version >= '3.6' -sentry-sdk==1.9.0 -urllib3==1.26.11; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4' +certifi==2022.12.7; python_version >= '3.6' +sentry-sdk==1.14.0 +urllib3==1.26.14; python_version >= '3.6' diff --git a/test_wcd2reshare.py b/test_wcd2reshare.py index 4dc4d88..22ebe76 100644 --- a/test_wcd2reshare.py +++ b/test_wcd2reshare.py @@ -1,7 +1,9 @@ import os from importlib import reload +from unittest.mock import MagicMock import pytest +import requests_mock import wcd2reshare @@ -19,6 +21,18 @@ def baseURL(): return "https://borrowdirect.reshare.indexdata.com/Search/Results?" +@pytest.fixture +def mocked_searchHasResults(*args, **kwargs): + if args[0].get("oclc"): + return False + + if args[0].get("isbn"): + return False + + if args[0].get("title"): + return True + + def test_configures_sentry_if_dsn_present(caplog, monkeypatch): monkeypatch.setenv("SENTRY_DSN", "https://1234567890@00000.ingest.sentry.io/123456") reload(wcd2reshare) @@ -34,106 +48,153 @@ def test_doesnt_configure_sentry_if_dsn_not_present(caplog, monkeypatch): assert "Sentry DSN found" not in caplog.text -def test_isbn(): - params = {"rft.isbn": "978-3-16-148410-0"} - assert wcd2reshare.query_formatter(params) == "type=ISN&lookfor=978-3-16-148410-0" - - -def test_title_no_author(): - params = {"rft.title": "salad days"} - assert wcd2reshare.query_formatter(params) == "type=title&lookfor=salad+days" +def test_query_formatter(): + params = { + "rft.isbn": "978-3-16-148410-0", + "rft.title": "salad days", + "rft_id": "info%3Aoclcnum%2F12345678", + } + SearchStrings = wcd2reshare.query_formatter(params) + assert SearchStrings["oclc"] == "type=oclc_num&lookfor=12345678" + assert SearchStrings["isbn"] == "type=ISN&lookfor=978-3-16-148410-0" + assert SearchStrings["title"] == "type=title&lookfor=salad+days" -def test_title_with_author(): +def test_query_formatter_title_with_author(): params = {"rft.title": "salad days", "rft.aulast": "ranch"} - assert wcd2reshare.query_formatter(params) == ( - "join=AND&type0%5B%5D=title&lookfor0%5B%5D=salad+days&" - "type0%5B%5D=author&lookfor0%5B%5D=ranch" + assert wcd2reshare.query_formatter(params)["title"] == ( + "join=AND&type0%5B%5D=title&lookfor0%5B%5D=salad+days&type0%5B%5D=author&" + "lookfor0%5B%5D=ranch" ) -def test_btitle_no_author(): - params = {"rft.btitle": "salad days"} - assert wcd2reshare.query_formatter(params) == "type=title&lookfor=salad+days" +def test_query_formatter_no_rft_fields_of_interest(): + params = {"rft.popcorn": "sure"} + assert wcd2reshare.query_formatter(params) == {} -def test_btitle_with_author(): - params = {"rft.btitle": "salad days", "rft.aulast": "ranch"} - assert wcd2reshare.query_formatter(params) == ( - "join=AND&type0%5B%5D=title&lookfor0%5B%5D=salad+days&" - "type0%5B%5D=author&lookfor0%5B%5D=ranch" +def test_query_formatter_title_priority(): + params = { + "rft.btitle": "b title", + "rft.ctitle": "c title", + "rft.jtitle": "j title", + "rft.aulast": "ranch", + "rft.title": "salad days", + } + assert wcd2reshare.query_formatter(params)["title"] == ( + "join=AND&type0%5B%5D=title&lookfor0%5B%5D=salad+days&type0%5B%5D=author&" + "lookfor0%5B%5D=ranch" ) -def test_ctitle_no_author(): - params = {"rft.ctitle": "salad days"} - assert wcd2reshare.query_formatter(params) == "type=title&lookfor=salad+days" +def test_query_formatter_btitle_priority(): + params = { + "rft.ctitle": "c title", + "rft.jtitle": "j title", + "rft.aulast": "ranch", + "rft.btitle": "b title", + } + assert wcd2reshare.query_formatter(params)["title"] == ( + "join=AND&type0%5B%5D=title&lookfor0%5B%5D=b+title&type0%5B%5D=author&" + "lookfor0%5B%5D=ranch" + ) -def test_ctitle_with_author(): - params = {"rft.ctitle": "salad days", "rft.aulast": "ranch"} - assert wcd2reshare.query_formatter(params) == ( - "join=AND&type0%5B%5D=title&lookfor0%5B%5D=salad+days&" - "type0%5B%5D=author&lookfor0%5B%5D=ranch" +def test_query_formatter_ctitle_priority(): + params = {"rft.jtitle": "j title", "rft.aulast": "ranch", "rft.ctitle": "c title"} + assert wcd2reshare.query_formatter(params)["title"] == ( + "join=AND&type0%5B%5D=title&lookfor0%5B%5D=c+title&type0%5B%5D=author&" + "lookfor0%5B%5D=ranch" ) -def test_jtitle_no_author(): - params = {"rft.jtitle": "salad days"} - assert wcd2reshare.query_formatter(params) == "type=title&lookfor=salad+days" +def test_query_formatter_fields_of_no_interest_ignored(): + params = {"rft.popcorn": "sure", "rft.isbn": "978-3-16-148410-0"} + assert wcd2reshare.query_formatter(params)["isbn"] == ( + "type=ISN&lookfor=978-3-16-148410-0" + ) -def test_jtitle_with_author(): - params = {"rft.jtitle": "salad days", "rft.aulast": "ranch"} - assert wcd2reshare.query_formatter(params) == ( - "join=AND&type0%5B%5D=title&lookfor0%5B%5D=salad+days&" - "type0%5B%5D=author&lookfor0%5B%5D=ranch" - ) +def test_searchHasResults_is_true_when_results_are_returned(): + searchString = "successful search string" + with requests_mock.Mocker() as m: + m.request(requests_mock.ANY, requests_mock.ANY, json={"resultCount": 1}) + assert wcd2reshare.searchHasResults(searchString) is True -def test_no_rft_fields_of_interest(): - params = {"rft.popcorn": "sure"} - assert wcd2reshare.query_formatter(params) == "" +def test_searchHasResults_is_false_when_results_are_not_returned(): + searchString = "failing search string" + with requests_mock.Mocker() as m: + m.request(requests_mock.ANY, requests_mock.ANY, json={"resultCount": 0}) + assert wcd2reshare.searchHasResults(searchString) is False -def test_title_priority(): - params = { - "rft.btitle": "btitle", - "rft.ctitle": "ctitle", - "rft.jtitle": "jtitle", - "rft.aulast": "ranch", - "rft.title": "title", +def test_buildTitleSearchString_no_author(): + title = "salad days" + assert wcd2reshare.buildTitleSearchString(title, aulast=None) == [ + ("type", "title"), + ("lookfor", title), + ] + + +def test_selectSearchStrategy_no_success(): + searchStrings = { + "oclc": "type=oclc_num&lookfor=12345678", + "isbn": "type=ISN&lookfor=978-3-16-148410-0", + "title": "type=title&lookfor=salad+days", } - assert wcd2reshare.query_formatter(params) == ( - "join=AND&type0%5B%5D=title&lookfor0%5B%5D=title&" - "type0%5B%5D=author&lookfor0%5B%5D=ranch" - ) + wcd2reshare.searchHasResults = MagicMock(side_effect=[False, False, False]) + selectedStrategy = wcd2reshare.selectSearchStrategy(searchStrings) + assert wcd2reshare.searchHasResults.call_count == 3 + assert selectedStrategy == "" -def test_btitle_priority(): - params = { - "rft.ctitle": "ctitle", - "rft.jtitle": "jtitle", - "rft.aulast": "ranch", - "rft.btitle": "btitle", +def test_selectSearchStrategy_oclc_success(): + searchStrings = { + "oclc": "type=oclc_num&lookfor=12345678", + "isbn": "type=ISN&lookfor=978-3-16-148410-0", + "title": "type=title&lookfor=salad+days", } - assert wcd2reshare.query_formatter(params) == ( - "join=AND&type0%5B%5D=title&lookfor0%5B%5D=btitle&" - "type0%5B%5D=author&lookfor0%5B%5D=ranch" - ) + wcd2reshare.searchHasResults = MagicMock(side_effect=[True]) + selectedStrategy = wcd2reshare.selectSearchStrategy(searchStrings) + assert wcd2reshare.searchHasResults.call_count == 1 + assert selectedStrategy == searchStrings["oclc"] -def test_ctitle_priority(): - params = {"rft.jtitle": "jtitle", "rft.aulast": "ranch", "rft.ctitle": "ctitle"} - assert wcd2reshare.query_formatter(params) == ( - "join=AND&type0%5B%5D=title&lookfor0%5B%5D=ctitle&" - "type0%5B%5D=author&lookfor0%5B%5D=ranch" - ) +def test_selectSearchStrategy_isbn_success(): + searchStrings = { + "oclc": "type=oclc_num&lookfor=12345678", + "isbn": "type=ISN&lookfor=978-3-16-148410-0", + "title": "type=title&lookfor=salad+days", + } + wcd2reshare.searchHasResults = MagicMock(side_effect=[False, True]) + selectedStrategy = wcd2reshare.selectSearchStrategy(searchStrings) + assert wcd2reshare.searchHasResults.call_count == 2 + assert selectedStrategy == searchStrings["isbn"] -def test_fields_of_no_interest_ignored(): - params = {"rft.popcorn": "sure", "rft.isbn": "978-3-16-148410-0"} - assert wcd2reshare.query_formatter(params) == "type=ISN&lookfor=978-3-16-148410-0" +def test_selectSearchStrategy_title_success(): + searchStrings = { + "oclc": "type=oclc_num&lookfor=12345678", + "isbn": "type=ISN&lookfor=978-3-16-148410-0", + "title": "type=title&lookfor=salad+days", + } + wcd2reshare.searchHasResults = MagicMock(side_effect=[False, False, True]) + selectedStrategy = wcd2reshare.selectSearchStrategy(searchStrings) + assert wcd2reshare.searchHasResults.call_count == 3 + assert selectedStrategy == searchStrings["title"] + + +def test_buildTitleSearchString_with_author(): + title = "salad days" + aulast = "ranch" + assert wcd2reshare.buildTitleSearchString(title, aulast) == [ + ("join", "AND"), + ("type0[]", "title"), + ("lookfor0[]", title), + ("type0[]", "author"), + ("lookfor0[]", aulast), + ] def test_lambda_handler_workspace_missing(caplog, monkeypatch): @@ -152,6 +213,7 @@ def test_lambda_handler_workspace_found(caplog): def test_lambda_handler_with_query(baseURL): event = {"queryStringParameters": {"rft.isbn": "978-3-16-148410-0"}} queryString = "type=ISN&lookfor=978-3-16-148410-0" + wcd2reshare.selectSearchStrategy = MagicMock(return_value=queryString) response = wcd2reshare.lambda_handler(event, context={}) assert response["statusCode"] == 307 assert response["headers"]["Location"] == baseURL + queryString @@ -165,6 +227,7 @@ def test_lambda_handler_with_multiple_query(baseURL): "join=AND&type0%5B%5D=title&lookfor0%5B%5D=salad+days&" "type0%5B%5D=author&lookfor0%5B%5D=ranch" ) + wcd2reshare.selectSearchStrategy = MagicMock(return_value=queryString) response = wcd2reshare.lambda_handler(event, context={}) assert response["statusCode"] == 307 assert response["headers"]["Location"] == baseURL + queryString @@ -177,28 +240,9 @@ def test_lambda_handler_without_query(baseURL): def test_lambda_handler_with_garbage_query(baseURL): + wcd2reshare.selectSearchStrategy = MagicMock(return_value="") response = wcd2reshare.lambda_handler( event={"queryStringParameters": {"door": "knob"}}, context={} ) assert response["statusCode"] == 307 assert response["headers"]["Location"] == baseURL - - -def test_buildSearchString_no_author(): - title = "salad days" - assert wcd2reshare.buildSearchString(title, aulast=None) == [ - ("type", "title"), - ("lookfor", title), - ] - - -def test_buildSearchString_with_author(): - title = "salad days" - aulast = "ranch" - assert wcd2reshare.buildSearchString(title, aulast) == [ - ("join", "AND"), - ("type0[]", "title"), - ("lookfor0[]", title), - ("type0[]", "author"), - ("lookfor0[]", aulast), - ] diff --git a/wcd2reshare.py b/wcd2reshare.py index 80c794c..ae1c362 100644 --- a/wcd2reshare.py +++ b/wcd2reshare.py @@ -1,7 +1,10 @@ import logging import os +import re +import typing import urllib.parse +import requests import sentry_sdk from sentry_sdk.integrations.aws_lambda import AwsLambdaIntegration @@ -19,22 +22,27 @@ logger.info("Sentry DSN found, exceptions will be sent to Sentry with env=%s", env) -def query_formatter(args: dict) -> str: - """Transforms a dictionary of OpenURL request params to a string of search - params formatted for BorrowDirect / ReShare vuFind UI. +def query_formatter(args: dict) -> dict: + """Transforms a dictionary of OpenURL request params to a dict of search + strings formatted for BorrowDirect / ReShare vuFind UI. - Logic is: - if isbn - use isbn and nothing else - else if any of the 4 titles exist: - use the title that exists in this preferential order - title, btitle, ctitle, jtitle - nested condition of if aulast include that as well""" + """ + + searchStrings = {} + if rft_id := args.get("rft_id"): + # we expect the rft_id param to contain an 8 or 9 digit oclc number preceeded + # by some stuff we don't care about + pattern = re.compile("info%3Aoclcnum%2F([0-9]{8,9})") + # if we encounter the expected pattern extract the oclc number + # from the first capture group + if oclc_num := pattern.match(rft_id): + searchStrings["oclc"] = [ + ("type", "oclc_num"), + ("lookfor", oclc_num.group(1)), + ] - searchString = [] if isbn := args.get("rft.isbn"): - searchString = [("type", "ISN"), ("lookfor", isbn)] - return urllib.parse.urlencode(searchString) + searchStrings["isbn"] = [("type", "ISN"), ("lookfor", isbn)] if title := ( args.get("rft.title") @@ -43,14 +51,15 @@ def query_formatter(args: dict) -> str: or args.get("rft.jtitle") ): aulast = args.get("rft.aulast") - searchString = buildSearchString(title, aulast) - return urllib.parse.urlencode(searchString) - - # if nothing matches, just return. no search will be done - return "" + searchStrings["title"] = buildTitleSearchString(title, aulast) + # urlencode the search strings + encodedSearchStrings = { + k: urllib.parse.urlencode(v) for k, v, in searchStrings.items() + } + return encodedSearchStrings -def buildSearchString(title: str, aulast: str = None) -> list: +def buildTitleSearchString(title: str, aulast: typing.Optional[str]) -> list: """Takes title and aulast (author last name) values from openURL params and builds the correct search string syntax for VuFind. If aulast is None, only a title search is built. If an aulast is supplied, a combined title / author search is built. @@ -67,6 +76,40 @@ def buildSearchString(title: str, aulast: str = None) -> list: return result +def selectSearchStrategy(searchStrings: dict) -> str: + """takes a dict of search strings and checks whether each search + string returns any results. Returns the first successful search string. + + Searches are tried in a specific order from most specific to least + specific + """ + + if query_string := searchStrings.get("oclc"): + if searchHasResults(query_string): + return query_string + + if query_string := searchStrings.get("isbn"): + if searchHasResults(query_string): + return query_string + + if query_string := searchStrings.get("title"): + if searchHasResults(query_string): + return query_string + + return "" + + +def searchHasResults(searchString: str) -> bool: + """check whether VuFind API returns any records for a given search string""" + vuFind_API = "https://borrowdirect.reshare.indexdata.com/api/v1/search?" + r = requests.get(vuFind_API + searchString) + body = r.json() + if body.get("resultCount"): + return True + else: + return False + + def lambda_handler(event: dict, context: dict) -> dict: """Extracts query string parameters (if any exist) from incoming lambda function URL request. If there are query string parameters, try to build query string for @@ -78,9 +121,11 @@ def lambda_handler(event: dict, context: dict) -> dict: raise ValueError("WORKSPACE environment variable is required") location = "https://borrowdirect.reshare.indexdata.com/Search/Results?" - + query_string = "" if args := event.get("queryStringParameters"): - location = location + query_formatter(args) + query_string = selectSearchStrategy(query_formatter(args)) + location = location + query_string + response = { "headers": {"Location": location}, "statusCode": 307,