diff --git a/Pipfile b/Pipfile index 3d4eeb3..b46da8f 100644 --- a/Pipfile +++ b/Pipfile @@ -4,19 +4,21 @@ verify_ssl = true name = "pypi" [packages] +archivessnake = "*" +boto3 = "*" click = "*" +pyairtable = "*" sentry-sdk = "*" -boto3 = "*" [dev-packages] black = "*" +boto3-stubs = "*" coveralls = "*" +moto = "*" mypy = "*" pre-commit = "*" pytest = "*" ruff = "*" -boto3-stubs = "*" -moto = "*" [requires] python_version = "3.12" diff --git a/Pipfile.lock b/Pipfile.lock index 48e8c4e..5703093 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2efd556d500136bc82428e61c2d7a07bf9a79b98f75794c828d37bcd9ac1c1b1" + "sha256": "dd455b97b69c30f3654c46e6cfd19fabde7bc8a6f8fed3d019981e902a2af7c3" }, "pipfile-spec": 6, "requires": { @@ -16,22 +16,47 @@ ] }, "default": { + "archivessnake": { + "hashes": [ + "sha256:5b9bbebafd7a4edb3624acda0d1abe3f65c198af2778e9787c8751dcf27f6f04", + "sha256:5e12ad94240609a2257650abbf97e1802a6d53e8761eb9535b03c96e03d7c0a1" + ], + "index": "pypi", + "markers": "python_version ~= '3.4'", + "version": "==0.10.1" + }, + "attrs": { + "hashes": [ + "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", + "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2" + ], + "markers": "python_version >= '3.7'", + "version": "==24.2.0" + }, + "boltons": { + "hashes": [ + "sha256:4a49b7d57ee055b83a458c8682a2a6f199d263a8aa517098bda9bab813554b87", + "sha256:a1776d47fdc387fb730fba1fe245f405ee184ee0be2fb447dd289773a84aed3b" + ], + "markers": "python_version >= '3.7'", + "version": "==24.1.0" + }, "boto3": { "hashes": [ - "sha256:d0f938d4f6f392b6ffc5e75fff14a42e5bbb5228675a0367c8af55398abadbec", - "sha256:deb593d9a0fb240deb4c43e4da8e6626d7c36be7b2fd2fe28f49d44d395b7de0" + "sha256:09a610f8cf4d3c22d4ca69c1f89079e3a1c82805ce94fa0eb4ecdd4d2ba6c4bc", + "sha256:c392b9168b65e9c23483eaccb5b68d1f960232d7f967a1e00a045ba065ce050d" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.63" + "version": "==1.35.66" }, "botocore": { "hashes": [ - "sha256:0ca1200694a4c0a3fa846795d8e8a08404c214e21195eb9e010c4b8a4ca78a4a", - "sha256:2b8196bab0a997d206c3d490b52e779ef47dffb68c57c685443f77293aca1589" + "sha256:51f43220315f384959f02ea3266740db4d421592dd87576c18824e424b349fdb", + "sha256:d0683e9c18bb6852f768da268086c3749d925332a664db0dd1459cfa7e96e475" ], "markers": "python_version >= '3.8'", - "version": "==1.35.63" + "version": "==1.35.66" }, "certifi": { "hashes": [ @@ -41,6 +66,117 @@ "markers": "python_version >= '3.6'", "version": "==2024.8.30" }, + "charset-normalizer": { + "hashes": [ + "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", + "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", + "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", + "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", + "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", + "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", + "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", + "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", + "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", + "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", + "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", + "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", + "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", + "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", + "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", + "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", + "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", + "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", + "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", + "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", + "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", + "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", + "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", + "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", + "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", + "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", + "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", + "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", + "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", + "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", + "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", + "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", + "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", + "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", + "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", + "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", + "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", + "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", + "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", + "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", + "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", + "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", + "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", + "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", + "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", + "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", + "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", + "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", + "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", + "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", + "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", + "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", + "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", + "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", + "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", + "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", + "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", + "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", + "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", + "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", + "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", + "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", + "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", + "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", + "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", + "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", + "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", + "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", + "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", + "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", + "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", + "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", + "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", + "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", + "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", + "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", + "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", + "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", + "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", + "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", + "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", + "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", + "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", + "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", + "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", + "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", + "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", + "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", + "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.4.0" + }, "click": { "hashes": [ "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", @@ -50,6 +186,22 @@ "markers": "python_version >= '3.7'", "version": "==8.1.7" }, + "idna": { + "hashes": [ + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" + ], + "markers": "python_version >= '3.6'", + "version": "==3.10" + }, + "inflection": { + "hashes": [ + "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417", + "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2" + ], + "markers": "python_version >= '3.5'", + "version": "==0.5.1" + }, "jmespath": { "hashes": [ "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", @@ -58,6 +210,71 @@ "markers": "python_version >= '3.7'", "version": "==1.0.1" }, + "more-itertools": { + "hashes": [ + "sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", + "sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6" + ], + "markers": "python_version >= '3.8'", + "version": "==10.5.0" + }, + "pyairtable": { + "hashes": [ + "sha256:41e256fdcf0e68e8348197d8f474b0789b6f05d2fd3bd6c407e5900a8fae02f8", + "sha256:dd2dde960f261f947407cf865922bcf2e0e2524b94c7a596c8901dfdf4471b68" + ], + "index": "pypi", + "version": "==2.0.0" + }, + "pydantic": { + "hashes": [ + "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea", + "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0", + "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34", + "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e", + "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4", + "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98", + "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6", + "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59", + "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f", + "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b", + "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f", + "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f", + "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3", + "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555", + "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25", + "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4", + "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c", + "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186", + "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac", + "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3", + "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb", + "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413", + "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f", + "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d", + "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3", + "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086", + "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f", + "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d", + "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10", + "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3", + "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289", + "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0", + "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f", + "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890", + "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3", + "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08", + "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3", + "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526", + "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206", + "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96", + "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e", + "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10", + "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35" + ], + "markers": "python_version >= '3.7'", + "version": "==1.10.19" + }, "python-dateutil": { "hashes": [ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", @@ -66,13 +283,174 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.9.0.post0" }, + "pyyaml": { + "hashes": [ + "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff", + "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", + "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", + "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", + "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", + "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", + "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", + "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", + "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", + "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", + "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a", + "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", + "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", + "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", + "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", + "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", + "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", + "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a", + "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", + "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", + "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", + "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", + "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", + "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", + "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", + "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", + "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", + "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", + "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", + "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706", + "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", + "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", + "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", + "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083", + "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", + "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", + "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", + "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", + "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", + "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", + "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", + "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", + "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", + "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", + "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5", + "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d", + "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", + "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", + "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", + "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", + "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", + "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", + "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4" + ], + "markers": "python_version >= '3.8'", + "version": "==6.0.2" + }, + "rapidfuzz": { + "hashes": [ + "sha256:00d02cbd75d283c287471b5b3738b3e05c9096150f93f2d2dfa10b3d700f2db9", + "sha256:031f8b367e5d92f7a1e27f7322012f3c321c3110137b43cc3bf678505583ef48", + "sha256:073a5b107e17ebd264198b78614c0206fa438cce749692af5bc5f8f484883f50", + "sha256:0b75fe506c8e02769cc47f5ab21ce3e09b6211d3edaa8f8f27331cb6988779be", + "sha256:0e06d99ad1ad97cb2ef7f51ec6b1fedd74a3a700e4949353871cf331d07b382a", + "sha256:0fff4a6b87c07366662b62ae994ffbeadc472e72f725923f94b72a3db49f4671", + "sha256:10746c1d4c8cd8881c28a87fd7ba0c9c102346dfe7ff1b0d021cdf093e9adbff", + "sha256:1340b56340896bede246f612b6ecf685f661a56aabef3d2512481bfe23ac5835", + "sha256:18123168cba156ab5794ea6de66db50f21bb3c66ae748d03316e71b27d907b95", + "sha256:187d9747149321607be4ccd6f9f366730078bed806178ec3eeb31d05545e9e8f", + "sha256:191633722203f5b7717efcb73a14f76f3b124877d0608c070b827c5226d0b972", + "sha256:195baad28057ec9609e40385991004e470af9ef87401e24ebe72c064431524ab", + "sha256:1996feb7a61609fa842e6b5e0c549983222ffdedaf29644cc67e479902846dfe", + "sha256:1b35a118d61d6f008e8e3fb3a77674d10806a8972c7b8be433d6598df4d60b01", + "sha256:1e6bbca9246d9eedaa1c84e04a7f555493ba324d52ae4d9f3d9ddd1b740dcd87", + "sha256:1e96c84d6c2a0ca94e15acb5399118fff669f4306beb98a6d8ec6f5dccab4412", + "sha256:2316515169b7b5a453f0ce3adbc46c42aa332cae9f2edb668e24d1fc92b2f2bb", + "sha256:231ef1ec9cf7b59809ce3301006500b9d564ddb324635f4ea8f16b3e2a1780da", + "sha256:237bec5dd1bfc9b40bbd786cd27949ef0c0eb5fab5eb491904c6b5df59d39d3c", + "sha256:26f71582c0d62445067ee338ddad99b655a8f4e4ed517a90dcbfbb7d19310474", + "sha256:2cf44d01bfe8ee605b7eaeecbc2b9ca64fc55765f17b304b40ed8995f69d7716", + "sha256:335fee93188f8cd585552bb8057228ce0111bd227fa81bfd40b7df6b75def8ab", + "sha256:3611c8f45379a12063d70075c75134f2a8bd2e4e9b8a7995112ddae95ca1c982", + "sha256:365e4fc1a2b95082c890f5e98489b894e6bf8c338c6ac89bb6523c2ca6e9f086", + "sha256:36c0e1483e21f918d0f2f26799fe5ac91c7b0c34220b73007301c4f831a9c4c7", + "sha256:38b0dac2c8e057562b8f0d8ae5b663d2d6a28c5ab624de5b73cef9abb6129a24", + "sha256:39c4983e2e2ccb9732f3ac7d81617088822f4a12291d416b09b8a1eadebb3e29", + "sha256:3c3b537b97ac30da4b73930fa8a4fe2f79c6d1c10ad535c5c09726612cd6bed9", + "sha256:425f4ac80b22153d391ee3f94bc854668a0c6c129f05cf2eaf5ee74474ddb69e", + "sha256:440b5608ab12650d0390128d6858bc839ae77ffe5edf0b33a1551f2fa9860651", + "sha256:4ffed25f9fdc0b287f30a98467493d1e1ce5b583f6317f70ec0263b3c97dbba6", + "sha256:54bcf4efaaee8e015822be0c2c28214815f4f6b4f70d8362cfecbd58a71188ac", + "sha256:565c2bd4f7d23c32834652b27b51dd711814ab614b4e12add8476be4e20d1cf5", + "sha256:567f88180f2c1423b4fe3f3ad6e6310fc97b85bdba574801548597287fc07028", + "sha256:5a15546d847a915b3f42dc79ef9b0c78b998b4e2c53b252e7166284066585979", + "sha256:616290fb9a8fa87e48cb0326d26f98d4e29f17c3b762c2d586f2b35c1fd2034b", + "sha256:65a2fa13e8a219f9b5dcb9e74abe3ced5838a7327e629f426d333dfc8c5a6e66", + "sha256:666d5d8b17becc3f53447bcb2b6b33ce6c2df78792495d1fa82b2924cd48701a", + "sha256:6729b856166a9e95c278410f73683957ea6100c8a9d0a8dbe434c49663689255", + "sha256:6b2cd7c29d6ecdf0b780deb587198f13213ac01c430ada6913452fd0c40190fc", + "sha256:6fde3bbb14e92ce8fcb5c2edfff72e474d0080cadda1c97785bf4822f037a309", + "sha256:75561f3df9a906aaa23787e9992b228b1ab69007932dc42070f747103e177ba8", + "sha256:779027d3307e1a2b1dc0c03c34df87a470a368a1a0840a9d2908baf2d4067956", + "sha256:7b6015da2e707bf632a71772a2dbf0703cff6525732c005ad24987fe86e8ec32", + "sha256:7f4f43f2204b56a61448ec2dd061e26fd344c404da99fb19f3458200c5874ba2", + "sha256:82cac41a411e07a6f3dc80dfbd33f6be70ea0abd72e99c59310819d09f07d945", + "sha256:8a2ef08b27167bcff230ffbfeedd4c4fa6353563d6aaa015d725dd3632fc3de7", + "sha256:8d1b7082104d596a3eb012e0549b2634ed15015b569f48879701e9d8db959dbb", + "sha256:8e06fe6a12241ec1b72c0566c6b28cda714d61965d86569595ad24793d1ab259", + "sha256:9141fb0592e55f98fe9ac0f3ce883199b9c13e262e0bf40c5b18cdf926109d16", + "sha256:92958ae075c87fef393f835ed02d4fe8d5ee2059a0934c6c447ea3417dfbf0e8", + "sha256:958473c9f0bca250590200fd520b75be0dbdbc4a7327dc87a55b6d7dc8d68552", + "sha256:9a0d519ff39db887cd73f4e297922786d548f5c05d6b51f4e6754f452a7f4296", + "sha256:9d81bf186a453a2757472133b24915768abc7c3964194406ed93e170e16c21cb", + "sha256:9da82aa4b46973aaf9e03bb4c3d6977004648c8638febfc0f9d237e865761270", + "sha256:9ef60dfa73749ef91cb6073be1a3e135f4846ec809cc115f3cbfc6fe283a5584", + "sha256:9f912d459e46607ce276128f52bea21ebc3e9a5ccf4cccfef30dd5bddcf47be8", + "sha256:a1d9aa156ed52d3446388ba4c2f335e312191d1ca9d1f5762ee983cf23e4ecf6", + "sha256:a7fbac18f2c19fc983838a60611e67e3262e36859994c26f2ee85bb268de2355", + "sha256:aaf83e9170cb1338922ae42d320699dccbbdca8ffed07faeb0b9257822c26e24", + "sha256:ac4452f182243cfab30ba4668ef2de101effaedc30f9faabb06a095a8c90fd16", + "sha256:ac7adee6bcf0c6fee495d877edad1540a7e0f5fc208da03ccb64734b43522d7a", + "sha256:b31f358a70efc143909fb3d75ac6cd3c139cd41339aa8f2a3a0ead8315731f2b", + "sha256:ba7521e072c53e33c384e78615d0718e645cab3c366ecd3cc8cb732befd94967", + "sha256:bc308d79a7e877226f36bdf4e149e3ed398d8277c140be5c1fd892ec41739e6d", + "sha256:bebb7bc6aeb91cc57e4881b222484c26759ca865794187217c9dcea6c33adae6", + "sha256:bfa48a4a2d45a41457f0840c48e579db157a927f4e97acf6e20df8fc521c79de", + "sha256:c0c955e32afdbfdf6e9ee663d24afb25210152d98c26d22d399712d29a9b976b", + "sha256:c34c022d5ad564f1a5a57a4a89793bd70d7bad428150fb8ff2760b223407cdcf", + "sha256:c5da802a0d085ad81b0f62828fb55557996c497b2d0b551bbdfeafd6d447892f", + "sha256:cf654702f144beaa093103841a2ea6910d617d0bb3fccb1d1fd63c54dde2cd49", + "sha256:cfcc8feccf63245a22dfdd16e222f1a39771a44b870beb748117a0e09cbb4a62", + "sha256:d02cf8e5af89a9ac8f53c438ddff6d773f62c25c6619b29db96f4aae248177c0", + "sha256:d99c1cd9443b19164ec185a7d752f4b4db19c066c136f028991a480720472e23", + "sha256:dfa64b89dcb906835e275187569e51aa9d546a444489e97aaf2cc84011565fbe", + "sha256:e8e154b84a311263e1aca86818c962e1fa9eefdd643d1d5d197fcd2738f88cb9", + "sha256:ec108bf25de674781d0a9a935030ba090c78d49def3d60f8724f3fc1e8e75024", + "sha256:ed4f3adc1294834955b7e74edd3c6bd1aad5831c007f2d91ea839e76461a5879", + "sha256:edd062490537e97ca125bc6c7f2b7331c2b73d21dc304615afe61ad1691e15d5", + "sha256:efa1582a397da038e2f2576c9cd49b842f56fde37d84a6b0200ffebc08d82350", + "sha256:f017dbfecc172e2d0c37cf9e3d519179d71a7f16094b57430dffc496a098aa17", + "sha256:f12912acee1f506f974f58de9fdc2e62eea5667377a7e9156de53241c05fdba8", + "sha256:f17d9f21bf2f2f785d74f7b0d407805468b4c173fa3e52c86ec94436b338e74a", + "sha256:f1da2028cb4e41be55ee797a82d6c1cf589442504244249dfeb32efc608edee7", + "sha256:f3bb81d4fe6a5d20650f8c0afcc8f6e1941f6fecdb434f11b874c42467baded0", + "sha256:f98f36c6a1bb9a6c8bbec99ad87c8c0e364f34761739b5ea9adf7b48129ae8cf", + "sha256:fc22d69a1c9cccd560a5c434c0371b2df0f47c309c635a01a913e03bbf183710", + "sha256:fe07f8b9c3bb5c5ad1d2c66884253e03800f4189a60eb6acd6119ebaf3eb9894" + ], + "markers": "python_version >= '3.9'", + "version": "==3.10.1" + }, + "requests": { + "hashes": [ + "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" + ], + "markers": "python_version >= '3.8'", + "version": "==2.32.3" + }, "s3transfer": { "hashes": [ - "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d", - "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c" + "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e", + "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7" ], "markers": "python_version >= '3.8'", - "version": "==0.10.3" + "version": "==0.10.4" }, "sentry-sdk": { "hashes": [ @@ -91,6 +469,22 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, + "structlog": { + "hashes": [ + "sha256:597f61e80a91cc0749a9fd2a098ed76715a1c8a01f73e336b746504d1aad7610", + "sha256:b27bfecede327a6d2da5fbc96bd859f114ecc398a6389d664f62085ee7ae6fc4" + ], + "markers": "python_version >= '3.8'", + "version": "==24.4.0" + }, + "typing-extensions": { + "hashes": [ + "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", + "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" + ], + "markers": "python_version >= '3.8'", + "version": "==4.12.2" + }, "urllib3": { "hashes": [ "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", @@ -132,37 +526,37 @@ }, "boto3": { "hashes": [ - "sha256:d0f938d4f6f392b6ffc5e75fff14a42e5bbb5228675a0367c8af55398abadbec", - "sha256:deb593d9a0fb240deb4c43e4da8e6626d7c36be7b2fd2fe28f49d44d395b7de0" + "sha256:09a610f8cf4d3c22d4ca69c1f89079e3a1c82805ce94fa0eb4ecdd4d2ba6c4bc", + "sha256:c392b9168b65e9c23483eaccb5b68d1f960232d7f967a1e00a045ba065ce050d" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.63" + "version": "==1.35.66" }, "boto3-stubs": { "hashes": [ - "sha256:74663e6087360f49a4da4d2079bca6a809586f44d42238046d5a726c48be4a00", - "sha256:cc471636d28f595bf750dc3c2079d16e988c9f518a66f50c9d62b0119c3f72cf" + "sha256:45bd1af609367e49acd2a7a895d630bdf224bff3ab0c29eb98900e60981162f3", + "sha256:e73eadf5e979cf0bcbc37ff83286a80f1ac181548fba4efc3237387ce288d75e" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.63" + "version": "==1.35.66" }, "botocore": { "hashes": [ - "sha256:0ca1200694a4c0a3fa846795d8e8a08404c214e21195eb9e010c4b8a4ca78a4a", - "sha256:2b8196bab0a997d206c3d490b52e779ef47dffb68c57c685443f77293aca1589" + "sha256:51f43220315f384959f02ea3266740db4d421592dd87576c18824e424b349fdb", + "sha256:d0683e9c18bb6852f768da268086c3749d925332a664db0dd1459cfa7e96e475" ], "markers": "python_version >= '3.8'", - "version": "==1.35.63" + "version": "==1.35.66" }, "botocore-stubs": { "hashes": [ - "sha256:7ac5cbfb3bf15106c3344a56d5e853c07dd1fc775ebc37ff1a2d2cb0e79b4ef1", - "sha256:e7d1f5c704c837b751e5c2b1d128f7c889ab04ebf2d56143702f5fc92702858b" + "sha256:94b7fda03003c30e9f40dc16d5f8c3897002e78b1cb46c9fbb1d081752639499", + "sha256:cf9ba0850316fbaf250f3bb87816613b5f2dfab20536fa5a9d6da0f2235b234e" ], "markers": "python_version >= '3.8'", - "version": "==1.35.63" + "version": "==1.35.66" }, "certifi": { "hashes": [ @@ -846,11 +1240,11 @@ }, "s3transfer": { "hashes": [ - "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d", - "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c" + "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e", + "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7" ], "markers": "python_version >= '3.8'", - "version": "==0.10.3" + "version": "==0.10.4" }, "six": { "hashes": [ @@ -917,4 +1311,4 @@ "version": "==0.14.2" } } -} +} \ No newline at end of file diff --git a/README.md b/README.md index 018daf5..cdb6bff 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,14 @@ -# python-cli-template - -A template repository for creating Python CLI applications. - -## App Setup (delete this section and above after initial application setup) - -1. Rename "asati" to the desired app name across the repo. (May be helpful to do a project-wide find-and-replace). -2. Update Python version if needed. -3. Install all dependencies with `make install` to create initial Pipfile.lock with latest dependency versions. -4. Add initial app description to README and update initial required ENV variable documentation as needed. -5. Update license if needed (check app-specific dependencies for licensing terms). -6. Check Github repository settings: - - Confirm repo branch protection settings are correct (see [dev docs](https://mitlibraries.github.io/guides/basics/github.html) for details) - - Confirm that all of the following are enabled in the repo's code security and analysis settings: - - Dependabot alerts - - Dependabot security updates - - Secret scanning -7. Create a Sentry project for the app if needed (we want this for most apps): - - Send initial exceptions to Sentry project for dev, stage, and prod environments to create them. - - Create an alert for the prod environment only, with notifications sent to the appropriate team(s). - - If *not* using Sentry, delete Sentry configuration from config.py and test_config.py, and remove sentry_sdk from project dependencies. +# archivesspace-airtable-integration +An application for updating Airtable with ArchivesSpace data. + # asati +The application extracts data from newly-created accession records in ArchivesSpace on a daily basis. It uses an SSM parameter (`/apps/asati/last-accession-uri-id`) to track the last accession that was added to Airtable via the ID in the URI (e.g. "/repositories/2/accessions/**123**"). The application accesses the SSM parameter at the start of each run and calls the ArchivesSpace API's `accessions` endpoint with the `?all_ids=true` parameter to check if a higher ID number has been created. ArchivesSpace increments the IDs and does not reuse IDs, making this a safe method for checking if new accessions have been created. + +If no new accessions were create, the run ends. If a new accession has been created, the accession record is retrieved and the necessary data is posted as a new row in Airtable. This is not expected to be high-volume application, only a few accessions at most are expected to be created on a given day and most days will not have any new accessions. + +Sentry will be used for exception monitoring and the application is expected to immediately fail if there is an error. Given the simple structure and logging at potential failure points, troubleshooting should be quick if the application does fail. Furthermore, the application can pick up where it left off on the next daily run, given that the SSM parameter is updated after each row is added to Airtable. -Description of the app ## Development @@ -40,16 +26,14 @@ Description of the app ```shell SENTRY_DSN=### If set to a valid Sentry DSN, enables Sentry exception monitoring. This is not needed for local development. WORKSPACE=### Set to `dev` for local development, this will be set to `stage` and `prod` in those environments by Terraform. +LAST_ACCESSION_PARAMETER=### The name of the SSM parameter that stores the ID from the URI of the last processed accession. +ARCHIVESSPACE_URL=### The URL of the ArchivesSpace instance to use. Given this app is read-only, the production instance will be used. +ARCHIVESSPACE_USER=### The username to use for authenticating to ArchivesSpace. +ARCHIVESSPACE_PASSWORD=### The password to use for authenticating to ArchivesSpace. +AIRTABLE_TOKEN=### The token to use for authenticating to Airtable. +AIRTABLE_BASE_ID=### The Airtable base containing the table to be updated. +AIRTABLE_TABLE_NAME=### The Airtable table to be updated. ``` -### Optional - -_Delete this section if it isn't applicable to the PR._ - -```shell -=### Description for optional environment variable -``` - - diff --git a/asati/cli.py b/asati/cli.py index 01c83a4..52541f2 100644 --- a/asati/cli.py +++ b/asati/cli.py @@ -1,10 +1,14 @@ import logging +import os from datetime import timedelta from time import perf_counter import click +import pyairtable +from asnake.client import ASnakeClient # type: ignore[import-untyped] from asati.config import configure_logger, configure_sentry +from asati.utils import SSMClient, parse_accession_number, parse_extent_data logger = logging.getLogger(__name__) @@ -20,7 +24,67 @@ def main(*, verbose: bool) -> None: logger.info(configure_sentry()) logger.info("Running process") - # Do things here! + ssm_client = SSMClient() + last_accession_parameter = os.environ["LAST_ACCESSION_PARAMETER"] + last_accession_uri_id = ssm_client.get_parameter(last_accession_parameter) + logger.info( + f"SSM parameter '{last_accession_parameter}' retrieved: '{last_accession_uri_id}'" + ) + + asnake_client = ASnakeClient( + baseurl=os.environ["ARCHIVESSPACE_URL"], + username=os.environ["ARCHIVESSPACE_USER"], + password=os.environ["ARCHIVESSPACE_PASSWORD"], + ) + accession_uri_ids = asnake_client.get( + "/repositories/2/accessions?all_ids=true" + ).json() + + if max(accession_uri_ids) <= int(last_accession_uri_id): + logger.info("No new accessions to add to Airtable.") + else: + airtable_api = pyairtable.Api(os.environ["AIRTABLE_TOKEN"]) + airtable_table = airtable_api.table( + os.environ["AIRTABLE_BASE_ID"], os.environ["AIRTABLE_TABLE_NAME"] + ) + logger.info( + f"Airtable client configured for base '{airtable_table.base}'" + f" and table '{airtable_table.name}'" + ) + accessions_to_add = sorted( + [ + accession_uri_id + for accession_uri_id in accession_uri_ids + if accession_uri_id > int(last_accession_uri_id) + ] + ) + logger.info(f"Adding the following accessions to Airtable: {accessions_to_add}") + for accession_uri_id in accessions_to_add: + accession_uri = f"/repositories/2/accessions/{accession_uri_id}" + accession_record = asnake_client.get(accession_uri).json() + logger.debug(f"Retrieved record: {accession_uri}") + accession_data = { + "Accession Title": accession_record["title"], + "Accession Number": parse_accession_number(accession_record), + "Current Status": "Unassigned", + **parse_extent_data(accession_record), + } + logger.debug(f"Data extracted from ArchivesSpace: {accession_data}") + + response = airtable_table.create(accession_data) + logger.info( + "Airtable row created for Accession Number: " + f"'{response["fields"]["Accession Number"]}'" + ) + + logger.info(f"Last accession ID processed: {accession_uri_id}") + updated_last_accession_uri_id = ssm_client.update_parameter( + last_accession_parameter, str(accession_uri_id) + ) + logger.info( + f"Updated SSM parameter '{last_accession_parameter}' " + f"to '{updated_last_accession_uri_id}'" + ) elapsed_time = perf_counter() - start_time logger.info( diff --git a/pyproject.toml b/pyproject.toml index 00f5162..603dde8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ ignore = [ "PLR0915", "S320", "S321", - "G004", + "G004" ] # allow autofix behavior for specified rules diff --git a/tests/conftest.py b/tests/conftest.py index a9691e9..f1ad720 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,6 +15,21 @@ def _test_env(monkeypatch): monkeypatch.setenv("AWS_SESSION_TOKEN", "testing") +@pytest.fixture +def aspace_record(): + return { + "title": "MIT Libraries records and Bibliotech newsletters 2024 July transfer", + "id_0": "2025", + "id_1": "014", + "extents": [ + { + "number": "1", + "extent_type": "box(es)", + } + ], + } + + @pytest.fixture def runner(): return CliRunner() diff --git a/tests/test_cli.py b/tests/test_cli.py index 027ef7c..3b403c1 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,17 +1,48 @@ +import logging +from unittest.mock import patch + from asati.cli import main -def test_cli_no_options(caplog, runner): - result = runner.invoke(main) +@patch("asati.cli.ASnakeClient") +@patch("asati.cli.pyairtable") +def test_cli_new_accessions_success( + mocked_airtable, mocked_asnake, aspace_record, caplog, runner +): + mocked_asnake.return_value.get.return_value.json.side_effect = [ + [1234, 5678], + aspace_record, + ] + mocked_airtable.Api.return_value.table.return_value.create.return_value = { + "fields": {"Accession Number": "2025-014"} + } + caplog.set_level(logging.DEBUG) + result = runner.invoke(main, ["--verbose"]) assert result.exit_code == 0 - assert "Logger 'root' configured with level=INFO" in caplog.text + assert "Logger 'root' configured with level=DEBUG" in caplog.text assert "Running process" in caplog.text + assert ( + "Data extracted from ArchivesSpace: {'Accession Title': 'MIT Libraries records " + "and Bibliotech newsletters 2024 July transfer', 'Accession Number': '2025-014'," + " 'Current Status': 'Unassigned', 'Extent Number': 1.0, 'Extent Type': 'box(es)'}" + in caplog.text + ) + assert "Airtable row created for Accession Number: '2025-014'" in caplog.text + assert ( + "Updated SSM parameter '/apps/asati/last-accession-uri-id' to '5678'" + in caplog.text + ) assert "Total time to complete process" in caplog.text -def test_cli_all_options(caplog, runner): - result = runner.invoke(main, ["--verbose"]) +@patch("asati.cli.ASnakeClient") +def test_cli_no_accessions_success(mocked_asnake, caplog, runner): + mocked_asnake.return_value.get.return_value.json.return_value = [1234] + result = runner.invoke(main) assert result.exit_code == 0 - assert "Logger 'root' configured with level=DEBUG" in caplog.text + assert "Logger 'root' configured with level=INFO" in caplog.text assert "Running process" in caplog.text + assert "No new accessions to add to Airtable." in caplog.text assert "Total time to complete process" in caplog.text + assert "Airtable row created for Accession Number:" not in caplog.text + assert "Updated SSM parameter" not in caplog.text