From 776ef1c0081d954228746d3b52610daca41f63a1 Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Mon, 22 Jan 2024 13:15:58 -0800 Subject: [PATCH 01/15] revise postgres dependencies --- airbyte-lib/airbyte_lib/caches/postgres.py | 4 +- airbyte-lib/poetry.lock | 495 ++++++++------------- airbyte-lib/poetry.toml | 2 + airbyte-lib/pyproject.toml | 8 +- 4 files changed, 198 insertions(+), 311 deletions(-) create mode 100644 airbyte-lib/poetry.toml diff --git a/airbyte-lib/airbyte_lib/caches/postgres.py b/airbyte-lib/airbyte_lib/caches/postgres.py index 72fe8291bf54..5c7df3a898ad 100644 --- a/airbyte-lib/airbyte_lib/caches/postgres.py +++ b/airbyte-lib/airbyte_lib/caches/postgres.py @@ -28,9 +28,7 @@ class PostgresCacheConfig(SQLCacheConfigBase, ParquetWriterConfig): @overrides def get_sql_alchemy_url(self) -> str: """Return the SQLAlchemy URL to use.""" - return ( - f"postgresql://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}" - ) + return f"postgresql+psycopg2://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}" def get_database_name(self) -> str: """Return the name of the database.""" diff --git a/airbyte-lib/poetry.lock b/airbyte-lib/poetry.lock index 06576ed330a2..bbd7435528b2 100644 --- a/airbyte-lib/poetry.lock +++ b/airbyte-lib/poetry.lock @@ -879,77 +879,73 @@ format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-va [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.4" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, -] - -[[package]] -name = "mirakuru" -version = "2.5.2" -description = "Process executor (not only) for tests." -optional = false -python-versions = ">=3.8" -files = [ - {file = "mirakuru-2.5.2-py3-none-any.whl", hash = "sha256:90c2d90a8cf14349b2f33e6db30a16acd855499811e0312e56cf80ceacf2d3e5"}, - {file = "mirakuru-2.5.2.tar.gz", hash = "sha256:41ca583d355eb7a6cfdc21c1aea549979d685c27b57239b88725434f115a7132"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-win32.whl", hash = "sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-win32.whl", hash = "sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-win32.whl", hash = "sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-win32.whl", hash = "sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-win_amd64.whl", hash = "sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-win32.whl", hash = "sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-win_amd64.whl", hash = "sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-win32.whl", hash = "sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959"}, + {file = "MarkupSafe-2.1.4.tar.gz", hash = "sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f"}, ] -[package.dependencies] -psutil = {version = ">=4.0.0", markers = "sys_platform != \"cygwin\""} - [[package]] name = "mypy" version = "1.8.0" @@ -1300,17 +1296,6 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[[package]] -name = "port-for" -version = "0.7.2" -description = "Utility that helps with local TCP ports management. It can find an unused TCP localhost port and remember the association." -optional = false -python-versions = ">=3.8" -files = [ - {file = "port-for-0.7.2.tar.gz", hash = "sha256:074f29335130578aa42fef3726985e57d01c15189e509633a8a1b0b7f9226349"}, - {file = "port_for-0.7.2-py3-none-any.whl", hash = "sha256:16b279ab4f210bad33515c45bd9af0c6e048ab24c3b6bbd9cfc7e451782617df"}, -] - [[package]] name = "proto-plus" version = "1.23.0" @@ -1349,166 +1334,84 @@ files = [ ] [[package]] -name = "psutil" -version = "5.9.7" -description = "Cross-platform lib for process and system monitoring in Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "psutil-5.9.7-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0bd41bf2d1463dfa535942b2a8f0e958acf6607ac0be52265ab31f7923bcd5e6"}, - {file = "psutil-5.9.7-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:5794944462509e49d4d458f4dbfb92c47539e7d8d15c796f141f474010084056"}, - {file = "psutil-5.9.7-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:fe361f743cb3389b8efda21980d93eb55c1f1e3898269bc9a2a1d0bb7b1f6508"}, - {file = "psutil-5.9.7-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:e469990e28f1ad738f65a42dcfc17adaed9d0f325d55047593cb9033a0ab63df"}, - {file = "psutil-5.9.7-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:3c4747a3e2ead1589e647e64aad601981f01b68f9398ddf94d01e3dc0d1e57c7"}, - {file = "psutil-5.9.7-cp27-none-win32.whl", hash = "sha256:1d4bc4a0148fdd7fd8f38e0498639ae128e64538faa507df25a20f8f7fb2341c"}, - {file = "psutil-5.9.7-cp27-none-win_amd64.whl", hash = "sha256:4c03362e280d06bbbfcd52f29acd79c733e0af33d707c54255d21029b8b32ba6"}, - {file = "psutil-5.9.7-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ea36cc62e69a13ec52b2f625c27527f6e4479bca2b340b7a452af55b34fcbe2e"}, - {file = "psutil-5.9.7-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1132704b876e58d277168cd729d64750633d5ff0183acf5b3c986b8466cd0284"}, - {file = "psutil-5.9.7-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8b7f07948f1304497ce4f4684881250cd859b16d06a1dc4d7941eeb6233bfe"}, - {file = "psutil-5.9.7-cp36-cp36m-win32.whl", hash = "sha256:b27f8fdb190c8c03914f908a4555159327d7481dac2f01008d483137ef3311a9"}, - {file = "psutil-5.9.7-cp36-cp36m-win_amd64.whl", hash = "sha256:44969859757f4d8f2a9bd5b76eba8c3099a2c8cf3992ff62144061e39ba8568e"}, - {file = "psutil-5.9.7-cp37-abi3-win32.whl", hash = "sha256:c727ca5a9b2dd5193b8644b9f0c883d54f1248310023b5ad3e92036c5e2ada68"}, - {file = "psutil-5.9.7-cp37-abi3-win_amd64.whl", hash = "sha256:f37f87e4d73b79e6c5e749440c3113b81d1ee7d26f21c19c47371ddea834f414"}, - {file = "psutil-5.9.7-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:032f4f2c909818c86cea4fe2cc407f1c0f0cde8e6c6d702b28b8ce0c0d143340"}, - {file = "psutil-5.9.7.tar.gz", hash = "sha256:3f02134e82cfb5d089fddf20bb2e03fd5cd52395321d1c8458a9e58500ff417c"}, -] - -[package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] - -[[package]] -name = "psycopg" -version = "3.1.17" -description = "PostgreSQL database adapter for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "psycopg-3.1.17-py3-none-any.whl", hash = "sha256:96b7b13af6d5a514118b759a66b2799a8a4aa78675fa6bb0d3f7d52d67eff002"}, - {file = "psycopg-3.1.17.tar.gz", hash = "sha256:437e7d7925459f21de570383e2e10542aceb3b9cb972ce957fdd3826ca47edc6"}, -] - -[package.dependencies] -psycopg-binary = {version = "3.1.17", optional = true, markers = "implementation_name != \"pypy\" and extra == \"binary\""} -psycopg-pool = {version = "*", optional = true, markers = "extra == \"pool\""} -typing-extensions = ">=4.1" -tzdata = {version = "*", markers = "sys_platform == \"win32\""} - -[package.extras] -binary = ["psycopg-binary (==3.1.17)"] -c = ["psycopg-c (==3.1.17)"] -dev = ["black (>=23.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=1.4.1)", "types-setuptools (>=57.4)", "wheel (>=0.37)"] -docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"] -pool = ["psycopg-pool"] -test = ["anyio (>=3.6.2,<4.0)", "mypy (>=1.4.1)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"] - -[[package]] -name = "psycopg-binary" -version = "3.1.17" -description = "PostgreSQL database adapter for Python -- C optimisation distribution" -optional = false -python-versions = ">=3.7" -files = [ - {file = "psycopg_binary-3.1.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9ba559eabb0ba1afd4e0504fa0b10e00a212cac0c4028b8a1c3b087b5c1e5de"}, - {file = "psycopg_binary-3.1.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2b2a689eaede08cf91a36b10b0da6568dd6e4669200f201e082639816737992b"}, - {file = "psycopg_binary-3.1.17-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a16abab0c1abc58feb6ab11d78d0f8178a67c3586bd70628ec7c0218ec04c4ef"}, - {file = "psycopg_binary-3.1.17-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:73e7097b81cad9ae358334e3cec625246bb3b8013ae6bb287758dd6435e12f65"}, - {file = "psycopg_binary-3.1.17-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:67a5b93101bc85a95a189c0a23d02a29cf06c1080a695a0dedfdd50dd734662a"}, - {file = "psycopg_binary-3.1.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:751b31c2faae0348f87f22b45ef58f704bdcfc2abdd680fa0c743c124071157e"}, - {file = "psycopg_binary-3.1.17-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b447ea765e71bc33a82cf070bba814b1efa77967442d116b95ccef8ce5da7631"}, - {file = "psycopg_binary-3.1.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d2e9ed88d9a6a475c67bf70fc8285e88ccece0391727c7701e5a512e0eafbb05"}, - {file = "psycopg_binary-3.1.17-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a89f36bf7b612ff6ed3e789bd987cbd0787cf0d66c49386fa3bad816dd7bee87"}, - {file = "psycopg_binary-3.1.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5ccbe8b2ec444763a51ecb1213befcbb75defc1ef36e7dd5dff501a23d7ce8cf"}, - {file = "psycopg_binary-3.1.17-cp310-cp310-win_amd64.whl", hash = "sha256:adb670031b27949c9dc5cf585c4a5a6b4469d3879fd2fb9d39b6d53e5f66b9bc"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0227885686c2cc0104ceb22d6eebc732766e9ad48710408cb0123237432e5435"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9124b6db07e8d8b11f4512b8b56cbe136bf1b7d0417d1280e62291a9dcad4408"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8a46f77ba0ca7c5a5449b777170a518fa7820e1710edb40e777c9798f00d033"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f5f5bcbb772d8c243d605fc7151beec760dd27532d42145a58fb74ef9c5fbf2"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:267a82548c21476120e43dc72b961f1af52c380c0b4c951bdb34cf14cb26bd35"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b20013051f1fd7d02b8d0766cfe8d009e8078babc00a6d39bc7e2d50a7b96af"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c5c38129cc79d7e3ba553035b9962a442171e9f97bb1b8795c0885213f206f3"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d01c4faae66de60fcd3afd3720dcc8ffa03bc2087f898106da127774db12aac5"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e6ae27b0617ad3809449964b5e901b21acff8e306abacb8ba71d5ee7c8c47eeb"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:40af298b209dd77ca2f3e7eb3fbcfb87a25999fc015fcd14140bde030a164c7e"}, - {file = "psycopg_binary-3.1.17-cp311-cp311-win_amd64.whl", hash = "sha256:7b4e4c2b05f3b431e9026e82590b217e87696e7a7548f512ae8059d59fa8af3b"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ea425a8dcd808a7232a5417d2633bfa543da583a2701b5228e9e29989a50deda"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3f1196d76860e72d338fab0d2b6722e8d47e2285d693e366ae36011c4a5898a"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1e867c2a729348df218a14ba1b862e627177fd57c7b4f3db0b4c708f6d03696"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0711e46361ea3047cd049868419d030c8236a9dea7e9ed1f053cbd61a853ec9"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1c0115bdf80cf6c8c9109cb10cf6f650fd1a8d841f884925e8cb12f34eb5371"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d0d154c780cc7b28a3a0886e8a4b18689202a1dbb522b3c771eb3a1289cf7c3"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f4028443bf25c1e04ecffdc552c0a98d826903dec76a1568dfddf5ebbbb03db7"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf424d92dd7e94705b31625b02d396297a7c8fab4b6f7de8dba6388323a7b71c"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:00377f6963ee7e4bf71cab17c2c235ef0624df9483f3b615d86aa24cde889d42"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9690a535d9ccd361bbc3590bfce7fe679e847f44fa7cc97f3b885f4744ca8a2c"}, - {file = "psycopg_binary-3.1.17-cp312-cp312-win_amd64.whl", hash = "sha256:6b2ae342d69684555bfe77aed5546d125b4a99012e0b83a8b3da68c8829f0935"}, - {file = "psycopg_binary-3.1.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:86bb3656c8d744cc1e42003414cd6c765117d70aa23da6c0f4ff2b826e0fd0fd"}, - {file = "psycopg_binary-3.1.17-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c10b7713e3ed31df7319c2a72d5fea5a2536476d7695a3e1d18a1f289060997c"}, - {file = "psycopg_binary-3.1.17-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12eab8bc91b4ba01b2ecee3b5b80501934b198f6e1f8d4b13596f3f38ba6e762"}, - {file = "psycopg_binary-3.1.17-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a728beefd89b430ebe2729d04ba10e05036b5e9d01648da60436000d2fcd242"}, - {file = "psycopg_binary-3.1.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61104b8e7a43babf2bbaa36c08e31a12023e2f967166e99d6b052b11a4c7db06"}, - {file = "psycopg_binary-3.1.17-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:02cd2eb62ffc56f8c847d68765cbf461b3d11b438fe48951e44b6c563ec27d18"}, - {file = "psycopg_binary-3.1.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ca1757a6e080086f7234dc45684e81a47a66a6dd492a37d6ce38c58a1a93e9ff"}, - {file = "psycopg_binary-3.1.17-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:6e3543edc18553e31a3884af3cd7eea43d6c44532d8b9b16f3e743cdf6cfe6c5"}, - {file = "psycopg_binary-3.1.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:914254849486e14aa931b0b3382cd16887f1507068ffba775cbdc5a55fe9ef19"}, - {file = "psycopg_binary-3.1.17-cp37-cp37m-win_amd64.whl", hash = "sha256:92fad8f1aa80a5ab316c0493dc6d1b54c1dba21937e43eea7296ff4a0ccc071e"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6d4f2e15d33ed4f9776fdf23683512d76f4e7825c4b80677e9e3ce6c1b193ff2"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4fa26836ce074a1104249378727e1f239a01530f36bae16e77cf6c50968599b4"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d54bcf2dfc0880bf13f38512d44b194c092794e4ee9e01d804bc6cd3eed9bfb7"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e28024204dc0c61094268c682041d2becfedfea2e3b46bed5f6138239304d98"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b1ec6895cab887b92c303565617f994c9b9db53befda81fa2a31b76fe8a3ab1"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:420c1eb1626539c261cf3fbe099998da73eb990f9ce1a34da7feda414012ea5f"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:83404a353240fdff5cfe9080665fdfdcaa2d4d0c5112e15b0a2fe2e59200ed57"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a0c4ba73f9e7721dd6cc3e6953016652dbac206f654229b7a1a8ac182b16e689"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f6898bf1ca5aa01115807643138e3e20ec603b17a811026bc4a49d43055720a7"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6b40fa54a02825d3d6a8009d9a82a2b4fad80387acf2b8fd6d398fd2813cb2d9"}, - {file = "psycopg_binary-3.1.17-cp38-cp38-win_amd64.whl", hash = "sha256:78ebb43dca7d5b41eee543cd005ee5a0256cecc74d84acf0fab4f025997b837e"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:02ac573f5a6e79bb6df512b3a6279f01f033bbd45c47186e8872fee45f6681d0"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:704f6393d758b12a4369887fe956b2a8c99e4aced839d9084de8e3f056015d40"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0340ef87a888fd940796c909e038426f4901046f61856598582a817162c64984"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a880e4113af3ab84d6a0991e3f85a2424924c8a182733ab8d964421df8b5190a"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93921178b9a40c60c26e47eb44970f88c49fe484aaa3bb7ec02bb8b514eab3d9"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a05400e9314fc30bc1364865ba9f6eaa2def42b5e7e67f71f9a4430f870023e"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e2cc2bbf37ff1cf11e8b871c294e3532636a3cf7f0c82518b7537158923d77b"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a343261701a8f63f0d8268f7fd32be40ffe28d24b65d905404ca03e7281f7bb5"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:dceb3930ec426623c0cacc78e447a90882981e8c49d6fea8d1e48850e24a0170"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d613a23f8928f30acb2b6b2398cb7775ba9852e8968e15df13807ba0d3ebd565"}, - {file = "psycopg_binary-3.1.17-cp39-cp39-win_amd64.whl", hash = "sha256:d90c0531e9d591bde8cea04e75107fcddcc56811b638a34853436b23c9a3cb7d"}, -] - -[[package]] -name = "psycopg-pool" -version = "3.2.1" -description = "Connection Pool for Psycopg" -optional = false -python-versions = ">=3.8" -files = [ - {file = "psycopg-pool-3.2.1.tar.gz", hash = "sha256:6509a75c073590952915eddbba7ce8b8332a440a31e77bba69561483492829ad"}, - {file = "psycopg_pool-3.2.1-py3-none-any.whl", hash = "sha256:060b551d1b97a8d358c668be58b637780b884de14d861f4f5ecc48b7563aafb7"}, -] - -[package.dependencies] -typing-extensions = ">=4.4" - -[[package]] -name = "psycopg2" +name = "psycopg2-binary" version = "2.9.9" description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = false python-versions = ">=3.7" files = [ - {file = "psycopg2-2.9.9-cp310-cp310-win32.whl", hash = "sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516"}, - {file = "psycopg2-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3"}, - {file = "psycopg2-2.9.9-cp311-cp311-win32.whl", hash = "sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372"}, - {file = "psycopg2-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981"}, - {file = "psycopg2-2.9.9-cp312-cp312-win32.whl", hash = "sha256:d735786acc7dd25815e89cc4ad529a43af779db2e25aa7c626de864127e5a024"}, - {file = "psycopg2-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:a7653d00b732afb6fc597e29c50ad28087dcb4fbfb28e86092277a559ae4e693"}, - {file = "psycopg2-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa"}, - {file = "psycopg2-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a"}, - {file = "psycopg2-2.9.9-cp38-cp38-win32.whl", hash = "sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c"}, - {file = "psycopg2-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e"}, - {file = "psycopg2-2.9.9-cp39-cp39-win32.whl", hash = "sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59"}, - {file = "psycopg2-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913"}, - {file = "psycopg2-2.9.9.tar.gz", hash = "sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156"}, + {file = "psycopg2-binary-2.9.9.tar.gz", hash = "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-win32.whl", hash = "sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-win32.whl", hash = "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-win32.whl", hash = "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-win32.whl", hash = "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-win32.whl", hash = "sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957"}, ] [[package]] @@ -1607,47 +1510,47 @@ files = [ [[package]] name = "pydantic" -version = "1.10.13" +version = "1.10.14" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"}, - {file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"}, - {file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"}, - {file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"}, - {file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"}, - {file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"}, - {file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"}, - {file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"}, - {file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"}, - {file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"}, + {file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"}, + {file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"}, + {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"}, + {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"}, + {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"}, + {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"}, + {file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"}, + {file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"}, + {file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"}, + {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"}, + {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"}, + {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"}, + {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"}, + {file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"}, + {file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"}, + {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"}, + {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"}, + {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"}, + {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"}, + {file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"}, + {file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"}, + {file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"}, + {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"}, + {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"}, + {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"}, + {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"}, + {file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"}, + {file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"}, + {file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"}, + {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"}, + {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"}, + {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"}, + {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"}, + {file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"}, + {file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"}, + {file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"}, ] [package.dependencies] @@ -1827,24 +1730,6 @@ pytest = [ {version = ">=4.6", markers = "python_version >= \"3.6\" and python_version < \"3.10\""}, ] -[[package]] -name = "pytest-postgresql" -version = "5.0.0" -description = "Postgresql fixtures and fixture factories for Pytest." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-postgresql-5.0.0.tar.gz", hash = "sha256:22edcbafab8995ee85b8d948ddfaad4f70c2c7462303d7477ecd2f77fc9d15bd"}, - {file = "pytest_postgresql-5.0.0-py3-none-any.whl", hash = "sha256:6e8f0773b57c9b8975b6392c241b7b81b7018f32079a533f368f2fbda732ecd3"}, -] - -[package.dependencies] -mirakuru = "*" -port-for = ">=0.6.0" -psycopg = ">=3.0.0" -pytest = ">=6.2" -setuptools = "*" - [[package]] name = "python-dateutil" version = "2.8.2" @@ -2154,28 +2039,28 @@ pyasn1 = ">=0.1.3" [[package]] name = "ruff" -version = "0.1.13" +version = "0.1.14" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.13-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e3fd36e0d48aeac672aa850045e784673449ce619afc12823ea7868fcc41d8ba"}, - {file = "ruff-0.1.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9fb6b3b86450d4ec6a6732f9f60c4406061b6851c4b29f944f8c9d91c3611c7a"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b13ba5d7156daaf3fd08b6b993360a96060500aca7e307d95ecbc5bb47a69296"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ebb40442f7b531e136d334ef0851412410061e65d61ca8ce90d894a094feb22"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226b517f42d59a543d6383cfe03cccf0091e3e0ed1b856c6824be03d2a75d3b6"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5f0312ba1061e9b8c724e9a702d3c8621e3c6e6c2c9bd862550ab2951ac75c16"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2f59bcf5217c661254bd6bc42d65a6fd1a8b80c48763cb5c2293295babd945dd"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6894b00495e00c27b6ba61af1fc666f17de6140345e5ef27dd6e08fb987259d"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1600942485c6e66119da294c6294856b5c86fd6df591ce293e4a4cc8e72989"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ee3febce7863e231a467f90e681d3d89210b900d49ce88723ce052c8761be8c7"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dcaab50e278ff497ee4d1fe69b29ca0a9a47cd954bb17963628fa417933c6eb1"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f57de973de4edef3ad3044d6a50c02ad9fc2dff0d88587f25f1a48e3f72edf5e"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7a36fa90eb12208272a858475ec43ac811ac37e91ef868759770b71bdabe27b6"}, - {file = "ruff-0.1.13-py3-none-win32.whl", hash = "sha256:a623349a505ff768dad6bd57087e2461be8db58305ebd5577bd0e98631f9ae69"}, - {file = "ruff-0.1.13-py3-none-win_amd64.whl", hash = "sha256:f988746e3c3982bea7f824c8fa318ce7f538c4dfefec99cd09c8770bd33e6539"}, - {file = "ruff-0.1.13-py3-none-win_arm64.whl", hash = "sha256:6bbbc3042075871ec17f28864808540a26f0f79a4478c357d3e3d2284e832998"}, - {file = "ruff-0.1.13.tar.gz", hash = "sha256:e261f1baed6291f434ffb1d5c6bd8051d1c2a26958072d38dfbec39b3dda7352"}, + {file = "ruff-0.1.14-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:96f76536df9b26622755c12ed8680f159817be2f725c17ed9305b472a757cdbb"}, + {file = "ruff-0.1.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ab3f71f64498c7241123bb5a768544cf42821d2a537f894b22457a543d3ca7a9"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7060156ecc572b8f984fd20fd8b0fcb692dd5d837b7606e968334ab7ff0090ab"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a53d8e35313d7b67eb3db15a66c08434809107659226a90dcd7acb2afa55faea"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bea9be712b8f5b4ebed40e1949379cfb2a7d907f42921cf9ab3aae07e6fba9eb"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2270504d629a0b064247983cbc495bed277f372fb9eaba41e5cf51f7ba705a6a"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80258bb3b8909b1700610dfabef7876423eed1bc930fe177c71c414921898efa"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:653230dd00aaf449eb5ff25d10a6e03bc3006813e2cb99799e568f55482e5cae"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b3acc6c4e6928459ba9eb7459dd4f0c4bf266a053c863d72a44c33246bfdbf"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6b3dadc9522d0eccc060699a9816e8127b27addbb4697fc0c08611e4e6aeb8b5"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1c8eca1a47b4150dc0fbec7fe68fc91c695aed798532a18dbb1424e61e9b721f"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:62ce2ae46303ee896fc6811f63d6dabf8d9c389da0f3e3f2bce8bc7f15ef5488"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b2027dde79d217b211d725fc833e8965dc90a16d0d3213f1298f97465956661b"}, + {file = "ruff-0.1.14-py3-none-win32.whl", hash = "sha256:722bafc299145575a63bbd6b5069cb643eaa62546a5b6398f82b3e4403329cab"}, + {file = "ruff-0.1.14-py3-none-win_amd64.whl", hash = "sha256:e3d241aa61f92b0805a7082bd89a9990826448e4d0398f0e2bc8f05c75c63d99"}, + {file = "ruff-0.1.14-py3-none-win_arm64.whl", hash = "sha256:269302b31ade4cde6cf6f9dd58ea593773a37ed3f7b97e793c8594b262466b67"}, + {file = "ruff-0.1.14.tar.gz", hash = "sha256:ad3f8088b2dfd884820289a06ab718cde7d38b94972212cc4ba90d5fbc9955f3"}, ] [[package]] @@ -2609,4 +2494,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "5457f59d89d371fbdacd1a5ba132de627ad4f7b6bd2c073fe75b54d90d216e5f" +content-hash = "eb7f87eb174b6eabbd28d336a4e4059cb77f886c9e8c40fec0db577803036585" diff --git a/airbyte-lib/poetry.toml b/airbyte-lib/poetry.toml new file mode 100644 index 000000000000..ab1033bd3722 --- /dev/null +++ b/airbyte-lib/poetry.toml @@ -0,0 +1,2 @@ +[virtualenvs] +in-project = true diff --git a/airbyte-lib/pyproject.toml b/airbyte-lib/pyproject.toml index a1aea3d19bd4..35c99ab59965 100644 --- a/airbyte-lib/pyproject.toml +++ b/airbyte-lib/pyproject.toml @@ -15,7 +15,7 @@ jsonschema = "3.2.0" orjson = "^3.9.10" overrides = "^7.4.0" pandas = "^2.1.4" -psycopg = {extras = ["binary", "pool"], version = "^3.1.16"} +psycopg2-binary = "^2.9.9" python-ulid = "^2.2.0" types-pyyaml = "^6.0.12.12" ulid = "^1.1" @@ -25,7 +25,10 @@ snowflake-sqlalchemy = "^1.5.1" duckdb-engine = "^0.10.0" requests = "^2.31.0" pyarrow = "^14.0.2" -psycopg2 = "^2.9.9" + +# Psycopg3 is not supported in SQLAlchemy 1.x: +# psycopg = {extras = ["binary", "pool"], version = "^3.1.16"} + [tool.poetry.group.dev.dependencies] docker = "^7.0.0" @@ -37,7 +40,6 @@ pyarrow-stubs = "^10.0.1.7" pytest = "^7.4.3" pytest-docker = "^2.0.1" pytest-mypy = "^0.10.3" -pytest-postgresql = "^5.0.0" ruff = "^0.1.11" types-jsonschema = "^4.20.0.0" google-cloud-secret-manager = "^2.17.0" From e958779673b58ebb100bef7faf993f55a1991a8a Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Mon, 22 Jan 2024 13:16:43 -0800 Subject: [PATCH 02/15] add tests for lazy, sql, and cached datasets --- .../integration_tests/test_integration.py | 95 ++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/airbyte-lib/tests/integration_tests/test_integration.py b/airbyte-lib/tests/integration_tests/test_integration.py index c9bdfbf91415..378d26e68888 100644 --- a/airbyte-lib/tests/integration_tests/test_integration.py +++ b/airbyte-lib/tests/integration_tests/test_integration.py @@ -16,6 +16,10 @@ from airbyte_lib.registry import _update_cache from airbyte_lib.version import get_version from airbyte_lib.results import ReadResult +from airbyte_lib.datasets import CachedDataset, DatasetBase, LazyDataset, LazySQLDataset +import airbyte_lib as ab + +from airbyte_lib.results import ReadResult @pytest.fixture(scope="module", autouse=True) @@ -185,6 +189,93 @@ def test_sync_with_merge_to_duckdb(expected_test_stream_data: dict[str, list[dic ) +def test_cached_dataset(): + source = ab.get_connector("source-test", config={"apiKey": "test"}) + result: ReadResult = source.read(ab.new_local_cache()) + + stream_name = "stream1" + not_a_stream_name = "not_a_stream" + + # Check that the stream appears in mapping-like attributes + assert stream_name in result.cache._streams_with_data + assert stream_name in result + assert stream_name in result.cache.streams + assert stream_name in result.streams + + stream_get_a: CachedDataset = result[stream_name] + stream_get_b: CachedDataset = result.streams[stream_name] + stream_get_c: CachedDataset = result.cache.streams[stream_name] + + # Check that each get method is syntactically equivalent + + assert isinstance(stream_get_a, CachedDataset) + assert isinstance(stream_get_b, CachedDataset) + assert isinstance(stream_get_c, CachedDataset) + + assert stream_get_a == stream_get_b + assert stream_get_b == stream_get_c + + # Check that we can iterate over the stream + + list_from_iter_a = list(stream_get_a) + list_from_iter_b = [row for row in stream_get_a] + + # Make sure that we get a key error if we try to access a stream that doesn't exist + with pytest.raises(KeyError): + result[not_a_stream_name] + with pytest.raises(KeyError): + result.streams[not_a_stream_name] + with pytest.raises(KeyError): + result.cache.streams[not_a_stream_name] + + +def test_lazy_dataset_from_source(): + source = ab.get_connector("source-test", config={"apiKey": "test"}) + + stream_name = "stream1" + not_a_stream_name = "not_a_stream" + + lazy_dataset_a = source.get_records(stream_name) + lazy_dataset_b = source.get_records(stream_name) + + assert isinstance(lazy_dataset_a, LazyDataset) + + # Check that we can iterate over the stream + + list_from_iter_a = list(lazy_dataset_a) + list_from_iter_b = [row for row in lazy_dataset_b] + + assert list_from_iter_a == list_from_iter_b + + # Make sure that we get a key error if we try to access a stream that doesn't exist + with pytest.raises(KeyError): + source.get_records(not_a_stream_name) + + +def test_lazy_sql_dataset_from_cache(): + source = ab.get_connector("source-test", config={"apiKey": "test"}) + + stream_name = "stream1" + not_a_stream_name = "not_a_stream" + + lazy_dataset_a = source.get_records(stream_name) + lazy_dataset_b = source.get_records(stream_name) + lazy_dataset_c = source.get_records(stream_name) + + assert isinstance(lazy_dataset_a, LazyDataset) + + # Check that we can iterate over the stream + + list_from_iter_a = list(lazy_dataset_a) + list_from_iter_b = [row for row in lazy_dataset_b] + + assert list_from_iter_a == list_from_iter_b + + # Make sure that we get a key error if we try to access a stream that doesn't exist + with pytest.raises(KeyError): + source.get_records(not_a_stream_name) + + @pytest.mark.parametrize( "method_call", [ @@ -260,7 +351,7 @@ def test_tracking(mock_datetime: Mock, mock_requests: Mock, raises: bool, api_ke source.read(cache) else: source.read(cache) - + mock_post.assert_has_calls([ call("https://api.segment.io/v1/track", @@ -387,4 +478,4 @@ def test_install_uninstall(): source.install() - source.check() \ No newline at end of file + source.check() From 21d69ef66b551443b3d4d8ef6c1217099e80b6fb Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Mon, 22 Jan 2024 13:17:35 -0800 Subject: [PATCH 03/15] working and passing tests: sql, lazy, and cached datasets --- airbyte-lib/airbyte_lib/__init__.py | 5 +- airbyte-lib/airbyte_lib/_processors.py | 5 + .../airbyte_lib/_util/protocol_util.py | 2 +- airbyte-lib/airbyte_lib/caches/base.py | 36 ++++--- airbyte-lib/airbyte_lib/datasets/__init__.py | 5 +- airbyte-lib/airbyte_lib/datasets/_base.py | 11 +-- airbyte-lib/airbyte_lib/datasets/_cached.py | 98 ++++++++++++++++--- airbyte-lib/airbyte_lib/datasets/_lazy.py | 32 ++---- airbyte-lib/airbyte_lib/results.py | 15 +++ airbyte-lib/airbyte_lib/source.py | 9 +- airbyte-lib/tests/conftest.py | 2 +- 11 files changed, 148 insertions(+), 72 deletions(-) diff --git a/airbyte-lib/airbyte_lib/__init__.py b/airbyte-lib/airbyte_lib/__init__.py index 895849f19771..0e98616b0443 100644 --- a/airbyte-lib/airbyte_lib/__init__.py +++ b/airbyte-lib/airbyte_lib/__init__.py @@ -2,16 +2,19 @@ from airbyte_lib._factories.cache_factories import get_default_cache, new_local_cache from airbyte_lib._factories.connector_factories import get_connector +from airbyte_lib.caches import DuckDBCache, DuckDBCacheConfig from airbyte_lib.datasets import CachedDataset from airbyte_lib.results import ReadResult from airbyte_lib.source import Source __all__ = [ + "CachedDataset", + "DuckDBCache", + "DuckDBCacheConfig", "get_connector", "get_default_cache", "new_local_cache", - "CachedDataset", "ReadResult", "Source", ] diff --git a/airbyte-lib/airbyte_lib/_processors.py b/airbyte-lib/airbyte_lib/_processors.py index f0f94c30c512..2fc92a392bfc 100644 --- a/airbyte-lib/airbyte_lib/_processors.py +++ b/airbyte-lib/airbyte_lib/_processors.py @@ -99,6 +99,11 @@ def register_source( _ = source_name self.source_catalog = source_catalog + @property + def _streams_with_data(self) -> set[str]: + """Return a list of known streams.""" + return self._pending_batches.keys() | self._finalized_batches.keys() + @final def process_stdin( self, diff --git a/airbyte-lib/airbyte_lib/_util/protocol_util.py b/airbyte-lib/airbyte_lib/_util/protocol_util.py index 58ada9f5435b..f4e5ab3fb293 100644 --- a/airbyte-lib/airbyte_lib/_util/protocol_util.py +++ b/airbyte-lib/airbyte_lib/_util/protocol_util.py @@ -66,6 +66,6 @@ def get_primary_keys_from_stream( None, ) if stream is None: - raise ValueError(f"Stream {stream_name} not found in catalog.") + raise KeyError(f"Stream {stream_name} not found in catalog.") return set(stream.stream.source_defined_primary_key or []) diff --git a/airbyte-lib/airbyte_lib/caches/base.py b/airbyte-lib/airbyte_lib/caches/base.py index 0e3ad837b194..9fe4d8789d8c 100644 --- a/airbyte-lib/airbyte_lib/caches/base.py +++ b/airbyte-lib/airbyte_lib/caches/base.py @@ -5,7 +5,6 @@ import abc import enum -from collections.abc import Generator, Iterator, Mapping from contextlib import contextmanager from functools import cached_property from typing import TYPE_CHECKING, Any, cast, final @@ -22,10 +21,12 @@ from airbyte_lib._file_writers.base import FileWriterBase, FileWriterBatchHandle from airbyte_lib._processors import BatchHandle, RecordProcessor from airbyte_lib.config import CacheConfigBase +from airbyte_lib.datasets._cached import CachedDataset from airbyte_lib.types import SQLTypeConverter if TYPE_CHECKING: + from collections.abc import Generator, Iterator from pathlib import Path from sqlalchemy.engine import Connection, Engine @@ -118,6 +119,15 @@ def __init__( self.file_writer = file_writer or self.file_writer_class(config) self.type_converter = self.type_converter_class() + def __getitem__(self, stream: str) -> DatasetBase: + return self.streams[stream] + + def __contains__(self, stream: str) -> bool: + return stream in self._streams_with_data + + def __iter__(self) -> Iterator[str]: + return iter(self._streams_with_data) + # Public interface: def get_sql_alchemy_url(self) -> str: @@ -211,28 +221,22 @@ def get_sql_table( @property def streams( self, - ) -> dict[str, DatasetBase]: + ) -> dict[str, CachedDataset]: """Return a temporary table name.""" - # TODO: Add support for streams map, based on the cached catalog. - raise NotImplementedError("Streams map is not yet supported.") + result = {} + for stream_name in self._streams_with_data: + result[stream_name] = CachedDataset(self, stream_name) + + return result # Read methods: def get_records( self, stream_name: str, - ) -> Iterator[Mapping[str, Any]]: - """Uses SQLAlchemy to select all rows from the table. - - # TODO: Refactor to return a LazyDataset here. - """ - table_ref = self.get_sql_table(stream_name) - stmt = table_ref.select() - with self.get_sql_connection() as conn: - for row in conn.execute(stmt): - # Access to private member required because SQLAlchemy doesn't expose a public API. - # https://pydoc.dev/sqlalchemy/latest/sqlalchemy.engine.row.RowMapping.html - yield cast(Mapping[str, Any], row._mapping) # noqa: SLF001 + ) -> CachedDataset: + """Uses SQLAlchemy to select all rows from the table.""" + return CachedDataset(self, stream_name) def get_pandas_dataframe( self, diff --git a/airbyte-lib/airbyte_lib/datasets/__init__.py b/airbyte-lib/airbyte_lib/datasets/__init__.py index 862eee3e8baf..daed8d0ad639 100644 --- a/airbyte-lib/airbyte_lib/datasets/__init__.py +++ b/airbyte-lib/airbyte_lib/datasets/__init__.py @@ -1,5 +1,6 @@ from airbyte_lib.datasets._base import DatasetBase -from airbyte_lib.datasets._cached import CachedDataset +from airbyte_lib.datasets._cached import CachedDataset, SQLDataset +from airbyte_lib.datasets._lazy import LazyDataset from airbyte_lib.datasets._map import DatasetMap @@ -7,4 +8,6 @@ "CachedDataset", "DatasetBase", "DatasetMap", + "LazyDataset", + "SQLDataset", ] diff --git a/airbyte-lib/airbyte_lib/datasets/_base.py b/airbyte-lib/airbyte_lib/datasets/_base.py index b42e5258e559..0eb8db4a230d 100644 --- a/airbyte-lib/airbyte_lib/datasets/_base.py +++ b/airbyte-lib/airbyte_lib/datasets/_base.py @@ -5,19 +5,14 @@ from typing import Any, cast from pandas import DataFrame -from typing_extensions import Self -class DatasetBase(ABC, Iterator[Mapping[str, Any]]): +class DatasetBase(ABC): """Base implementation for all datasets.""" - def __iter__(self) -> Self: - """Return the iterator object (usually self).""" - return self - @abstractmethod - def __next__(self) -> Mapping[str, Any]: - """Return the next value from the iterator.""" + def __iter__(self) -> Iterator[Mapping[str, Any]]: + """Return the iterator object (usually self).""" raise NotImplementedError def to_pandas(self) -> DataFrame: diff --git a/airbyte-lib/airbyte_lib/datasets/_cached.py b/airbyte-lib/airbyte_lib/datasets/_cached.py index 37aed0458312..a1c4b3d5195f 100644 --- a/airbyte-lib/airbyte_lib/datasets/_cached.py +++ b/airbyte-lib/airbyte_lib/datasets/_cached.py @@ -1,34 +1,100 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. +from __future__ import annotations from collections.abc import Mapping -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, cast -from typing_extensions import Self +from overrides import overrides +from sqlalchemy import all_, text from airbyte_lib.datasets._base import DatasetBase if TYPE_CHECKING: + from collections.abc import Iterator + from pandas import DataFrame - from sqlalchemy import Table + from sqlalchemy import Selectable, Table + from sqlalchemy.sql import ClauseElement from airbyte_lib.caches import SQLCacheBase -class CachedDataset(DatasetBase): - def __init__(self, cache: "SQLCacheBase", stream: str) -> None: - self._cache = cache - self._stream = stream - self._iterator = iter(self._cache.get_records(self._stream)) +class SQLDataset(DatasetBase): + """A dataset that is loaded incrementally from a SQL query. + + The CachedDataset class is a subclass of this class, which simply passes a SELECT over the full + table as the query statement. + """ + + def __init__( + self, + cache: SQLCacheBase, + stream_name: str, + query_statement: Selectable, + ) -> None: + self._cache: SQLCacheBase = cache + self._stream_name: str = stream_name + self._query_statement: Selectable = query_statement + + def __iter__(self) -> Iterator[Mapping[str, Any]]: + with self._cache.get_sql_connection() as conn: + for row in conn.execute(self._query_statement): + # Access to private member required because SQLAlchemy doesn't expose a public API. + # https://pydoc.dev/sqlalchemy/latest/sqlalchemy.engine.row.RowMapping.html + yield cast(Mapping[str, Any], row._mapping) # noqa: SLF001 + + def __eq__(self, __value: object) -> bool: + if not isinstance(__value, SQLDataset): + return False + + if self._cache is not __value._cache: + return False + + if self._stream_name != __value._stream_name: + return False + + if self._query_statement != __value._query_statement: + return False + + return True + + def to_pandas(self) -> DataFrame: + return self._cache.get_pandas_dataframe(self._stream_name) + + +class CachedDataset(SQLDataset): + """A dataset backed by a SQL table cache. + + Because this dataset includes all records from the underlying table, we also expose the + underlying table as a SQLAlchemy Table object. + """ + + def __init__(self, cache: SQLCacheBase, stream_name: str) -> None: + self._cache: SQLCacheBase = cache + self._stream_name: str = stream_name + self._query_statement: Selectable = self.to_sql_table().select() - def __iter__(self) -> Self: - return self + @overrides + def to_pandas(self) -> DataFrame: + return self._cache.get_pandas_dataframe(self._stream_name) - def __next__(self) -> Mapping[str, Any]: - return next(self._iterator) + def to_sql_table(self) -> Table: + return self._cache.get_sql_table(self._stream_name) - def to_pandas(self) -> "DataFrame": - return self._cache.get_pandas_dataframe(self._stream) + def with_filter(self, *filter_expressions: ClauseElement | str) -> SQLDataset: + """Filter the dataset by a set of column values. - def to_sql_table(self) -> "Table": - return self._cache.get_sql_table(self._stream) + Filters can be specified as either a string or a SQLAlchemy expression. + """ + # Convert all strings to TextClause objects. + filters: list[ClauseElement] = [ + text(expression) if isinstance(expression, str) else expression + for expression in filter_expressions + ] + filtered_select = self._query_statement.where(all_(*filters)) + return SQLDataset( + cache=self._cache, + stream_name=self._stream_name, + query_statement=filtered_select, + ) diff --git a/airbyte-lib/airbyte_lib/datasets/_lazy.py b/airbyte-lib/airbyte_lib/datasets/_lazy.py index e08f844c4078..162e29137a1f 100644 --- a/airbyte-lib/airbyte_lib/datasets/_lazy.py +++ b/airbyte-lib/airbyte_lib/datasets/_lazy.py @@ -10,38 +10,22 @@ if TYPE_CHECKING: - from collections.abc import Callable, Iterator + from collections.abc import Iterator, Mapping -class LazyDataset(DatasetBase): - """A dataset that is loaded incrementally from a source or a SQL query. - TODO: Test and debug this. It is not yet implemented anywhere in the codebase. - For now it servers as a placeholder. - """ +class LazyDataset(DatasetBase): + """A dataset that is loaded incrementally from a source or a SQL query.""" def __init__( self, - iterator: Iterator, - on_open: Callable | None = None, - on_close: Callable | None = None, + iterator: Iterator[Mapping[str, Any]], ) -> None: - self._iterator = iterator - self._on_open = on_open - self._on_close = on_close - raise NotImplementedError("This class is not implemented yet.") + self._iterator: Iterator[Mapping[str, Any]] = iterator @overrides - def __iter__(self) -> Self: - raise NotImplementedError("This class is not implemented yet.") - # Pseudocode: - # if self._on_open is not None: - # self._on_open() - - # yield from self._iterator - - # if self._on_close is not None: - # self._on_close() + def __iter__(self) -> Iterator[Mapping[str, Any]]: + return self._iterator - def __next__(self) -> dict[str, Any]: + def __next__(self) -> Mapping[str, Any]: return next(self._iterator) diff --git a/airbyte-lib/airbyte_lib/results.py b/airbyte-lib/airbyte_lib/results.py index 3261416c130b..25f59a05acf6 100644 --- a/airbyte-lib/airbyte_lib/results.py +++ b/airbyte-lib/airbyte_lib/results.py @@ -1,5 +1,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. +from collections.abc import Iterator, Mapping + from sqlalchemy.engine import Engine from airbyte_lib.caches import SQLCacheBase @@ -12,11 +14,24 @@ def __init__(self, processed_records: int, cache: SQLCacheBase) -> None: self._cache = cache def __getitem__(self, stream: str) -> CachedDataset: + if stream not in self._cache: + raise KeyError(f"Stream {stream} does not exist") + return CachedDataset(self._cache, stream) + def __contains__(self, stream: str) -> bool: + return stream in self._cache + + def __iter__(self) -> Iterator[str]: + return self._cache.__iter__() + def get_sql_engine(self) -> Engine: return self._cache.get_sql_engine() + @property + def streams(self) -> Mapping[str, CachedDataset]: + return self._cache.streams + @property def cache(self) -> SQLCacheBase: return self._cache diff --git a/airbyte-lib/airbyte_lib/source.py b/airbyte-lib/airbyte_lib/source.py index 415284994510..d7d3a806c39f 100644 --- a/airbyte-lib/airbyte_lib/source.py +++ b/airbyte-lib/airbyte_lib/source.py @@ -23,6 +23,7 @@ from airbyte_lib._factories.cache_factories import get_default_cache from airbyte_lib._util import protocol_util # Internal utility functions +from airbyte_lib.datasets._lazy import LazyDataset from airbyte_lib.results import ReadResult from airbyte_lib.telemetry import ( CacheTelemetryInfo, @@ -174,7 +175,7 @@ def configured_catalog(self) -> ConfiguredAirbyteCatalog: ], ) - def get_records(self, stream: str) -> Iterator[dict[str, Any]]: + def get_records(self, stream: str) -> LazyDataset: """Read a stream from the connector. This involves the following steps: @@ -198,15 +199,15 @@ def get_records(self, stream: str) -> Iterator[dict[str, Any]]: ], ) if len(configured_catalog.streams) == 0: - raise ValueError( + raise KeyError( f"Stream {stream} is not available for connector {self.name}, " f"choose from {self.get_available_streams()}", ) - iterator: Iterable[dict[str, Any]] = protocol_util.airbyte_messages_to_record_dicts( + iterator: Iterator[dict[str, Any]] = protocol_util.airbyte_messages_to_record_dicts( self._read_with_catalog(streaming_cache_info, configured_catalog), ) - yield from iterator # TODO: Refactor to use LazyDataset here + return LazyDataset(iterator) def check(self) -> None: """Call check on the connector. diff --git a/airbyte-lib/tests/conftest.py b/airbyte-lib/tests/conftest.py index 8defc74b8ba2..5ceb2d2e2cb8 100644 --- a/airbyte-lib/tests/conftest.py +++ b/airbyte-lib/tests/conftest.py @@ -11,7 +11,7 @@ from airbyte_lib.caches.snowflake import SnowflakeCacheConfig import docker -import psycopg +import psycopg2 as psycopg import pytest from google.cloud import secretmanager From d774c3baf1804a9bbb9a4072f98ef20edbc5b059 Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Mon, 22 Jan 2024 13:17:39 -0800 Subject: [PATCH 04/15] updated docs --- airbyte-lib/docs/generated/airbyte_lib.html | 327 ++++++++++++++---- .../docs/generated/airbyte_lib/caches.html | 6 +- .../{factories.html => cloud.html} | 0 .../docs/generated/airbyte_lib/datasets.html | 114 +++++- 4 files changed, 379 insertions(+), 68 deletions(-) rename airbyte-lib/docs/generated/airbyte_lib/{factories.html => cloud.html} (100%) diff --git a/airbyte-lib/docs/generated/airbyte_lib.html b/airbyte-lib/docs/generated/airbyte_lib.html index 240492002ff8..195ce128874a 100644 --- a/airbyte-lib/docs/generated/airbyte_lib.html +++ b/airbyte-lib/docs/generated/airbyte_lib.html @@ -1,5 +1,260 @@
+
+
+ + class + CachedDataset(airbyte_lib.datasets._cached.SQLDataset): + + +
+ + +

A dataset backed by a SQL table cache.

+ +

Because this dataset includes all records from the underlying table, we also expose the +underlying table as a SQLAlchemy Table object.

+
+ + +
+
+ + CachedDataset(cache: 'SQLCacheBase', stream_name: str) + + +
+ + + + +
+
+
+
@overrides
+ + def + to_pandas(self) -> pandas.core.frame.DataFrame: + + +
+ + +

Return a pandas DataFrame representation of the dataset.

+
+ + +
+
+
+ + def + to_sql_table(self) -> 'Table': + + +
+ + + + +
+
+
+ + def + with_filter( self, *filter_expressions: 'ClauseElement | str') -> airbyte_lib.datasets._cached.SQLDataset: + + +
+ + +

Filter the dataset by a set of column values.

+ +

Filters can be specified as either a string or a SQLAlchemy expression.

+
+ + +
+
+
+
+ + class + DuckDBCache(airbyte_lib.caches.duckdb.DuckDBCacheBase): + + +
+ + +

A DuckDB implementation of the cache.

+ +

Parquet is used for local file storage before bulk loading. +Unlike the Snowflake implementation, we can't use the COPY command to load data +so we insert as values instead.

+
+ + +
+
+ file_writer_class = +<class 'airbyte_lib._file_writers.parquet.ParquetWriter'> + + +
+ + + + +
+
+
Inherited Members
+
+
airbyte_lib.caches.base.SQLCacheBase
+
SQLCacheBase
+
type_converter_class
+
use_singleton_connection
+
config
+
file_writer
+
type_converter
+
get_sql_alchemy_url
+
database_name
+
get_sql_engine
+
get_sql_connection
+
get_sql_table_name
+
get_sql_table
+
streams
+
get_records
+
get_pandas_dataframe
+ +
+
airbyte_lib.caches.duckdb.DuckDBCacheBase
+
config_class
+
supports_merge_insert
+
get_telemetry_info
+ +
+
airbyte_lib._processors.RecordProcessor
+
skip_finalize_step
+
source_catalog
+
register_source
+
process_stdin
+
process_input_stream
+
process_airbyte_messages
+ +
+
+
+
+
+
+ + class + DuckDBCacheConfig(airbyte_lib.caches.base.SQLCacheConfigBase, airbyte_lib._file_writers.parquet.ParquetWriterConfig): + + +
+ + +

Configuration for the DuckDB cache.

+ +

Also inherits config from the ParquetWriter, which is responsible for writing files to disk.

+
+ + +
+
+ db_path: pathlib.Path | str + + +
+ + +

Normally db_path is a Path object.

+ +

There are some cases, such as when connecting to MotherDuck, where it could be a string that +is not also a path, such as "md:" to connect the user's default MotherDuck DB.

+
+ + +
+
+
+ schema_name: str + + +
+ + +

The name of the schema to write to. Defaults to "main".

+
+ + +
+
+
+
@overrides
+ + def + get_sql_alchemy_url(self) -> str: + + +
+ + +

Return the SQLAlchemy URL to use.

+
+ + +
+
+
+ + def + get_database_name(self) -> str: + + +
+ + +

Return the name of the database.

+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
Config
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
airbyte_lib.caches.base.SQLCacheConfigBase
+
dedupe_mode
+
table_prefix
+
table_suffix
+ +
+
airbyte_lib._file_writers.base.FileWriterConfigBase
+
cache_dir
+
cleanup
+ +
+
+
+
@@ -34,7 +289,7 @@
def - get_default_cache() -> airbyte_lib.caches.duckdb.DuckDBCache: + get_default_cache() -> DuckDBCache:
@@ -52,7 +307,7 @@
def - new_local_cache( cache_name: str | None = None, cache_dir: str | pathlib.Path | None = None, *, cleanup: bool = True) -> airbyte_lib.caches.duckdb.DuckDBCache: + new_local_cache( cache_name: str | None = None, cache_dir: str | pathlib.Path | None = None, *, cleanup: bool = True) -> DuckDBCache:
@@ -70,61 +325,6 @@
-
-
-
- - class - CachedDataset(abc.ABC, collections.abc.Iterator[collections.abc.Mapping[str, typing.Any]]): - - -
- - -

Base implementation for all datasets.

-
- - -
-
- - CachedDataset(cache: airbyte_lib.caches.base.SQLCacheBase, stream: str) - - -
- - - - -
-
-
- - def - to_pandas(self) -> pandas.core.frame.DataFrame: - - -
- - -

Return a pandas DataFrame representation of the dataset.

-
- - -
-
-
- - def - to_sql_table(self) -> sqlalchemy.sql.schema.Table: - - -
- - - - -
@@ -173,6 +373,17 @@ +
+
+
+ streams: collections.abc.Mapping[str, CachedDataset] + + +
+ + + +
@@ -316,7 +527,7 @@
def - get_records(self, stream: str) -> collections.abc.Iterator[dict[str, typing.Any]]: + get_records(self, stream: str) -> airbyte_lib.datasets._lazy.LazyDataset:
diff --git a/airbyte-lib/docs/generated/airbyte_lib/caches.html b/airbyte-lib/docs/generated/airbyte_lib/caches.html index dbb675f6d5a2..e1d9e5f75fcc 100644 --- a/airbyte-lib/docs/generated/airbyte_lib/caches.html +++ b/airbyte-lib/docs/generated/airbyte_lib/caches.html @@ -622,7 +622,7 @@
Inherited Members
- streams: dict[str, airbyte_lib.datasets._base.DatasetBase] + streams: dict[str, airbyte_lib.datasets._cached.CachedDataset]
@@ -637,15 +637,13 @@
Inherited Members
def - get_records( self, stream_name: str) -> collections.abc.Iterator[collections.abc.Mapping[str, typing.Any]]: + get_records(self, stream_name: str) -> airbyte_lib.datasets._cached.CachedDataset:

Uses SQLAlchemy to select all rows from the table.

- -

TODO: Refactor to return a LazyDataset here.

diff --git a/airbyte-lib/docs/generated/airbyte_lib/factories.html b/airbyte-lib/docs/generated/airbyte_lib/cloud.html similarity index 100% rename from airbyte-lib/docs/generated/airbyte_lib/factories.html rename to airbyte-lib/docs/generated/airbyte_lib/cloud.html diff --git a/airbyte-lib/docs/generated/airbyte_lib/datasets.html b/airbyte-lib/docs/generated/airbyte_lib/datasets.html index acd3bb5928b6..82f34f033ee4 100644 --- a/airbyte-lib/docs/generated/airbyte_lib/datasets.html +++ b/airbyte-lib/docs/generated/airbyte_lib/datasets.html @@ -4,20 +4,23 @@
class - CachedDataset(abc.ABC, collections.abc.Iterator[collections.abc.Mapping[str, typing.Any]]): + CachedDataset(airbyte_lib.datasets.SQLDataset):
-

Base implementation for all datasets.

+

A dataset backed by a SQL table cache.

+ +

Because this dataset includes all records from the underlying table, we also expose the +underlying table as a SQLAlchemy Table object.

- CachedDataset(cache: airbyte_lib.caches.base.SQLCacheBase, stream: str) + CachedDataset(cache: 'SQLCacheBase', stream_name: str)
@@ -28,7 +31,8 @@
- +
@overrides
+ def to_pandas(self) -> pandas.core.frame.DataFrame: @@ -45,7 +49,7 @@
def - to_sql_table(self) -> sqlalchemy.sql.schema.Table: + to_sql_table(self) -> 'Table':
@@ -53,13 +57,30 @@ +
+
+
+ + def + with_filter( self, *filter_expressions: 'ClauseElement | str') -> SQLDataset: + + +
+ + +

Filter the dataset by a set of column values.

+ +

Filters can be specified as either a string or a SQLAlchemy expression.

+
+ +
class - DatasetBase(abc.ABC, collections.abc.Iterator[collections.abc.Mapping[str, typing.Any]]): + DatasetBase(abc.ABC):
@@ -112,6 +133,87 @@
Inherited Members
+
+
+ + class + LazyDataset(airbyte_lib.datasets.DatasetBase): + + +
+ + +

A dataset that is loaded incrementally from a source or a SQL query.

+
+ + +
+
+ + LazyDataset( iterator: collections.abc.Iterator[collections.abc.Mapping[str, typing.Any]]) + + +
+ + + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ + class + SQLDataset(airbyte_lib.datasets.DatasetBase): + + +
+ + +

A dataset that is loaded incrementally from a SQL query.

+ +

The CachedDataset class is a subclass of this class, which simply passes a SELECT over the full +table as the query statement.

+
+ + +
+
+ + SQLDataset( cache: 'SQLCacheBase', stream_name: str, query_statement: 'Selectable') + + +
+ + + + +
+
+
+ + def + to_pandas(self) -> pandas.core.frame.DataFrame: + + +
+ + +

Return a pandas DataFrame representation of the dataset.

+
+ + +
+
From dd03c49a810fd3c8eb3e3a0f8150d71a8a6f14af Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Mon, 22 Jan 2024 13:19:14 -0800 Subject: [PATCH 05/15] rename module from _cached to _sql --- airbyte-lib/airbyte_lib/caches/base.py | 2 +- airbyte-lib/airbyte_lib/datasets/__init__.py | 2 +- airbyte-lib/airbyte_lib/datasets/{_cached.py => _sql.py} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename airbyte-lib/airbyte_lib/datasets/{_cached.py => _sql.py} (100%) diff --git a/airbyte-lib/airbyte_lib/caches/base.py b/airbyte-lib/airbyte_lib/caches/base.py index 9fe4d8789d8c..53415da76248 100644 --- a/airbyte-lib/airbyte_lib/caches/base.py +++ b/airbyte-lib/airbyte_lib/caches/base.py @@ -21,7 +21,7 @@ from airbyte_lib._file_writers.base import FileWriterBase, FileWriterBatchHandle from airbyte_lib._processors import BatchHandle, RecordProcessor from airbyte_lib.config import CacheConfigBase -from airbyte_lib.datasets._cached import CachedDataset +from airbyte_lib.datasets._sql import CachedDataset from airbyte_lib.types import SQLTypeConverter diff --git a/airbyte-lib/airbyte_lib/datasets/__init__.py b/airbyte-lib/airbyte_lib/datasets/__init__.py index daed8d0ad639..d1c8d3a6d0ea 100644 --- a/airbyte-lib/airbyte_lib/datasets/__init__.py +++ b/airbyte-lib/airbyte_lib/datasets/__init__.py @@ -1,7 +1,7 @@ from airbyte_lib.datasets._base import DatasetBase -from airbyte_lib.datasets._cached import CachedDataset, SQLDataset from airbyte_lib.datasets._lazy import LazyDataset from airbyte_lib.datasets._map import DatasetMap +from airbyte_lib.datasets._sql import CachedDataset, SQLDataset __all__ = [ diff --git a/airbyte-lib/airbyte_lib/datasets/_cached.py b/airbyte-lib/airbyte_lib/datasets/_sql.py similarity index 100% rename from airbyte-lib/airbyte_lib/datasets/_cached.py rename to airbyte-lib/airbyte_lib/datasets/_sql.py From 0b75ab668beb5671f690b388830056fd87b9d969 Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Mon, 22 Jan 2024 13:19:31 -0800 Subject: [PATCH 06/15] update docs --- airbyte-lib/docs/generated/airbyte_lib.html | 4 ++-- airbyte-lib/docs/generated/airbyte_lib/caches.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/airbyte-lib/docs/generated/airbyte_lib.html b/airbyte-lib/docs/generated/airbyte_lib.html index 195ce128874a..b8f3f534ec44 100644 --- a/airbyte-lib/docs/generated/airbyte_lib.html +++ b/airbyte-lib/docs/generated/airbyte_lib.html @@ -4,7 +4,7 @@
class - CachedDataset(airbyte_lib.datasets._cached.SQLDataset): + CachedDataset(airbyte_lib.datasets._sql.SQLDataset):
@@ -62,7 +62,7 @@
def - with_filter( self, *filter_expressions: 'ClauseElement | str') -> airbyte_lib.datasets._cached.SQLDataset: + with_filter( self, *filter_expressions: 'ClauseElement | str') -> airbyte_lib.datasets._sql.SQLDataset:
diff --git a/airbyte-lib/docs/generated/airbyte_lib/caches.html b/airbyte-lib/docs/generated/airbyte_lib/caches.html index e1d9e5f75fcc..60dd860c4aa8 100644 --- a/airbyte-lib/docs/generated/airbyte_lib/caches.html +++ b/airbyte-lib/docs/generated/airbyte_lib/caches.html @@ -622,7 +622,7 @@
Inherited Members
- streams: dict[str, airbyte_lib.datasets._cached.CachedDataset] + streams: dict[str, airbyte_lib.datasets._sql.CachedDataset]
@@ -637,7 +637,7 @@
Inherited Members
def - get_records(self, stream_name: str) -> airbyte_lib.datasets._cached.CachedDataset: + get_records(self, stream_name: str) -> airbyte_lib.datasets._sql.CachedDataset:
From 746a7ad53f921eb574f9daf9f79d5e56c4c639ba Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Mon, 22 Jan 2024 13:20:35 -0800 Subject: [PATCH 07/15] lint fixes --- airbyte-lib/airbyte_lib/datasets/_lazy.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/airbyte-lib/airbyte_lib/datasets/_lazy.py b/airbyte-lib/airbyte_lib/datasets/_lazy.py index 162e29137a1f..a8bb8173711d 100644 --- a/airbyte-lib/airbyte_lib/datasets/_lazy.py +++ b/airbyte-lib/airbyte_lib/datasets/_lazy.py @@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, Any from overrides import overrides -from typing_extensions import Self from airbyte_lib.datasets import DatasetBase @@ -13,7 +12,6 @@ from collections.abc import Iterator, Mapping - class LazyDataset(DatasetBase): """A dataset that is loaded incrementally from a source or a SQL query.""" From 210c0bf1e0aebb4bfd6d6edebc12bc292ef4f8b1 Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Mon, 22 Jan 2024 14:01:22 -0800 Subject: [PATCH 08/15] add tests for sql filtering (now passing) --- airbyte-lib/airbyte_lib/datasets/_sql.py | 71 +++++++++++-------- airbyte-lib/docs/generated/airbyte_lib.html | 23 +++--- .../docs/generated/airbyte_lib/datasets.html | 51 +++++++++---- .../integration_tests/test_integration.py | 46 +++++++----- 4 files changed, 115 insertions(+), 76 deletions(-) diff --git a/airbyte-lib/airbyte_lib/datasets/_sql.py b/airbyte-lib/airbyte_lib/datasets/_sql.py index a1c4b3d5195f..0472ddbf4e50 100644 --- a/airbyte-lib/airbyte_lib/datasets/_sql.py +++ b/airbyte-lib/airbyte_lib/datasets/_sql.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Any, cast from overrides import overrides -from sqlalchemy import all_, text +from sqlalchemy import and_, text from airbyte_lib.datasets._base import DatasetBase @@ -37,6 +37,10 @@ def __init__( self._stream_name: str = stream_name self._query_statement: Selectable = query_statement + @property + def stream_name(self) -> str: + return self._stream_name + def __iter__(self) -> Iterator[Mapping[str, Any]]: with self._cache.get_sql_connection() as conn: for row in conn.execute(self._query_statement): @@ -44,24 +48,26 @@ def __iter__(self) -> Iterator[Mapping[str, Any]]: # https://pydoc.dev/sqlalchemy/latest/sqlalchemy.engine.row.RowMapping.html yield cast(Mapping[str, Any], row._mapping) # noqa: SLF001 - def __eq__(self, __value: object) -> bool: - if not isinstance(__value, SQLDataset): - return False - - if self._cache is not __value._cache: - return False - - if self._stream_name != __value._stream_name: - return False - - if self._query_statement != __value._query_statement: - return False - - return True - def to_pandas(self) -> DataFrame: return self._cache.get_pandas_dataframe(self._stream_name) + def with_filter(self, *filter_expressions: ClauseElement | str) -> SQLDataset: + """Filter the dataset by a set of column values. + + Filters can be specified as either a string or a SQLAlchemy expression. + """ + # Convert all strings to TextClause objects. + filters: list[ClauseElement] = [ + text(expression) if isinstance(expression, str) else expression + for expression in filter_expressions + ] + filtered_select = self._query_statement.where(and_(*filters)) + return SQLDataset( + cache=self._cache, + stream_name=self._stream_name, + query_statement=filtered_select, + ) + class CachedDataset(SQLDataset): """A dataset backed by a SQL table cache. @@ -82,19 +88,24 @@ def to_pandas(self) -> DataFrame: def to_sql_table(self) -> Table: return self._cache.get_sql_table(self._stream_name) - def with_filter(self, *filter_expressions: ClauseElement | str) -> SQLDataset: - """Filter the dataset by a set of column values. + def __eq__(self, value: object) -> bool: + """Return True if the value is a CachedDataset with the same cache and stream name. - Filters can be specified as either a string or a SQLAlchemy expression. + In the case of CachedDataset objects, we can simply compare the cache and stream name. + + Note that this equality check is only supported on CachedDataset objects and not for + the base SQLDataset implementation. This is because of the complexity and computational + cost of comparing two arbitrary SQL queries that could be bound to different variables, + as well as the chance that two queries can be syntactically equivalent without being + text-wise equivalent. """ - # Convert all strings to TextClause objects. - filters: list[ClauseElement] = [ - text(expression) if isinstance(expression, str) else expression - for expression in filter_expressions - ] - filtered_select = self._query_statement.where(all_(*filters)) - return SQLDataset( - cache=self._cache, - stream_name=self._stream_name, - query_statement=filtered_select, - ) + if not isinstance(value, SQLDataset): + return False + + if self._cache is not value._cache: + return False + + if self._stream_name != value._stream_name: + return False + + return True diff --git a/airbyte-lib/docs/generated/airbyte_lib.html b/airbyte-lib/docs/generated/airbyte_lib.html index b8f3f534ec44..5d1a7539b0fb 100644 --- a/airbyte-lib/docs/generated/airbyte_lib.html +++ b/airbyte-lib/docs/generated/airbyte_lib.html @@ -58,22 +58,15 @@
-
-
- - def - with_filter( self, *filter_expressions: 'ClauseElement | str') -> airbyte_lib.datasets._sql.SQLDataset: - - -
- - -

Filter the dataset by a set of column values.

- -

Filters can be specified as either a string or a SQLAlchemy expression.

-
- +
+
Inherited Members
+
+
airbyte_lib.datasets._sql.SQLDataset
+
stream_name
+
with_filter
+
+
diff --git a/airbyte-lib/docs/generated/airbyte_lib/datasets.html b/airbyte-lib/docs/generated/airbyte_lib/datasets.html index 82f34f033ee4..4d675640f905 100644 --- a/airbyte-lib/docs/generated/airbyte_lib/datasets.html +++ b/airbyte-lib/docs/generated/airbyte_lib/datasets.html @@ -58,22 +58,15 @@
-
-
- - def - with_filter( self, *filter_expressions: 'ClauseElement | str') -> SQLDataset: - - -
- - -

Filter the dataset by a set of column values.

- -

Filters can be specified as either a string or a SQLAlchemy expression.

-
- +
+
Inherited Members
+
+ +
@@ -197,6 +190,17 @@
Inherited Members
+
+
+
+ stream_name: str + + +
+ + + +
@@ -212,6 +216,23 @@
Inherited Members
+
+
+
+ + def + with_filter( self, *filter_expressions: 'ClauseElement | str') -> SQLDataset: + + +
+ + +

Filter the dataset by a set of column values.

+ +

Filters can be specified as either a string or a SQLAlchemy expression.

+
+ +
diff --git a/airbyte-lib/tests/integration_tests/test_integration.py b/airbyte-lib/tests/integration_tests/test_integration.py index 378d26e68888..ba8efff5bc51 100644 --- a/airbyte-lib/tests/integration_tests/test_integration.py +++ b/airbyte-lib/tests/integration_tests/test_integration.py @@ -1,12 +1,15 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. +from collections.abc import Mapping import os import shutil -import subprocess +from typing import Any from unittest.mock import Mock, call, patch import tempfile from pathlib import Path +from sqlalchemy import column, text + import airbyte_lib as ab from airbyte_lib.caches import SnowflakeCacheConfig, SnowflakeSQLCache import pandas as pd @@ -16,7 +19,7 @@ from airbyte_lib.registry import _update_cache from airbyte_lib.version import get_version from airbyte_lib.results import ReadResult -from airbyte_lib.datasets import CachedDataset, DatasetBase, LazyDataset, LazySQLDataset +from airbyte_lib.datasets import CachedDataset, LazyDataset, SQLDataset import airbyte_lib as ab from airbyte_lib.results import ReadResult @@ -229,30 +232,42 @@ def test_cached_dataset(): result.cache.streams[not_a_stream_name] -def test_lazy_dataset_from_source(): +def test_cached_dataset_filter(): source = ab.get_connector("source-test", config={"apiKey": "test"}) + result: ReadResult = source.read(ab.new_local_cache()) stream_name = "stream1" - not_a_stream_name = "not_a_stream" - lazy_dataset_a = source.get_records(stream_name) - lazy_dataset_b = source.get_records(stream_name) + # Check the many ways to add a filter: + cached_dataset: CachedDataset = result[stream_name] + filtered_dataset_a: SQLDataset = cached_dataset.with_filter("column2 == 1") + filtered_dataset_b: SQLDataset = cached_dataset.with_filter(text("column2 == 1")) + filtered_dataset_c: SQLDataset = cached_dataset.with_filter(column("column2") == 1) - assert isinstance(lazy_dataset_a, LazyDataset) + assert isinstance(cached_dataset, CachedDataset) + all_records = list(cached_dataset) + assert len(all_records) == 2 - # Check that we can iterate over the stream + for filtered_dataset, case in [ + (filtered_dataset_a, "a"), + (filtered_dataset_b, "b"), + (filtered_dataset_c, "c"), + ]: + assert isinstance(filtered_dataset, SQLDataset) - list_from_iter_a = list(lazy_dataset_a) - list_from_iter_b = [row for row in lazy_dataset_b] + # Check that we can iterate over each stream - assert list_from_iter_a == list_from_iter_b + filtered_records: list[Mapping[str, Any]] = [row for row in filtered_dataset] - # Make sure that we get a key error if we try to access a stream that doesn't exist - with pytest.raises(KeyError): - source.get_records(not_a_stream_name) + # Check that the filter worked + assert len(filtered_records) == 1, f"Case '{case}' had incorrect number of records." + # Assert the stream name still matches + assert filtered_dataset.stream_name == stream_name, \ + f"Case '{case}' had incorrect stream name." -def test_lazy_sql_dataset_from_cache(): + +def test_lazy_dataset_from_source(): source = ab.get_connector("source-test", config={"apiKey": "test"}) stream_name = "stream1" @@ -260,7 +275,6 @@ def test_lazy_sql_dataset_from_cache(): lazy_dataset_a = source.get_records(stream_name) lazy_dataset_b = source.get_records(stream_name) - lazy_dataset_c = source.get_records(stream_name) assert isinstance(lazy_dataset_a, LazyDataset) From cc7f10f41c131823accc6199c2690c60c02c21fa Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Mon, 22 Jan 2024 14:22:49 -0800 Subject: [PATCH 09/15] add cache iterator checks --- .../tests/integration_tests/test_integration.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/airbyte-lib/tests/integration_tests/test_integration.py b/airbyte-lib/tests/integration_tests/test_integration.py index ba8efff5bc51..bd7c2eded841 100644 --- a/airbyte-lib/tests/integration_tests/test_integration.py +++ b/airbyte-lib/tests/integration_tests/test_integration.py @@ -202,21 +202,25 @@ def test_cached_dataset(): # Check that the stream appears in mapping-like attributes assert stream_name in result.cache._streams_with_data assert stream_name in result + assert stream_name in result.cache assert stream_name in result.cache.streams assert stream_name in result.streams stream_get_a: CachedDataset = result[stream_name] stream_get_b: CachedDataset = result.streams[stream_name] - stream_get_c: CachedDataset = result.cache.streams[stream_name] + stream_get_c: CachedDataset = result.cache[stream_name] + stream_get_d: CachedDataset = result.cache.streams[stream_name] # Check that each get method is syntactically equivalent assert isinstance(stream_get_a, CachedDataset) assert isinstance(stream_get_b, CachedDataset) assert isinstance(stream_get_c, CachedDataset) + assert isinstance(stream_get_d, CachedDataset) assert stream_get_a == stream_get_b assert stream_get_b == stream_get_c + assert stream_get_c == stream_get_d # Check that we can iterate over the stream @@ -228,6 +232,8 @@ def test_cached_dataset(): result[not_a_stream_name] with pytest.raises(KeyError): result.streams[not_a_stream_name] + with pytest.raises(KeyError): + result.cache[not_a_stream_name] with pytest.raises(KeyError): result.cache.streams[not_a_stream_name] @@ -266,6 +272,12 @@ def test_cached_dataset_filter(): assert filtered_dataset.stream_name == stream_name, \ f"Case '{case}' had incorrect stream name." + # Check that chaining filters works + chained_dataset = filtered_dataset.with_filter("column1 == 'value1'") + chained_records = [row for row in chained_dataset] + assert len(chained_records) == 1, \ + f"Case '{case}' had incorrect number of records after chaining filters." + def test_lazy_dataset_from_source(): source = ab.get_connector("source-test", config={"apiKey": "test"}) From fa9730b2041b204bfdca734b7127c2fa6d1735cb Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Mon, 22 Jan 2024 14:23:01 -0800 Subject: [PATCH 10/15] update docstrings --- airbyte-lib/airbyte_lib/datasets/_base.py | 7 +++++-- airbyte-lib/airbyte_lib/datasets/_sql.py | 8 ++++++++ airbyte-lib/docs/generated/airbyte_lib.html | 2 ++ .../docs/generated/airbyte_lib/datasets.html | 16 ++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/airbyte-lib/airbyte_lib/datasets/_base.py b/airbyte-lib/airbyte_lib/datasets/_base.py index 0eb8db4a230d..b9f888c2fe81 100644 --- a/airbyte-lib/airbyte_lib/datasets/_base.py +++ b/airbyte-lib/airbyte_lib/datasets/_base.py @@ -12,11 +12,14 @@ class DatasetBase(ABC): @abstractmethod def __iter__(self) -> Iterator[Mapping[str, Any]]: - """Return the iterator object (usually self).""" + """Return the iterator of records.""" raise NotImplementedError def to_pandas(self) -> DataFrame: - """Return a pandas DataFrame representation of the dataset.""" + """Return a pandas DataFrame representation of the dataset. + + The base implementation simply passes the record iterator to Panda's DataFrame constructor. + """ # Technically, we return an iterator of Mapping objects. However, pandas # expects an iterator of dict objects. This cast is safe because we know # duck typing is correct for this use case. diff --git a/airbyte-lib/airbyte_lib/datasets/_sql.py b/airbyte-lib/airbyte_lib/datasets/_sql.py index 0472ddbf4e50..c6195dc6e280 100644 --- a/airbyte-lib/airbyte_lib/datasets/_sql.py +++ b/airbyte-lib/airbyte_lib/datasets/_sql.py @@ -55,6 +55,14 @@ def with_filter(self, *filter_expressions: ClauseElement | str) -> SQLDataset: """Filter the dataset by a set of column values. Filters can be specified as either a string or a SQLAlchemy expression. + + Filters are lazily applied to the dataset, so they can be chained together. For example: + + dataset.with_filter("id > 5").with_filter("id < 10") + + is equivalent to: + + dataset.with_filter("id > 5", "id < 10") """ # Convert all strings to TextClause objects. filters: list[ClauseElement] = [ diff --git a/airbyte-lib/docs/generated/airbyte_lib.html b/airbyte-lib/docs/generated/airbyte_lib.html index 5d1a7539b0fb..9af3ac6bfa56 100644 --- a/airbyte-lib/docs/generated/airbyte_lib.html +++ b/airbyte-lib/docs/generated/airbyte_lib.html @@ -41,6 +41,8 @@

Return a pandas DataFrame representation of the dataset.

+ +

The base implementation simply passes the record iterator to Panda's DataFrame constructor.

diff --git a/airbyte-lib/docs/generated/airbyte_lib/datasets.html b/airbyte-lib/docs/generated/airbyte_lib/datasets.html index 4d675640f905..76089344eca0 100644 --- a/airbyte-lib/docs/generated/airbyte_lib/datasets.html +++ b/airbyte-lib/docs/generated/airbyte_lib/datasets.html @@ -41,6 +41,8 @@

Return a pandas DataFrame representation of the dataset.

+ +

The base implementation simply passes the record iterator to Panda's DataFrame constructor.

@@ -94,6 +96,8 @@
Inherited Members

Return a pandas DataFrame representation of the dataset.

+ +

The base implementation simply passes the record iterator to Panda's DataFrame constructor.

@@ -213,6 +217,8 @@
Inherited Members

Return a pandas DataFrame representation of the dataset.

+ +

The base implementation simply passes the record iterator to Panda's DataFrame constructor.

@@ -230,6 +236,16 @@
Inherited Members

Filter the dataset by a set of column values.

Filters can be specified as either a string or a SQLAlchemy expression.

+ +

Filters are lazily applied to the dataset, so they can be chained together. For example:

+ +
    dataset.with_filter("id > 5").with_filter("id < 10")
+
+ +

is equivalent to:

+ +
    dataset.with_filter("id > 5", "id < 10")
+
From ede6e7402b69c39c7203ae3dc3aa4288fcb60b47 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Tue, 23 Jan 2024 18:20:02 +0100 Subject: [PATCH 11/15] actually run tests --- .github/workflows/airbyte-ci-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/airbyte-ci-tests.yml b/.github/workflows/airbyte-ci-tests.yml index c718bd7a993e..2fd268dc3382 100644 --- a/.github/workflows/airbyte-ci-tests.yml +++ b/.github/workflows/airbyte-ci-tests.yml @@ -79,7 +79,7 @@ jobs: - 'airbyte-ci/connectors/metadata_service/orchestrator/**' - '!**/*.md' airbyte_lib: - - 'airbyte_lib/**' + - 'airbyte-lib/**' - '!**/*.md' - name: Run airbyte-ci/connectors/connector_ops tests From 3498dfaf951d7b57cb4780b467b681a5a16c6602 Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Tue, 23 Jan 2024 09:31:15 -0800 Subject: [PATCH 12/15] fix docs --- airbyte-lib/docs/generated/airbyte_lib/cloud.html | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 airbyte-lib/docs/generated/airbyte_lib/cloud.html diff --git a/airbyte-lib/docs/generated/airbyte_lib/cloud.html b/airbyte-lib/docs/generated/airbyte_lib/cloud.html deleted file mode 100644 index c0d27ca14eaa..000000000000 --- a/airbyte-lib/docs/generated/airbyte_lib/cloud.html +++ /dev/null @@ -1,7 +0,0 @@ - -
-
- - - - \ No newline at end of file From cefff31e1e12ef4b15039001e23e711c31db91ae Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Tue, 23 Jan 2024 11:25:52 -0800 Subject: [PATCH 13/15] refactor look-alike `Source.streams` to `Source._selected_stream_names` --- airbyte-lib/airbyte_lib/source.py | 62 +++++++++++++-------- airbyte-lib/docs/generated/airbyte_lib.html | 31 ++++++----- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/airbyte-lib/airbyte_lib/source.py b/airbyte-lib/airbyte_lib/source.py index d7d3a806c39f..f4430698ef1f 100644 --- a/airbyte-lib/airbyte_lib/source.py +++ b/airbyte-lib/airbyte_lib/source.py @@ -71,18 +71,26 @@ def __init__( self._processed_records = 0 self.executor = executor self.name = name - self.streams: list[str] | None = None self._processed_records = 0 self._config_dict: dict[str, Any] | None = None self._last_log_messages: list[str] = [] self._discovered_catalog: AirbyteCatalog | None = None self._spec: ConnectorSpecification | None = None + self._selected_stream_names: list[str] | None = None if config is not None: self.set_config(config) if streams is not None: self.set_streams(streams) def set_streams(self, streams: list[str]) -> None: + """Optionally, select the stream names that should be read from the connector. + + Currently, if this is not set, all streams will be read. + + TODO: In the future if not set, the default behavior may exclude streams which the connector + would default to disabled. (For instance, streams that require a premium license + are sometimes disabled by default within the connector.) + """ available_streams = self.get_available_streams() for stream in streams: if stream not in available_streams: @@ -90,7 +98,7 @@ def set_streams(self, streams: list[str]) -> None: f"Stream {stream} is not available for connector {self.name}. " f"Choose from: {available_streams}", ) - self.streams = streams + self._selected_stream_names = streams def set_config(self, config: dict[str, Any]) -> None: self._validate_config(config) @@ -128,7 +136,7 @@ def _validate_config(self, config: dict[str, Any]) -> None: def get_available_streams(self) -> list[str]: """Get the available streams from the spec.""" - return [s.name for s in self._discover().streams] + return [s.name for s in self.discovered_catalog.streams] def _get_spec(self, *, force_refresh: bool = False) -> ConnectorSpecification: """Call spec on the connector. @@ -152,26 +160,41 @@ def _get_spec(self, *, force_refresh: bool = False) -> ConnectorSpecification: ) @property - def raw_catalog(self) -> AirbyteCatalog: - """Get the raw catalog for the given streams.""" - return self._discover() + def discovered_catalog(self) -> AirbyteCatalog: + """Get the raw catalog for the given streams. - @property - def configured_catalog(self) -> ConfiguredAirbyteCatalog: - """Get the configured catalog for the given streams.""" + If the catalog is not yet known, we call discover to get it. + """ if self._discovered_catalog is None: self._discovered_catalog = self._discover() + return self._discovered_catalog + + @property + def configured_catalog(self) -> ConfiguredAirbyteCatalog: + """Get the configured catalog for the given streams. + + If the raw catalog is not yet known, we call discover to get it. + + If no specific streams are selected, we return a catalog that syncs all available streams. + + TODO: We should consider disabling by default the streams that the connector would + disable by default. (For instance, streams that require a premium license are sometimes + disabled by default within the connector.) + """ + _ = self.discovered_catalog # Ensure discovered catalog is cached before we start + streams_filter: list[str] | None = self._selected_stream_names return ConfiguredAirbyteCatalog( streams=[ + # TODO: Set sync modes and primary key to a sensible adaptive default ConfiguredAirbyteStream( stream=s, sync_mode=SyncMode.full_refresh, destination_sync_mode=DestinationSyncMode.overwrite, primary_key=None, ) - for s in self._discovered_catalog.streams - if self.streams is None or s.name in self.streams + for s in self.discovered_catalog.streams + if streams_filter is None or s.name in streams_filter ], ) @@ -254,19 +277,10 @@ def _read(self, cache_info: CacheTelemetryInfo) -> Iterable[AirbyteRecordMessage * execute the connector with read --config --catalog * Listen to the messages and return the AirbyteRecordMessages that come along. """ - catalog = self._discover() - configured_catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=s, - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - for s in catalog.streams - if self.streams is None or s.name in self.streams - ], - ) - yield from self._read_with_catalog(cache_info, configured_catalog) + # Ensure discovered and configured catalog properties are cached before we start reading + _ = self.discovered_catalog + _ = self.configured_catalog + yield from self._read_with_catalog(cache_info, catalog=self.configured_catalog) def _read_with_catalog( self, diff --git a/airbyte-lib/docs/generated/airbyte_lib.html b/airbyte-lib/docs/generated/airbyte_lib.html index 9af3ac6bfa56..4e83755cbeca 100644 --- a/airbyte-lib/docs/generated/airbyte_lib.html +++ b/airbyte-lib/docs/generated/airbyte_lib.html @@ -439,17 +439,6 @@
Inherited Members
- -
-
- streams: list[str] | None - - -
- - - -
@@ -461,7 +450,15 @@
Inherited Members
- +

Optionally, select the stream names that should be read from the connector.

+ +

Currently, if this is not set, all streams will be read.

+ +

TODO: In the future if not set, the default behavior may exclude streams which the connector +would default to disabled. (For instance, streams that require a premium license +are sometimes disabled by default within the connector.)

+
+
@@ -492,13 +489,13 @@
Inherited Members
-
+
- raw_catalog: airbyte_protocol.models.airbyte_protocol.AirbyteCatalog + discovered_catalog: airbyte_protocol.models.airbyte_protocol.AirbyteCatalog
- +

Get the raw catalog for the given streams.

@@ -514,6 +511,10 @@
Inherited Members

Get the configured catalog for the given streams.

+ +

TODO: We should consider disabling by default the streams that the connector would +disable by default. (For instance, streams that require a premium license are sometimes +disabled by default within the connector.)

From 63912cdc63e3c61c6ef029829c66210811d7f554 Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Tue, 23 Jan 2024 11:26:18 -0800 Subject: [PATCH 14/15] update docs --- airbyte-lib/docs/generated/airbyte_lib.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/airbyte-lib/docs/generated/airbyte_lib.html b/airbyte-lib/docs/generated/airbyte_lib.html index 4e83755cbeca..91c67884b510 100644 --- a/airbyte-lib/docs/generated/airbyte_lib.html +++ b/airbyte-lib/docs/generated/airbyte_lib.html @@ -498,6 +498,8 @@
Inherited Members

Get the raw catalog for the given streams.

+ +

If the catalog is not yet known, we call discover to get it.

@@ -512,6 +514,10 @@
Inherited Members

Get the configured catalog for the given streams.

+

If the raw catalog is not yet known, we call discover to get it.

+ +

If no specific streams are selected, we return a catalog that syncs all available streams.

+

TODO: We should consider disabling by default the streams that the connector would disable by default. (For instance, streams that require a premium license are sometimes disabled by default within the connector.)

From 8cab3ea5b5990dee2b3aca377b587d38feaf4ac0 Mon Sep 17 00:00:00 2001 From: Aaron Steers Date: Tue, 23 Jan 2024 11:26:35 -0800 Subject: [PATCH 15/15] add tests --- .../integration_tests/test_integration.py | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/airbyte-lib/tests/integration_tests/test_integration.py b/airbyte-lib/tests/integration_tests/test_integration.py index bd7c2eded841..503539ae8380 100644 --- a/airbyte-lib/tests/integration_tests/test_integration.py +++ b/airbyte-lib/tests/integration_tests/test_integration.py @@ -192,7 +192,9 @@ def test_sync_with_merge_to_duckdb(expected_test_stream_data: dict[str, list[dic ) -def test_cached_dataset(): +def test_cached_dataset( + expected_test_stream_data: dict[str, list[dict[str, str | int]]], +) -> None: source = ab.get_connector("source-test", config={"apiKey": "test"}) result: ReadResult = source.read(ab.new_local_cache()) @@ -237,6 +239,22 @@ def test_cached_dataset(): with pytest.raises(KeyError): result.cache.streams[not_a_stream_name] + # Make sure we can use "result.streams.items()" + for stream_name, cached_dataset in result.streams.items(): + assert isinstance(cached_dataset, CachedDataset) + assert isinstance(stream_name, str) + + list_data = list(cached_dataset) + assert list_data == expected_test_stream_data[stream_name] + + # Make sure we can use "result.cache.streams.items()" + for stream_name, cached_dataset in result.cache.streams.items(): + assert isinstance(cached_dataset, CachedDataset) + assert isinstance(stream_name, str) + + list_data = list(cached_dataset) + assert list_data == expected_test_stream_data[stream_name] + def test_cached_dataset_filter(): source = ab.get_connector("source-test", config={"apiKey": "test"}) @@ -279,7 +297,9 @@ def test_cached_dataset_filter(): f"Case '{case}' had incorrect number of records after chaining filters." -def test_lazy_dataset_from_source(): +def test_lazy_dataset_from_source( + expected_test_stream_data: dict[str, list[dict[str, str | int]]], +) -> None: source = ab.get_connector("source-test", config={"apiKey": "test"}) stream_name = "stream1" @@ -301,6 +321,16 @@ def test_lazy_dataset_from_source(): with pytest.raises(KeyError): source.get_records(not_a_stream_name) + # Make sure we can iterate on all available streams + for stream_name in source.get_available_streams(): + assert isinstance(stream_name, str) + + lazy_dataset: LazyDataset = source.get_records(stream_name) + assert isinstance(lazy_dataset, LazyDataset) + + list_data = list(lazy_dataset) + assert list_data == expected_test_stream_data[stream_name] + @pytest.mark.parametrize( "method_call",