From eb53410c1c41f65a7e6064f946f93d3ac5bef639 Mon Sep 17 00:00:00 2001 From: FHU-yezi Date: Thu, 31 Oct 2024 16:58:36 +0800 Subject: [PATCH 1/7] =?UTF-8?q?chore:=20=E5=8D=87=E7=BA=A7=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements-dev.txt | 16 ++-- requirements.txt | 14 ++-- utils/log.py | 2 +- uv.lock | 196 ++++++++++++++++++++----------------------- 4 files changed, 106 insertions(+), 122 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 51a20e9..4054208 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,11 +1,11 @@ aiosqlite==0.20.0 alembic==1.13.3 annotated-types==0.7.0 -anyio==4.6.2.post1 +anyio==4.6.0 apprise==1.9.0 asgi-lifespan==2.1.0 -async-timeout==4.0.3 ; python_full_version < '3.11' -asyncpg==0.30.0 +async-timeout==4.0.3 ; python_full_version < '3.12' +asyncpg==0.29.0 attrs==24.2.0 cachetools==5.5.0 certifi==2024.8.30 @@ -61,7 +61,7 @@ packaging==24.1 pathspec==0.12.1 pendulum==2.1.2 ; python_full_version < '3.12' pendulum==3.0.0 ; python_full_version >= '3.12' -prefect==2.20.10 +prefect==2.20.11 psycopg==3.2.3 psycopg-binary==3.2.3 ; implementation_name != 'pypy' pyasn1==0.6.1 @@ -71,9 +71,9 @@ pydantic==2.9.2 pydantic-core==2.23.4 pygments==2.18.0 pymongo==4.9.2 -pyright==1.1.386 +pyright==1.1.387 python-dateutil==2.9.0.post0 -python-multipart==0.0.12 +python-multipart==0.0.17 python-slugify==8.0.4 pytz==2024.2 pytzdata==2020.1 ; python_full_version < '3.12' @@ -94,8 +94,8 @@ ruff==0.7.1 shellingham==1.5.4 six==1.16.0 sniffio==1.3.1 -sqlalchemy==2.0.36 -sshared==0.16.0 +sqlalchemy==2.0.35 +sshared==0.17.0 text-unidecode==1.3 time-machine==2.16.0 ; python_full_version >= '3.12' and implementation_name != 'pypy' toml==0.10.2 diff --git a/requirements.txt b/requirements.txt index 50e3347..5d5eb21 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,11 @@ aiosqlite==0.20.0 alembic==1.13.3 annotated-types==0.7.0 -anyio==4.6.2.post1 +anyio==4.6.0 apprise==1.9.0 asgi-lifespan==2.1.0 -async-timeout==4.0.3 ; python_full_version < '3.11' -asyncpg==0.30.0 +async-timeout==4.0.3 ; python_full_version < '3.12' +asyncpg==0.29.0 attrs==24.2.0 cachetools==5.5.0 certifi==2024.8.30 @@ -60,7 +60,7 @@ packaging==24.1 pathspec==0.12.1 pendulum==2.1.2 ; python_full_version < '3.12' pendulum==3.0.0 ; python_full_version >= '3.12' -prefect==2.20.10 +prefect==2.20.11 psycopg==3.2.3 psycopg-binary==3.2.3 ; implementation_name != 'pypy' pyasn1==0.6.1 @@ -71,7 +71,7 @@ pydantic-core==2.23.4 pygments==2.18.0 pymongo==4.9.2 python-dateutil==2.9.0.post0 -python-multipart==0.0.12 +python-multipart==0.0.17 python-slugify==8.0.4 pytz==2024.2 pytzdata==2020.1 ; python_full_version < '3.12' @@ -91,8 +91,8 @@ ruamel-yaml-clib==0.2.12 ; python_full_version < '3.13' and platform_python_impl shellingham==1.5.4 six==1.16.0 sniffio==1.3.1 -sqlalchemy==2.0.36 -sshared==0.16.0 +sqlalchemy==2.0.35 +sshared==0.17.0 text-unidecode==1.3 time-machine==2.16.0 ; python_full_version >= '3.12' and implementation_name != 'pypy' toml==0.10.2 diff --git a/utils/log.py b/utils/log.py index b0b2821..ba2094b 100644 --- a/utils/log.py +++ b/utils/log.py @@ -7,7 +7,7 @@ logger = Logger( display_level=CONFIG.logging.display_level, save_level=CONFIG.logging.save_level, - connection_string=CONFIG.postgres.logging_connection_string, + connection_string=CONFIG.logging.connection_string, table=CONFIG.logging.table, ) diff --git a/uv.lock b/uv.lock index 24f474e..6612d38 100644 --- a/uv.lock +++ b/uv.lock @@ -43,7 +43,7 @@ wheels = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, @@ -51,9 +51,9 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 } +sdist = { url = "https://files.pythonhosted.org/packages/78/49/f3f17ec11c4a91fe79275c426658e509b07547f874b14c1a526d86a83fc8/anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb", size = 170983 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 }, + { url = "https://files.pythonhosted.org/packages/9e/ef/7a4f225581a0d7886ea28359179cb861d7fbcdefad29663fc1167b86f69f/anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a", size = 89631 }, ] [[package]] @@ -96,53 +96,45 @@ wheels = [ [[package]] name = "asyncpg" -version = "0.30.0" +version = "0.29.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "async-timeout", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/07/1650a8c30e3a5c625478fa8aafd89a8dd7d85999bf7169b16f54973ebf2c/asyncpg-0.30.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfb4dd5ae0699bad2b233672c8fc5ccbd9ad24b89afded02341786887e37927e", size = 673143 }, - { url = "https://files.pythonhosted.org/packages/a0/9a/568ff9b590d0954553c56806766914c149609b828c426c5118d4869111d3/asyncpg-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc1f62c792752a49f88b7e6f774c26077091b44caceb1983509edc18a2222ec0", size = 645035 }, - { url = "https://files.pythonhosted.org/packages/de/11/6f2fa6c902f341ca10403743701ea952bca896fc5b07cc1f4705d2bb0593/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3152fef2e265c9c24eec4ee3d22b4f4d2703d30614b0b6753e9ed4115c8a146f", size = 2912384 }, - { url = "https://files.pythonhosted.org/packages/83/83/44bd393919c504ffe4a82d0aed8ea0e55eb1571a1dea6a4922b723f0a03b/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7255812ac85099a0e1ffb81b10dc477b9973345793776b128a23e60148dd1af", size = 2947526 }, - { url = "https://files.pythonhosted.org/packages/08/85/e23dd3a2b55536eb0ded80c457b0693352262dc70426ef4d4a6fc994fa51/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:578445f09f45d1ad7abddbff2a3c7f7c291738fdae0abffbeb737d3fc3ab8b75", size = 2895390 }, - { url = "https://files.pythonhosted.org/packages/9b/26/fa96c8f4877d47dc6c1864fef5500b446522365da3d3d0ee89a5cce71a3f/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c42f6bb65a277ce4d93f3fba46b91a265631c8df7250592dd4f11f8b0152150f", size = 3015630 }, - { url = "https://files.pythonhosted.org/packages/34/00/814514eb9287614188a5179a8b6e588a3611ca47d41937af0f3a844b1b4b/asyncpg-0.30.0-cp310-cp310-win32.whl", hash = "sha256:aa403147d3e07a267ada2ae34dfc9324e67ccc4cdca35261c8c22792ba2b10cf", size = 568760 }, - { url = "https://files.pythonhosted.org/packages/f0/28/869a7a279400f8b06dd237266fdd7220bc5f7c975348fea5d1e6909588e9/asyncpg-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb622c94db4e13137c4c7f98834185049cc50ee01d8f657ef898b6407c7b9c50", size = 625764 }, - { url = "https://files.pythonhosted.org/packages/4c/0e/f5d708add0d0b97446c402db7e8dd4c4183c13edaabe8a8500b411e7b495/asyncpg-0.30.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5e0511ad3dec5f6b4f7a9e063591d407eee66b88c14e2ea636f187da1dcfff6a", size = 674506 }, - { url = "https://files.pythonhosted.org/packages/6a/a0/67ec9a75cb24a1d99f97b8437c8d56da40e6f6bd23b04e2f4ea5d5ad82ac/asyncpg-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:915aeb9f79316b43c3207363af12d0e6fd10776641a7de8a01212afd95bdf0ed", size = 645922 }, - { url = "https://files.pythonhosted.org/packages/5c/d9/a7584f24174bd86ff1053b14bb841f9e714380c672f61c906eb01d8ec433/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c198a00cce9506fcd0bf219a799f38ac7a237745e1d27f0e1f66d3707c84a5a", size = 3079565 }, - { url = "https://files.pythonhosted.org/packages/a0/d7/a4c0f9660e333114bdb04d1a9ac70db690dd4ae003f34f691139a5cbdae3/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3326e6d7381799e9735ca2ec9fd7be4d5fef5dcbc3cb555d8a463d8460607956", size = 3109962 }, - { url = "https://files.pythonhosted.org/packages/3c/21/199fd16b5a981b1575923cbb5d9cf916fdc936b377e0423099f209e7e73d/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51da377487e249e35bd0859661f6ee2b81db11ad1f4fc036194bc9cb2ead5056", size = 3064791 }, - { url = "https://files.pythonhosted.org/packages/77/52/0004809b3427534a0c9139c08c87b515f1c77a8376a50ae29f001e53962f/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc6d84136f9c4d24d358f3b02be4b6ba358abd09f80737d1ac7c444f36108454", size = 3188696 }, - { url = "https://files.pythonhosted.org/packages/52/cb/fbad941cd466117be58b774a3f1cc9ecc659af625f028b163b1e646a55fe/asyncpg-0.30.0-cp311-cp311-win32.whl", hash = "sha256:574156480df14f64c2d76450a3f3aaaf26105869cad3865041156b38459e935d", size = 567358 }, - { url = "https://files.pythonhosted.org/packages/3c/0a/0a32307cf166d50e1ad120d9b81a33a948a1a5463ebfa5a96cc5606c0863/asyncpg-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:3356637f0bd830407b5597317b3cb3571387ae52ddc3bca6233682be88bbbc1f", size = 629375 }, - { url = "https://files.pythonhosted.org/packages/4b/64/9d3e887bb7b01535fdbc45fbd5f0a8447539833b97ee69ecdbb7a79d0cb4/asyncpg-0.30.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e", size = 673162 }, - { url = "https://files.pythonhosted.org/packages/6e/eb/8b236663f06984f212a087b3e849731f917ab80f84450e943900e8ca4052/asyncpg-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a", size = 637025 }, - { url = "https://files.pythonhosted.org/packages/cc/57/2dc240bb263d58786cfaa60920779af6e8d32da63ab9ffc09f8312bd7a14/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3", size = 3496243 }, - { url = "https://files.pythonhosted.org/packages/f4/40/0ae9d061d278b10713ea9021ef6b703ec44698fe32178715a501ac696c6b/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737", size = 3575059 }, - { url = "https://files.pythonhosted.org/packages/c3/75/d6b895a35a2c6506952247640178e5f768eeb28b2e20299b6a6f1d743ba0/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a", size = 3473596 }, - { url = "https://files.pythonhosted.org/packages/c8/e7/3693392d3e168ab0aebb2d361431375bd22ffc7b4a586a0fc060d519fae7/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af", size = 3641632 }, - { url = "https://files.pythonhosted.org/packages/32/ea/15670cea95745bba3f0352341db55f506a820b21c619ee66b7d12ea7867d/asyncpg-0.30.0-cp312-cp312-win32.whl", hash = "sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e", size = 560186 }, - { url = "https://files.pythonhosted.org/packages/7e/6b/fe1fad5cee79ca5f5c27aed7bd95baee529c1bf8a387435c8ba4fe53d5c1/asyncpg-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305", size = 621064 }, - { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373 }, - { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745 }, - { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103 }, - { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471 }, - { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253 }, - { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720 }, - { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404 }, - { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623 }, - { url = "https://files.pythonhosted.org/packages/b4/82/d94f3ed6921136a0ef40a825740eda19437ccdad7d92d924302dca1d5c9e/asyncpg-0.30.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6f4e83f067b35ab5e6371f8a4c93296e0439857b4569850b178a01385e82e9ad", size = 673026 }, - { url = "https://files.pythonhosted.org/packages/4e/db/7db8b73c5d86ec9a21807f405e0698f8f637a8a3ca14b7b6fd4259b66bcf/asyncpg-0.30.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5df69d55add4efcd25ea2a3b02025b669a285b767bfbf06e356d68dbce4234ff", size = 644732 }, - { url = "https://files.pythonhosted.org/packages/eb/a0/1f1910659d08050cb3e8f7d82b32983974798d7fd4ddf7620b8e2023d4ac/asyncpg-0.30.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3479a0d9a852c7c84e822c073622baca862d1217b10a02dd57ee4a7a081f708", size = 2911761 }, - { url = "https://files.pythonhosted.org/packages/4d/53/5aa0d92488ded50bab2b6626430ed9743b0b7e2d864a2b435af1ccbf219a/asyncpg-0.30.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26683d3b9a62836fad771a18ecf4659a30f348a561279d6227dab96182f46144", size = 2946595 }, - { url = "https://files.pythonhosted.org/packages/c5/cd/d6d548d8ee721f4e0f7fbbe509bbac140d556c2e45814d945540c96cf7d4/asyncpg-0.30.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1b982daf2441a0ed314bd10817f1606f1c28b1136abd9e4f11335358c2c631cb", size = 2890135 }, - { url = "https://files.pythonhosted.org/packages/46/f0/28df398b685dabee20235e24880e1f6486d84ae7e6b0d11bdebc17740e7a/asyncpg-0.30.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1c06a3a50d014b303e5f6fc1e5f95eb28d2cee89cf58384b700da621e5d5e547", size = 3011889 }, - { url = "https://files.pythonhosted.org/packages/c8/07/8c7ffe6fe8bccff9b12fcb6410b1b2fa74b917fd8b837806a40217d5228b/asyncpg-0.30.0-cp39-cp39-win32.whl", hash = "sha256:1b11a555a198b08f5c4baa8f8231c74a366d190755aa4f99aacec5970afe929a", size = 569406 }, - { url = "https://files.pythonhosted.org/packages/05/51/f59e4df6d9b8937530d4b9fdee1598b93db40c631fe94ff3ce64207b7a95/asyncpg-0.30.0-cp39-cp39-win_amd64.whl", hash = "sha256:8b684a3c858a83cd876f05958823b68e8d14ec01bb0c0d14a6704c5bf9711773", size = 626581 }, + { name = "async-timeout", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c1/11/7a6000244eaeb6b8ed2238bf33477c486515d6133f2c295913aca3ba4a00/asyncpg-0.29.0.tar.gz", hash = "sha256:d1c49e1f44fffafd9a55e1a9b101590859d881d639ea2922516f5d9c512d354e", size = 820455 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/df/5cc866069c3a248a67d59a3de495afec34b4d36ed74101da4dfa1f456167/asyncpg-0.29.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72fd0ef9f00aeed37179c62282a3d14262dbbafb74ec0ba16e1b1864d8a12169", size = 669258 }, + { url = "https://files.pythonhosted.org/packages/a9/eb/569047f87d6b7ced42352af3771c1b1e6d39584f072e11068e3e3b4bde68/asyncpg-0.29.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52e8f8f9ff6e21f9b39ca9f8e3e33a5fcdceaf5667a8c5c32bee158e313be385", size = 650833 }, + { url = "https://files.pythonhosted.org/packages/b8/38/d399e70fcfc880a70ae02551a68cfb1b3663d59850943f6e711ab19d3648/asyncpg-0.29.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9e6823a7012be8b68301342ba33b4740e5a166f6bbda0aee32bc01638491a22", size = 2654513 }, + { url = "https://files.pythonhosted.org/packages/1f/fb/e5b798ff0d6aceda7067dad9dbf1a11016ef7c8d0117d75f031a39f5ed1e/asyncpg-0.29.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:746e80d83ad5d5464cfbf94315eb6744222ab00aa4e522b704322fb182b83610", size = 2677142 }, + { url = "https://files.pythonhosted.org/packages/d5/98/314ccb06cf587656da2c58afb57b4ff3ddd661108db568c16c181af40436/asyncpg-0.29.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ff8e8109cd6a46ff852a5e6bab8b0a047d7ea42fcb7ca5ae6eaae97d8eacf397", size = 3206559 }, + { url = "https://files.pythonhosted.org/packages/7e/ca/aad32992a1d38ff568e11be44d9b45942b48d50d3647f7b421f62fd99ef3/asyncpg-0.29.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:97eb024685b1d7e72b1972863de527c11ff87960837919dac6e34754768098eb", size = 3237148 }, + { url = "https://files.pythonhosted.org/packages/6d/66/0d26bebcb6794bb49cdd0104deba38cb8deed5d86196afb6f6366c03ee4e/asyncpg-0.29.0-cp310-cp310-win32.whl", hash = "sha256:5bbb7f2cafd8d1fa3e65431833de2642f4b2124be61a449fa064e1a08d27e449", size = 503268 }, + { url = "https://files.pythonhosted.org/packages/a6/05/fed8ceefaef48dda4a24572906b2931b4bf5b20d037d2fc6b6f66f284439/asyncpg-0.29.0-cp310-cp310-win_amd64.whl", hash = "sha256:76c3ac6530904838a4b650b2880f8e7af938ee049e769ec2fba7cd66469d7772", size = 553053 }, + { url = "https://files.pythonhosted.org/packages/69/28/3e3c4e243778f0361214b9d6e8bc6aa8e8bf55f35a2d2cb8949a6863caab/asyncpg-0.29.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4900ee08e85af01adb207519bb4e14b1cae8fd21e0ccf80fac6aa60b6da37b4", size = 653061 }, + { url = "https://files.pythonhosted.org/packages/4a/13/f96284d7014dd06db2e78bea15706443d7895548bf74cf34f0c3ee1863fd/asyncpg-0.29.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a65c1dcd820d5aea7c7d82a3fdcb70e096f8f70d1a8bf93eb458e49bfad036ac", size = 638740 }, + { url = "https://files.pythonhosted.org/packages/27/25/d140bd503932f99528edc0a1461648973ad3c1c67f5929d11f3e8b5f81f4/asyncpg-0.29.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b52e46f165585fd6af4863f268566668407c76b2c72d366bb8b522fa66f1870", size = 2788952 }, + { url = "https://files.pythonhosted.org/packages/c4/41/a0bdc18f13bdd5f27e7fc1b5de7e1caae19951967c109bca1a2e99cf3331/asyncpg-0.29.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc600ee8ef3dd38b8d67421359779f8ccec30b463e7aec7ed481c8346decf99f", size = 2809108 }, + { url = "https://files.pythonhosted.org/packages/f2/1f/1737248d7b1b75d19e7f07a98321bc58cb6fc979754c78544cfebff3359b/asyncpg-0.29.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:039a261af4f38f949095e1e780bae84a25ffe3e370175193174eb08d3cecab23", size = 3355924 }, + { url = "https://files.pythonhosted.org/packages/88/b0/6bebd69ed484055d47b78ea34fd9887c35694b63c9a648a7f02759d3bf73/asyncpg-0.29.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6feaf2d8f9138d190e5ec4390c1715c3e87b37715cd69b2c3dfca616134efd2b", size = 3391360 }, + { url = "https://files.pythonhosted.org/packages/5b/89/3ed6e9d235f8aa13aa8ee8dc3a70f754962dbd441bec2dcfdae9f9e0e2e3/asyncpg-0.29.0-cp311-cp311-win32.whl", hash = "sha256:1e186427c88225ef730555f5fdda6c1812daa884064bfe6bc462fd3a71c4b675", size = 496216 }, + { url = "https://files.pythonhosted.org/packages/f2/39/f7e755b5d5aa59d8385c08be58726aceffc1da9360041031554d664c783f/asyncpg-0.29.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfe73ffae35f518cfd6e4e5f5abb2618ceb5ef02a2365ce64f132601000587d3", size = 543321 }, + { url = "https://files.pythonhosted.org/packages/f2/b7/38b7c195f66a5598413c538da499b3f8119ba5764ded6fff620f7eb84c65/asyncpg-0.29.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6011b0dc29886ab424dc042bf9eeb507670a3b40aece3439944006aafe023178", size = 636282 }, + { url = "https://files.pythonhosted.org/packages/eb/0b/d128b57f7e994a6d71253d0a6a8c949fc50c969785010d46b87d8491be24/asyncpg-0.29.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b544ffc66b039d5ec5a7454667f855f7fec08e0dfaf5a5490dfafbb7abbd2cfb", size = 618024 }, + { url = "https://files.pythonhosted.org/packages/49/ac/0396e559e1e7ab23787f790ae96b22affe2d66acebb084d6fc42293d12b8/asyncpg-0.29.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d84156d5fb530b06c493f9e7635aa18f518fa1d1395ef240d211cb563c4e2364", size = 3196465 }, + { url = "https://files.pythonhosted.org/packages/99/38/0bfb00e9b828513bd759174860fd2b1c5e36d0b33985c90ff4ed6f96814c/asyncpg-0.29.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54858bc25b49d1114178d65a88e48ad50cb2b6f3e475caa0f0c092d5f527c106", size = 3275564 }, + { url = "https://files.pythonhosted.org/packages/16/1b/bb42784e9895832bf460ee6643f818bd53e4d6a6308cca5984c581a51845/asyncpg-0.29.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bde17a1861cf10d5afce80a36fca736a86769ab3579532c03e45f83ba8a09c59", size = 3164724 }, + { url = "https://files.pythonhosted.org/packages/d5/d1/7ed5169e30e80573c942f5a6f29b2f87d5b8379bdd9bd916f0ed136c874e/asyncpg-0.29.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:37a2ec1b9ff88d8773d3eb6d3784dc7e3fee7756a5317b67f923172a4748a175", size = 3252834 }, + { url = "https://files.pythonhosted.org/packages/91/2e/20e024608c57c2099531ba492c761b12fdd80891a67e58c92de44d05d57e/asyncpg-0.29.0-cp312-cp312-win32.whl", hash = "sha256:bb1292d9fad43112a85e98ecdc2e051602bce97c199920586be83254d9dafc02", size = 487254 }, + { url = "https://files.pythonhosted.org/packages/71/86/7a18e1a457afb73991e5e5586e2341af09a31c91d8f65cc003f0b4553252/asyncpg-0.29.0-cp312-cp312-win_amd64.whl", hash = "sha256:2245be8ec5047a605e0b454c894e54bf2ec787ac04b1cb7e0d3c67aa1e32f0fe", size = 530253 }, + { url = "https://files.pythonhosted.org/packages/74/49/243b77ff7ac7c11ec771ce0d76df20e7af73ea92c0399bd480ef794ce946/asyncpg-0.29.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5340dd515d7e52f4c11ada32171d87c05570479dc01dc66d03ee3e150fb695da", size = 686978 }, + { url = "https://files.pythonhosted.org/packages/6b/4d/ee74620647766e67fb6fe88554e49874eb74e34903a2b6c32319cb97e271/asyncpg-0.29.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e17b52c6cf83e170d3d865571ba574577ab8e533e7361a2b8ce6157d02c665d3", size = 665009 }, + { url = "https://files.pythonhosted.org/packages/4d/53/0b9e8f09a87cb764fa8e99c3ff3c6286ef7f29a92782e5667a38032e23d1/asyncpg-0.29.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f100d23f273555f4b19b74a96840aa27b85e99ba4b1f18d4ebff0734e78dc090", size = 2754493 }, + { url = "https://files.pythonhosted.org/packages/16/48/e0c950af52a21fe71f0e0ba71830511e78cd455957fe2d25badf89ad12a8/asyncpg-0.29.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48e7c58b516057126b363cec8ca02b804644fd012ef8e6c7e23386b7d5e6ce83", size = 2782828 }, + { url = "https://files.pythonhosted.org/packages/be/a3/d6002935c546829d9d2138d1bc1929a596e489a35c147d7ed68a496c54d3/asyncpg-0.29.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f9ea3f24eb4c49a615573724d88a48bd1b7821c890c2effe04f05382ed9e8810", size = 3291150 }, + { url = "https://files.pythonhosted.org/packages/db/06/e388331eed46eaea42a73d38b8aa8f624a2e6ca426f03d4a423bd97d823f/asyncpg-0.29.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8d36c7f14a22ec9e928f15f92a48207546ffe68bc412f3be718eedccdf10dc5c", size = 3309783 }, + { url = "https://files.pythonhosted.org/packages/dd/29/980c4401aeb7d3ddff24453fae555cc422b84bdb907c8316f7cd07eab924/asyncpg-0.29.0-cp39-cp39-win32.whl", hash = "sha256:797ab8123ebaed304a1fad4d7576d5376c3a006a4100380fb9d517f0b59c1ab2", size = 515864 }, + { url = "https://files.pythonhosted.org/packages/6d/64/89d970c41baeece88b4123e0b53e13ef855596e33aeb060031cd9b720a40/asyncpg-0.29.0-cp39-cp39-win_amd64.whl", hash = "sha256:cce08a178858b426ae1aa8409b5cc171def45d4293626e7aa6510696d46decd8", size = 567186 }, ] [[package]] @@ -724,7 +716,7 @@ dependencies = [ { name = "sshared", extra = ["config", "mongo", "postgres"] }, ] -[package.dev-dependencies] +[package.dependency-groups] dev = [ { name = "pyright" }, { name = "ruff" }, @@ -738,7 +730,7 @@ requires-dist = [ { name = "sshared", extras = ["config", "mongo", "postgres"], specifier = ">=0.16.0" }, ] -[package.metadata.requires-dev] +[package.metadata.dependency-groups] dev = [ { name = "pyright", specifier = ">=1.1.0" }, { name = "ruff", specifier = ">=0.7.0" }, @@ -1193,7 +1185,7 @@ wheels = [ [[package]] name = "prefect" -version = "2.20.10" +version = "2.20.11" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiosqlite" }, @@ -1250,9 +1242,9 @@ dependencies = [ { name = "uvicorn" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c3/b1/c9ecb26869573e722449fc49084a047f18d2ec47701d75ffc319f2337652/prefect-2.20.10.tar.gz", hash = "sha256:76bc7000b8aac3aa21bc9a73deab6492232726c8263ffd80b573c9ac9a8966ea", size = 5721239 } +sdist = { url = "https://files.pythonhosted.org/packages/37/2c/4717e4122eaf929cd2832ec6e02ee20aec2744d764110857198e70aba3d9/prefect-2.20.11.tar.gz", hash = "sha256:823fbdc74837193263cf39d72202cfc8bbedd72beb8da191a2de089df5d89758", size = 5722044 } wheels = [ - { url = "https://files.pythonhosted.org/packages/de/25/f2348fab3f16b28e7dd9093e26e4fc6a1e9d722383240f9eace69259fb5a/prefect-2.20.10-py3-none-any.whl", hash = "sha256:d44d9fe276d218a0904bc728cecd3c46b06d8bb239a3f1a3562fad8248491888", size = 6026438 }, + { url = "https://files.pythonhosted.org/packages/b2/e8/720eba8edff497cc2acfec2123872d23ecec13629880ab955007118f6547/prefect-2.20.11-py3-none-any.whl", hash = "sha256:e5e167aaddc77686af38011638e74c4c5a652b05295bfea78683f963b2faa360", size = 6027502 }, ] [[package]] @@ -1539,15 +1531,15 @@ wheels = [ [[package]] name = "pyright" -version = "1.1.386" +version = "1.1.387" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/92/50/1a57054b5585fa72a93a6244c1b4b5639f8f7a1cc60b2e807cc67da8f0bc/pyright-1.1.386.tar.gz", hash = "sha256:8e9975e34948ba5f8e07792a9c9d2bdceb2c6c0b61742b068d2229ca2bc4a9d9", size = 21949 } +sdist = { url = "https://files.pythonhosted.org/packages/c2/32/e7187478d3105d6d7edc9b754d56472ee06557c25cc404911288fee1796a/pyright-1.1.387.tar.gz", hash = "sha256:577de60224f7fe36505d5b181231e3a395d427b7873be0bbcaa962a29ea93a60", size = 21939 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/68/47fd6b3ffa27c99d7e0c866c618f07784b8806712059049daa492ca7e526/pyright-1.1.386-py3-none-any.whl", hash = "sha256:7071ac495593b2258ccdbbf495f1a5c0e5f27951f6b429bed4e8b296eb5cd21d", size = 18577 }, + { url = "https://files.pythonhosted.org/packages/a0/18/c497df36641b0572f5bd59ae147b08ccaa6b8086397d50e1af97cc2ddcf6/pyright-1.1.387-py3-none-any.whl", hash = "sha256:6a1f495a261a72e12ad17e20d1ae3df4511223c773b19407cfa006229b1b08a5", size = 18577 }, ] [[package]] @@ -1564,11 +1556,11 @@ wheels = [ [[package]] name = "python-multipart" -version = "0.0.12" +version = "0.0.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/16/6e/7ecfe1366b9270f7f475c76fcfa28812493a6a1abd489b2433851a444f4f/python_multipart-0.0.12.tar.gz", hash = "sha256:045e1f98d719c1ce085ed7f7e1ef9d8ccc8c02ba02b5566d5f7521410ced58cb", size = 35713 } +sdist = { url = "https://files.pythonhosted.org/packages/40/22/edea41c2d4a22e666c0c7db7acdcbf7bc8c1c1f7d3b3ca246ec982fec612/python_multipart-0.0.17.tar.gz", hash = "sha256:41330d831cae6e2f22902704ead2826ea038d0419530eadff3ea80175aec5538", size = 36452 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f5/0b/c316262244abea7481f95f1e91d7575f3dfcf6455d56d1ffe9839c582eb1/python_multipart-0.0.12-py3-none-any.whl", hash = "sha256:43dcf96cf65888a9cd3423544dd0d75ac10f7aa0c3c28a175bbcd00c9ce1aebf", size = 23246 }, + { url = "https://files.pythonhosted.org/packages/b4/fb/275137a799169392f1fa88fff2be92f16eee38e982720a8aaadefc4a36b2/python_multipart-0.0.17-py3-none-any.whl", hash = "sha256:15dc4f487e0a9476cc1201261188ee0940165cffc94429b6fc565c4d3045cb5d", size = 24453 }, ] [[package]] @@ -2059,55 +2051,47 @@ wheels = [ [[package]] name = "sqlalchemy" -version = "2.0.36" +version = "2.0.35" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "greenlet", marker = "(python_full_version < '3.13' and platform_machine == 'AMD64') or (python_full_version < '3.13' and platform_machine == 'WIN32') or (python_full_version < '3.13' and platform_machine == 'aarch64') or (python_full_version < '3.13' and platform_machine == 'amd64') or (python_full_version < '3.13' and platform_machine == 'ppc64le') or (python_full_version < '3.13' and platform_machine == 'win32') or (python_full_version < '3.13' and platform_machine == 'x86_64')" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/50/65/9cbc9c4c3287bed2499e05033e207473504dc4df999ce49385fb1f8b058a/sqlalchemy-2.0.36.tar.gz", hash = "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5", size = 9574485 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/72/14ab694b8b3f0e35ef5beb74a8fea2811aa791ba1611c44dc90cdf46af17/SQLAlchemy-2.0.36-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72", size = 2092604 }, - { url = "https://files.pythonhosted.org/packages/1e/59/333fcbca58b79f5b8b61853d6137530198823392151fa8fd9425f367519e/SQLAlchemy-2.0.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908", size = 2083796 }, - { url = "https://files.pythonhosted.org/packages/6c/a0/ec3c188d2b0c1bc742262e76408d44104598d7247c23f5b06bb97ee21bfa/SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08", size = 3066165 }, - { url = "https://files.pythonhosted.org/packages/07/15/68ef91de5b8b7f80fb2d2b3b31ed42180c6227fe0a701aed9d01d34f98ec/SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07", size = 3074428 }, - { url = "https://files.pythonhosted.org/packages/e2/4c/9dfea5e63b87325eef6d9cdaac913459aa6a157a05a05ea6ff20004aee8e/SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5", size = 3030477 }, - { url = "https://files.pythonhosted.org/packages/16/a5/fcfde8e74ea5f683b24add22463bfc21e431d4a5531c8a5b55bc6fbea164/SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44", size = 3055942 }, - { url = "https://files.pythonhosted.org/packages/3c/ee/c22c415a771d791ae99146d72ffdb20e43625acd24835ea7fc157436d59f/SQLAlchemy-2.0.36-cp310-cp310-win32.whl", hash = "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa", size = 2064960 }, - { url = "https://files.pythonhosted.org/packages/aa/af/ad9c25cadc79bd851bdb9d82b68af9bdb91ff05f56d0da2f8a654825974f/SQLAlchemy-2.0.36-cp310-cp310-win_amd64.whl", hash = "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5", size = 2089078 }, - { url = "https://files.pythonhosted.org/packages/00/4e/5a67963fd7cbc1beb8bd2152e907419f4c940ef04600b10151a751fe9e06/SQLAlchemy-2.0.36-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fd3a55deef00f689ce931d4d1b23fa9f04c880a48ee97af488fd215cf24e2a6c", size = 2093782 }, - { url = "https://files.pythonhosted.org/packages/b3/24/30e33b6389ebb5a17df2a4243b091bc709fb3dfc9a48c8d72f8e037c943d/SQLAlchemy-2.0.36-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f5e9cd989b45b73bd359f693b935364f7e1f79486e29015813c338450aa5a71", size = 2084180 }, - { url = "https://files.pythonhosted.org/packages/10/1e/70e9ed2143a27065246be40f78637ad5160ea0f5fd32f8cab819a31ff54d/SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ddd9db6e59c44875211bc4c7953a9f6638b937b0a88ae6d09eb46cced54eff", size = 3202469 }, - { url = "https://files.pythonhosted.org/packages/b4/5f/95e0ed74093ac3c0db6acfa944d4d8ac6284ef5e1136b878a327ea1f975a/SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2519f3a5d0517fc159afab1015e54bb81b4406c278749779be57a569d8d1bb0d", size = 3202464 }, - { url = "https://files.pythonhosted.org/packages/91/95/2cf9b85a6bc2ee660e40594dffe04e777e7b8617fd0c6d77a0f782ea96c9/SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59b1ee96617135f6e1d6f275bbe988f419c5178016f3d41d3c0abb0c819f75bb", size = 3139508 }, - { url = "https://files.pythonhosted.org/packages/92/ea/f0c01bc646456e4345c0fb5a3ddef457326285c2dc60435b0eb96b61bf31/SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:39769a115f730d683b0eb7b694db9789267bcd027326cccc3125e862eb03bfd8", size = 3159837 }, - { url = "https://files.pythonhosted.org/packages/a6/93/c8edbf153ee38fe529773240877bf1332ed95328aceef6254288f446994e/SQLAlchemy-2.0.36-cp311-cp311-win32.whl", hash = "sha256:66bffbad8d6271bb1cc2f9a4ea4f86f80fe5e2e3e501a5ae2a3dc6a76e604e6f", size = 2064529 }, - { url = "https://files.pythonhosted.org/packages/b1/03/d12b7c1d36fd80150c1d52e121614cf9377dac99e5497af8d8f5b2a8db64/SQLAlchemy-2.0.36-cp311-cp311-win_amd64.whl", hash = "sha256:23623166bfefe1487d81b698c423f8678e80df8b54614c2bf4b4cfcd7c711959", size = 2089874 }, - { url = "https://files.pythonhosted.org/packages/b8/bf/005dc47f0e57556e14512d5542f3f183b94fde46e15ff1588ec58ca89555/SQLAlchemy-2.0.36-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7b64e6ec3f02c35647be6b4851008b26cff592a95ecb13b6788a54ef80bbdd4", size = 2092378 }, - { url = "https://files.pythonhosted.org/packages/94/65/f109d5720779a08e6e324ec89a744f5f92c48bd8005edc814bf72fbb24e5/SQLAlchemy-2.0.36-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:46331b00096a6db1fdc052d55b101dbbfc99155a548e20a0e4a8e5e4d1362855", size = 2082778 }, - { url = "https://files.pythonhosted.org/packages/60/f6/d9aa8c49c44f9b8c9b9dada1f12fa78df3d4c42aa2de437164b83ee1123c/SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdf3386a801ea5aba17c6410dd1dc8d39cf454ca2565541b5ac42a84e1e28f53", size = 3232191 }, - { url = "https://files.pythonhosted.org/packages/8a/ab/81d4514527c068670cb1d7ab62a81a185df53a7c379bd2a5636e83d09ede/SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9dfa18ff2a67b09b372d5db8743c27966abf0e5344c555d86cc7199f7ad83a", size = 3243044 }, - { url = "https://files.pythonhosted.org/packages/35/b4/f87c014ecf5167dc669199cafdb20a7358ff4b1d49ce3622cc48571f811c/SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:90812a8933df713fdf748b355527e3af257a11e415b613dd794512461eb8a686", size = 3178511 }, - { url = "https://files.pythonhosted.org/packages/ea/09/badfc9293bc3ccba6ede05e5f2b44a760aa47d84da1fc5a326e963e3d4d9/SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1bc330d9d29c7f06f003ab10e1eaced295e87940405afe1b110f2eb93a233588", size = 3205147 }, - { url = "https://files.pythonhosted.org/packages/c8/60/70e681de02a13c4b27979b7b78da3058c49bacc9858c89ba672e030f03f2/SQLAlchemy-2.0.36-cp312-cp312-win32.whl", hash = "sha256:79d2e78abc26d871875b419e1fd3c0bca31a1cb0043277d0d850014599626c2e", size = 2062709 }, - { url = "https://files.pythonhosted.org/packages/b7/ed/f6cd9395e41bfe47dd253d74d2dfc3cab34980d4e20c8878cb1117306085/SQLAlchemy-2.0.36-cp312-cp312-win_amd64.whl", hash = "sha256:b544ad1935a8541d177cb402948b94e871067656b3a0b9e91dbec136b06a2ff5", size = 2088433 }, - { url = "https://files.pythonhosted.org/packages/78/5c/236398ae3678b3237726819b484f15f5c038a9549da01703a771f05a00d6/SQLAlchemy-2.0.36-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5cc79df7f4bc3d11e4b542596c03826063092611e481fcf1c9dfee3c94355ef", size = 2087651 }, - { url = "https://files.pythonhosted.org/packages/a8/14/55c47420c0d23fb67a35af8be4719199b81c59f3084c28d131a7767b0b0b/SQLAlchemy-2.0.36-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3c01117dd36800f2ecaa238c65365b7b16497adc1522bf84906e5710ee9ba0e8", size = 2078132 }, - { url = "https://files.pythonhosted.org/packages/3d/97/1e843b36abff8c4a7aa2e37f9bea364f90d021754c2de94d792c2d91405b/SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bc633f4ee4b4c46e7adcb3a9b5ec083bf1d9a97c1d3854b92749d935de40b9b", size = 3164559 }, - { url = "https://files.pythonhosted.org/packages/7b/c5/07f18a897b997f6d6b234fab2bf31dccf66d5d16a79fe329aefc95cd7461/SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e46ed38affdfc95d2c958de328d037d87801cfcbea6d421000859e9789e61c2", size = 3177897 }, - { url = "https://files.pythonhosted.org/packages/b3/cd/e16f3cbefd82b5c40b33732da634ec67a5f33b587744c7ab41699789d492/SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b2985c0b06e989c043f1dc09d4fe89e1616aadd35392aea2844f0458a989eacf", size = 3111289 }, - { url = "https://files.pythonhosted.org/packages/15/85/5b8a3b0bc29c9928aa62b5c91fcc8335f57c1de0a6343873b5f372e3672b/SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a121d62ebe7d26fec9155f83f8be5189ef1405f5973ea4874a26fab9f1e262c", size = 3139491 }, - { url = "https://files.pythonhosted.org/packages/a1/95/81babb6089938680dfe2cd3f88cd3fd39cccd1543b7cb603b21ad881bff1/SQLAlchemy-2.0.36-cp313-cp313-win32.whl", hash = "sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436", size = 2060439 }, - { url = "https://files.pythonhosted.org/packages/c1/ce/5f7428df55660d6879d0522adc73a3364970b5ef33ec17fa125c5dbcac1d/SQLAlchemy-2.0.36-cp313-cp313-win_amd64.whl", hash = "sha256:8c78ac40bde930c60e0f78b3cd184c580f89456dd87fc08f9e3ee3ce8765ce88", size = 2084574 }, - { url = "https://files.pythonhosted.org/packages/43/10/c1c865afeb50270677942cda17ed78b55b0a0068e426d22284a625d7341f/SQLAlchemy-2.0.36-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc022184d3e5cacc9579e41805a681187650e170eb2fd70e28b86192a479dcaa", size = 2095474 }, - { url = "https://files.pythonhosted.org/packages/25/cb/78d7663ad1c82ca8b5cbc7532b8e3c9f80a53f1bdaafd8f5314525700a01/SQLAlchemy-2.0.36-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b817d41d692bf286abc181f8af476c4fbef3fd05e798777492618378448ee689", size = 2086708 }, - { url = "https://files.pythonhosted.org/packages/5c/5b/f9b5cf759865b0dd8b20579b3d920ed87b6160fce75e2b7ed697ddbf0008/SQLAlchemy-2.0.36-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4e46a888b54be23d03a89be510f24a7652fe6ff660787b96cd0e57a4ebcb46d", size = 3080607 }, - { url = "https://files.pythonhosted.org/packages/18/f6/afaef83a3fbeff40b9289508b985c5630c0e8303d08106a0117447c680d9/SQLAlchemy-2.0.36-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4ae3005ed83f5967f961fd091f2f8c5329161f69ce8480aa8168b2d7fe37f06", size = 3088410 }, - { url = "https://files.pythonhosted.org/packages/62/60/ec2b8c14b3c15b4a915ae821b455823fbafa6f38c4011b27c0a76f94928a/SQLAlchemy-2.0.36-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763", size = 3047623 }, - { url = "https://files.pythonhosted.org/packages/40/a2/9f748bdaf769eceb780c438b3dd7a37b8b8cbc6573e2a3748b0d5c2e9d80/SQLAlchemy-2.0.36-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3dbb986bad3ed5ceaf090200eba750b5245150bd97d3e67343a3cfed06feecf7", size = 3074096 }, - { url = "https://files.pythonhosted.org/packages/01/f7/290d7193c81d1ff0f751bd9430f3762bee0f53efd0273aba7ba18eb10520/SQLAlchemy-2.0.36-cp39-cp39-win32.whl", hash = "sha256:9fe53b404f24789b5ea9003fc25b9a3988feddebd7e7b369c8fac27ad6f52f28", size = 2067304 }, - { url = "https://files.pythonhosted.org/packages/6f/a0/dc1a808d6ac466b190ca570f7ce52a1761308279eab4a09367ccf2cd6bd7/SQLAlchemy-2.0.36-cp39-cp39-win_amd64.whl", hash = "sha256:af148a33ff0349f53512a049c6406923e4e02bf2f26c5fb285f143faf4f0e46a", size = 2091520 }, - { url = "https://files.pythonhosted.org/packages/b8/49/21633706dd6feb14cd3f7935fc00b60870ea057686035e1a99ae6d9d9d53/SQLAlchemy-2.0.36-py3-none-any.whl", hash = "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e", size = 1883787 }, +sdist = { url = "https://files.pythonhosted.org/packages/36/48/4f190a83525f5cefefa44f6adc9e6386c4de5218d686c27eda92eb1f5424/sqlalchemy-2.0.35.tar.gz", hash = "sha256:e11d7ea4d24f0a262bccf9a7cd6284c976c5369dac21db237cff59586045ab9f", size = 9562798 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/61/19395d0ae78c94f6f80c8adf39a142f3fe56cfb2235d8f2317d6dae1bf0e/SQLAlchemy-2.0.35-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:67219632be22f14750f0d1c70e62f204ba69d28f62fd6432ba05ab295853de9b", size = 2090086 }, + { url = "https://files.pythonhosted.org/packages/e6/82/06b5fcbe5d49043e40cf4e01e3b33c471c8d9292d478420b08538cae8928/SQLAlchemy-2.0.35-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4668bd8faf7e5b71c0319407b608f278f279668f358857dbfd10ef1954ac9f90", size = 2081278 }, + { url = "https://files.pythonhosted.org/packages/68/d1/7fb7ee46949a5fb34005795b1fc06a8fef67587a66da731c14e545f7eb5b/SQLAlchemy-2.0.35-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb8bea573863762bbf45d1e13f87c2d2fd32cee2dbd50d050f83f87429c9e1ea", size = 3063763 }, + { url = "https://files.pythonhosted.org/packages/7e/ff/a1eacd78b31e52a5073e9924fb4722ecc2a72f093ca8181ed81fc61aed2e/SQLAlchemy-2.0.35-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f552023710d4b93d8fb29a91fadf97de89c5926c6bd758897875435f2a939f33", size = 3072032 }, + { url = "https://files.pythonhosted.org/packages/21/ae/ddfecf149a6d16af87408bca7bd108eef7ef23d376cc8464317efb3cea3f/SQLAlchemy-2.0.35-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:016b2e665f778f13d3c438651dd4de244214b527a275e0acf1d44c05bc6026a9", size = 3028092 }, + { url = "https://files.pythonhosted.org/packages/cc/51/3e84d42121662a160bacd311cfacb29c1e6a229d59dd8edb09caa8ab283b/SQLAlchemy-2.0.35-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7befc148de64b6060937231cbff8d01ccf0bfd75aa26383ffdf8d82b12ec04ff", size = 3053543 }, + { url = "https://files.pythonhosted.org/packages/3e/7a/039c78105958da3fc361887f0a82c974cb6fa5bba965c1689ec778be1c01/SQLAlchemy-2.0.35-cp310-cp310-win32.whl", hash = "sha256:22b83aed390e3099584b839b93f80a0f4a95ee7f48270c97c90acd40ee646f0b", size = 2062372 }, + { url = "https://files.pythonhosted.org/packages/a2/50/f31e927d32f9729f69d150ffe47e7cf51e3e0bb2148fc400b3e93a92ca4c/SQLAlchemy-2.0.35-cp310-cp310-win_amd64.whl", hash = "sha256:a29762cd3d116585278ffb2e5b8cc311fb095ea278b96feef28d0b423154858e", size = 2086485 }, + { url = "https://files.pythonhosted.org/packages/c3/46/9215a35bf98c3a2528e987791e6180eb51624d2c7d5cb8e2d96a6450b657/SQLAlchemy-2.0.35-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e21f66748ab725ade40fa7af8ec8b5019c68ab00b929f6643e1b1af461eddb60", size = 2091274 }, + { url = "https://files.pythonhosted.org/packages/1e/69/919673c5101a0c633658d58b11b454b251ca82300941fba801201434755d/SQLAlchemy-2.0.35-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8a6219108a15fc6d24de499d0d515c7235c617b2540d97116b663dade1a54d62", size = 2081672 }, + { url = "https://files.pythonhosted.org/packages/67/ea/a6b0597cbda12796be2302153369dbbe90573fdab3bc4885f8efac499247/SQLAlchemy-2.0.35-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:042622a5306c23b972192283f4e22372da3b8ddf5f7aac1cc5d9c9b222ab3ff6", size = 3200083 }, + { url = "https://files.pythonhosted.org/packages/8c/d6/97bdc8d714fb21762f2092511f380f18cdb2d985d516071fa925bb433a90/SQLAlchemy-2.0.35-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:627dee0c280eea91aed87b20a1f849e9ae2fe719d52cbf847c0e0ea34464b3f7", size = 3200080 }, + { url = "https://files.pythonhosted.org/packages/87/d2/8c2adaf2ade4f6f1b725acd0b0be9210bb6a2df41024729a8eec6a86fe5a/SQLAlchemy-2.0.35-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4fdcd72a789c1c31ed242fd8c1bcd9ea186a98ee8e5408a50e610edfef980d71", size = 3137108 }, + { url = "https://files.pythonhosted.org/packages/7e/ae/ea05d0bfa8f2b25ae34591895147152854fc950f491c4ce362ae06035db8/SQLAlchemy-2.0.35-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:89b64cd8898a3a6f642db4eb7b26d1b28a497d4022eccd7717ca066823e9fb01", size = 3157437 }, + { url = "https://files.pythonhosted.org/packages/fe/5d/8ad6df01398388a766163d27960b3365f1bbd8bb7b05b5cad321a8b69b25/SQLAlchemy-2.0.35-cp311-cp311-win32.whl", hash = "sha256:6a93c5a0dfe8d34951e8a6f499a9479ffb9258123551fa007fc708ae2ac2bc5e", size = 2061935 }, + { url = "https://files.pythonhosted.org/packages/ff/68/8557efc0c32c8e2c147cb6512237448b8ed594a57cd015fda67f8e56bb3f/SQLAlchemy-2.0.35-cp311-cp311-win_amd64.whl", hash = "sha256:c68fe3fcde03920c46697585620135b4ecfdfc1ed23e75cc2c2ae9f8502c10b8", size = 2087281 }, + { url = "https://files.pythonhosted.org/packages/2f/2b/fff87e6db0da31212c98bbc445f83fb608ea92b96bda3f3f10e373bac76c/SQLAlchemy-2.0.35-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eb60b026d8ad0c97917cb81d3662d0b39b8ff1335e3fabb24984c6acd0c900a2", size = 2089790 }, + { url = "https://files.pythonhosted.org/packages/68/92/4bb761bd82764d5827bf6b6095168c40fb5dbbd23670203aef2f96ba6bc6/SQLAlchemy-2.0.35-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6921ee01caf375363be5e9ae70d08ce7ca9d7e0e8983183080211a062d299468", size = 2080266 }, + { url = "https://files.pythonhosted.org/packages/22/46/068a65db6dc253c6f25a7598d99e0a1d60b14f661f9d09ef6c73c718fa4e/SQLAlchemy-2.0.35-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cdf1a0dbe5ced887a9b127da4ffd7354e9c1a3b9bb330dce84df6b70ccb3a8d", size = 3229760 }, + { url = "https://files.pythonhosted.org/packages/6e/36/59830dafe40dda592304debd4cd86e583f63472f3a62c9e2695a5795e786/SQLAlchemy-2.0.35-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93a71c8601e823236ac0e5d087e4f397874a421017b3318fd92c0b14acf2b6db", size = 3240649 }, + { url = "https://files.pythonhosted.org/packages/00/50/844c50c6996f9c7f000c959dd1a7436a6c94e449ee113046a1d19e470089/SQLAlchemy-2.0.35-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e04b622bb8a88f10e439084486f2f6349bf4d50605ac3e445869c7ea5cf0fa8c", size = 3176138 }, + { url = "https://files.pythonhosted.org/packages/df/d2/336b18cac68eecb67de474fc15c85f13be4e615c6f5bae87ea38c6734ce0/SQLAlchemy-2.0.35-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1b56961e2d31389aaadf4906d453859f35302b4eb818d34a26fab72596076bb8", size = 3202753 }, + { url = "https://files.pythonhosted.org/packages/f0/f3/ee1e62fabdc10910b5ef720ae08e59bc785f26652876af3a50b89b97b412/SQLAlchemy-2.0.35-cp312-cp312-win32.whl", hash = "sha256:0f9f3f9a3763b9c4deb8c5d09c4cc52ffe49f9876af41cc1b2ad0138878453cf", size = 2060113 }, + { url = "https://files.pythonhosted.org/packages/60/63/a3cef44a52979169d884f3583d0640e64b3c28122c096474a1d7cfcaf1f3/SQLAlchemy-2.0.35-cp312-cp312-win_amd64.whl", hash = "sha256:25b0f63e7fcc2a6290cb5f7f5b4fc4047843504983a28856ce9b35d8f7de03cc", size = 2085839 }, + { url = "https://files.pythonhosted.org/packages/d1/4c/3a538c077057a449441b3e10a62ff1608eaa6e0910e681b2664ce0bcf961/SQLAlchemy-2.0.35-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ccae5de2a0140d8be6838c331604f91d6fafd0735dbdcee1ac78fc8fbaba76b4", size = 2092966 }, + { url = "https://files.pythonhosted.org/packages/4e/f0/ac290c05f9118cff70e48abd598bcb0dfb725a7ad0aeebaaa0d781d75367/SQLAlchemy-2.0.35-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2a275a806f73e849e1c309ac11108ea1a14cd7058577aba962cd7190e27c9e3c", size = 2084203 }, + { url = "https://files.pythonhosted.org/packages/8f/a7/6ddbcefb0ada3dbc9bc9260de32f9cd85b1eb5ea35c12344472a028a606e/SQLAlchemy-2.0.35-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:732e026240cdd1c1b2e3ac515c7a23820430ed94292ce33806a95869c46bd139", size = 3078233 }, + { url = "https://files.pythonhosted.org/packages/08/7b/6fae14cf33ebc54423f0e9c7de793dd2debe3ffd44b399a4905adb4b1225/SQLAlchemy-2.0.35-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:890da8cd1941fa3dab28c5bac3b9da8502e7e366f895b3b8e500896f12f94d11", size = 3086017 }, + { url = "https://files.pythonhosted.org/packages/d7/0c/fa68271e608bf4a86c131044966a9f63bc7c6f44e93535be70c7562ff19e/SQLAlchemy-2.0.35-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0d8326269dbf944b9201911b0d9f3dc524d64779a07518199a58384c3d37a44", size = 3045236 }, + { url = "https://files.pythonhosted.org/packages/f1/29/65d6441a2875c9e960703fb730c651f0a62505a16e968e6f99f5dd5bb925/SQLAlchemy-2.0.35-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b76d63495b0508ab9fc23f8152bac63205d2a704cd009a2b0722f4c8e0cba8e0", size = 3071708 }, + { url = "https://files.pythonhosted.org/packages/13/cb/c354d16eb4b9af27a8ef16ef476118497f61f99bf21cf177ec85d9a23d3f/SQLAlchemy-2.0.35-cp39-cp39-win32.whl", hash = "sha256:69683e02e8a9de37f17985905a5eca18ad651bf592314b4d3d799029797d0eb3", size = 2064708 }, + { url = "https://files.pythonhosted.org/packages/56/0a/3025867277836c325a0f69d3e43cfd35e72f877f472d4c4791d32c264d13/SQLAlchemy-2.0.35-cp39-cp39-win_amd64.whl", hash = "sha256:aee110e4ef3c528f3abbc3c2018c121e708938adeeff9006428dd7c8555e9b3f", size = 2088933 }, + { url = "https://files.pythonhosted.org/packages/0e/c6/33c706449cdd92b1b6d756b247761e27d32230fd6b2de5f44c4c3e5632b2/SQLAlchemy-2.0.35-py3-none-any.whl", hash = "sha256:2ab3f0336c0387662ce6221ad30ab3a5e6499aab01b9790879b6578fd9b8faa1", size = 1881276 }, ] [package.optional-dependencies] @@ -2117,14 +2101,14 @@ asyncio = [ [[package]] name = "sshared" -version = "0.16.0" +version = "0.17.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "msgspec" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/61/c7/1bfe6cd0d7f9dc72ce3aaa44aedd7edecada9fabbc78ea41e2da344328b1/sshared-0.16.0.tar.gz", hash = "sha256:0e3a41687005c39031cd4fb6965a366cba1c4d50e528e954110294d1cfde0be0", size = 16406 } +sdist = { url = "https://files.pythonhosted.org/packages/b8/6f/ce6920e79bcd10068c9e3340d44521975b2241484744c01ede55ee374514/sshared-0.17.0.tar.gz", hash = "sha256:922603d9fdafe845b3028b59eb712e4e744b593186f0b0b9418dfc711958ecde", size = 16498 } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/b9/c07621cddb457f45f24ca2b38b0e527963e4b46e7abe548f43468e5d23cf/sshared-0.16.0-py3-none-any.whl", hash = "sha256:aee540eb87d2cefbbf9877841da5dc80eed91b6c6060c05d5b2e42d97b2743d2", size = 24447 }, + { url = "https://files.pythonhosted.org/packages/d4/0f/dbb197378f52684fdb72d575de7bc5244e2d5c7c2d993aa63b54bdd173fc/sshared-0.17.0-py3-none-any.whl", hash = "sha256:1b9ca441e01d406c32bf884f3cf9095a09186e8ddcb4de56da94b5d17ad24f21", size = 24588 }, ] [package.optional-dependencies] From 9fe39b6ab492d2f24cb79438878d18f284f195e6 Mon Sep 17 00:00:00 2001 From: FHU-yezi Date: Thu, 31 Oct 2024 16:58:49 +0800 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E7=9A=84=20jpep=20=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.example.toml | 15 +++++++++++++-- utils/config.py | 3 ++- utils/postgres.py | 6 +++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/config.example.toml b/config.example.toml index 3d5de74..b4262c7 100644 --- a/config.example.toml +++ b/config.example.toml @@ -3,17 +3,28 @@ port = 27017 database = "jfetcher" -[postgres] +[jianshu_postgres] host = "localhost" port = 5432 user = "postgres" password = "postgres" database = "jfetcher" +[jpep_postgres] + host = "localhost" + port = 5432 + user = "postgres" + password = "postgres" + database = "jpep" + [logging] + host = "localhost" + port = 5432 + user = "jfetcher" + password = "jfetcher" + table = "jfetcher" display_level = "DEBUG" save_level = "DEBUG" - table = "jfetcher" [notify] enabled = true diff --git a/utils/config.py b/utils/config.py index a03497f..9ea2c84 100644 --- a/utils/config.py +++ b/utils/config.py @@ -4,7 +4,8 @@ class _Config(ConfigBase, frozen=True): mongo: MongoBlock - postgres: PostgresBlock + jianshu_postgres: PostgresBlock + jpep_postgres: PostgresBlock logging: LoggingBlock notify: GotifyBlock diff --git a/utils/postgres.py b/utils/postgres.py index 138d204..6c2f243 100644 --- a/utils/postgres.py +++ b/utils/postgres.py @@ -5,6 +5,10 @@ enhance_json_process() -_jianshu_connection_manager = ConnectionManager(CONFIG.postgres.connection_string) +_jianshu_connection_manager = ConnectionManager( + CONFIG.jianshu_postgres.connection_string +) +_jpep_connection_manager = ConnectionManager(CONFIG.jpep_postgres.connection_string) get_jianshu_conn = _jianshu_connection_manager.get_conn +get_jianshu_conn = _jpep_connection_manager.get_conn From 68fad666f76aa8b1c8154ae98b500326f5df9f1b Mon Sep 17 00:00:00 2001 From: FHU-yezi Date: Fri, 1 Nov 2024 15:09:51 +0800 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=E8=BF=81=E7=A7=BB=E7=AE=80?= =?UTF-8?q?=E4=B9=A6=E7=A7=AF=E5=88=86=E5=85=91=E6=8D=A2=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=B8=8E=E4=BF=A1=E7=94=A8=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jobs/jpep/ftn_trade.py | 25 +++--- main.py | 19 +--- migrate_credit_history.py | 26 ++++++ migrate_jpep_user.py | 30 +++++++ models/__init__.py | 19 ++++ models/jpep/credit_history.py | 25 ------ models/jpep/credit_record.py | 55 ++++++++++++ models/jpep/user.py | 159 +++++++++++++++++++--------------- utils/postgres.py | 2 +- 9 files changed, 234 insertions(+), 126 deletions(-) create mode 100644 migrate_credit_history.py create mode 100644 migrate_jpep_user.py create mode 100644 models/__init__.py delete mode 100644 models/jpep/credit_history.py create mode 100644 models/jpep/credit_record.py diff --git a/jobs/jpep/ftn_trade.py b/jobs/jpep/ftn_trade.py index 8dbd852..5daff8c 100644 --- a/jobs/jpep/ftn_trade.py +++ b/jobs/jpep/ftn_trade.py @@ -4,12 +4,9 @@ from jkit.jpep.ftn_macket import FTNMacket, FTNMacketOrderRecord from prefect import flow -from models.jpep.credit_history import CreditHistoryDocument -from models.jpep.ftn_trade_order import ( - AmountField, - FTNTradeOrderDocument, -) -from models.jpep.user import UserDocument +from models.jpep.credit_record import CreditRecord +from models.jpep.ftn_trade_order import AmountField, FTNTradeOrderDocument +from models.jpep.user import User from utils.log import log_flow_run_start, log_flow_run_success, logger from utils.prefect_helper import ( generate_deployment_config, @@ -38,23 +35,21 @@ async def process_item( type: Literal["buy", "sell"], # noqa: A002 ) -> FTNTradeOrderDocument: if item.publisher_info.id: - await UserDocument.insert_or_update_one( - updated_at=time, + await User.upsert( id=item.publisher_info.id, name=item.publisher_info.name, hashed_name=item.publisher_info.hashed_name, avatar_url=item.publisher_info.avatar_url, ) - latest_credit_value = await CreditHistoryDocument.get_latest_value( - item.publisher_info.id - ) - if not latest_credit_value or latest_credit_value != item.publisher_info.credit: - await CreditHistoryDocument( + latest_credit = await CreditRecord.get_latest_credit(item.publisher_info.id) + # 如果没有记录过这个用户的信用值,或信用值已修改,增加新的记录 + if not latest_credit or latest_credit != item.publisher_info.credit: + await CreditRecord( time=time, user_id=item.publisher_info.id, - value=item.publisher_info.credit, - ).save() + credit=item.publisher_info.credit, + ).create() return FTNTradeOrderDocument( fetch_time=time, diff --git a/main.py b/main.py index ae108a4..4d6178e 100644 --- a/main.py +++ b/main.py @@ -3,27 +3,12 @@ from prefect import serve from jobs import DEPLOYMENTS -from models.jianshu.article_earning_ranking_record import ( - ArticleEarningRankingRecord, -) -from models.jianshu.daily_update_ranking_record import DailyUpdateRankingRecord -from models.jianshu.user import User -from models.jianshu.user_assets_ranking_record import UserAssetsRankingRecord -from models.jpep.credit_history import CreditHistoryDocument -from models.jpep.ftn_trade_order import FTNTradeOrderDocument -from models.jpep.user import UserDocument +from models import init_db from utils.log import logger async def main() -> None: - await CreditHistoryDocument.ensure_indexes() - await FTNTradeOrderDocument.ensure_indexes() - await UserDocument.ensure_indexes() - - await ArticleEarningRankingRecord.init() - await UserAssetsRankingRecord.init() - await DailyUpdateRankingRecord.init() - await User.init() + await init_db() logger.info("初始化数据库完成") logger.info("启动工作流") diff --git a/migrate_credit_history.py b/migrate_credit_history.py new file mode 100644 index 0000000..b6602ef --- /dev/null +++ b/migrate_credit_history.py @@ -0,0 +1,26 @@ +from asyncio import run as asyncio_run + +from sshared.logging import Logger + +from models.jpep.credit_record import CreditRecord +from utils.mongo import JPEP_DB + +OLD_COLLECTION = JPEP_DB.credit_history +logger = Logger() + + +async def main() -> None: + await CreditRecord.init() + + logger.info("开始执行数据迁移") + async for item in OLD_COLLECTION.find().sort({"time": 1, "userId": 1}): + await CreditRecord( + time=item["time"], user_id=item["userId"], credit=item["value"] + ).create() + + logger.debug(f"已迁移 {item['time']} - {item['userId']}") + + logger.info("数据迁移完成") + + +asyncio_run(main()) diff --git a/migrate_jpep_user.py b/migrate_jpep_user.py new file mode 100644 index 0000000..3620f21 --- /dev/null +++ b/migrate_jpep_user.py @@ -0,0 +1,30 @@ +from asyncio import run as asyncio_run + +from sshared.logging import Logger + +from models.jpep.user import User +from utils.mongo import JPEP_DB + +OLD_COLLECTION = JPEP_DB.users +logger = Logger() + + +async def main() -> None: + await User.init() + + logger.info("开始执行数据迁移") + async for item in OLD_COLLECTION.find().sort({"id": 1}): + await User( + id=item["id"], + update_time=item["updatedAt"], + name=item["name"], + hashed_name=item["hashedName"], + avatar_url=item["avatarUrl"], + ).create() + + logger.debug(f"已迁移 {item['id']}") + + logger.info("数据迁移完成") + + +asyncio_run(main()) diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..ce66423 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,19 @@ +from models.jianshu.article_earning_ranking_record import ( + ArticleEarningRankingRecord, +) +from models.jianshu.daily_update_ranking_record import DailyUpdateRankingRecord +from models.jianshu.user import User as JianshuUser +from models.jianshu.user_assets_ranking_record import UserAssetsRankingRecord +from models.jpep.credit_record import CreditRecord +from models.jpep.ftn_trade_order import FTNTradeOrderDocument +from models.jpep.user import User as JPEPUser + + +async def init_db() -> None: + await ArticleEarningRankingRecord.init() + await DailyUpdateRankingRecord.init() + await JianshuUser.init() + await UserAssetsRankingRecord.init() + await CreditRecord.init() + await FTNTradeOrderDocument.ensure_indexes() + await JPEPUser.init() diff --git a/models/jpep/credit_history.py b/models/jpep/credit_history.py deleted file mode 100644 index e8281cd..0000000 --- a/models/jpep/credit_history.py +++ /dev/null @@ -1,25 +0,0 @@ -from datetime import datetime -from typing import Optional - -from jkit.msgspec_constraints import NonNegativeInt, PositiveInt -from sshared.mongo import Document, Index - -from utils.mongo import JPEP_DB - - -class CreditHistoryDocument(Document, frozen=True): - time: datetime - user_id: PositiveInt - value: NonNegativeInt - - class Meta: # type: ignore - collection = JPEP_DB.credit_history - indexes = (Index(keys=("time", "userId"), unique=True),) - - @classmethod - async def get_latest_value(cls, user_id: int) -> Optional[int]: - latest_record = await cls.find_one({"userId": user_id}, sort={"time": "DESC"}) - if not latest_record: - return None - - return latest_record.value diff --git a/models/jpep/credit_record.py b/models/jpep/credit_record.py new file mode 100644 index 0000000..18fb0c8 --- /dev/null +++ b/models/jpep/credit_record.py @@ -0,0 +1,55 @@ +from datetime import datetime +from typing import Optional + +from sshared.postgres import Table +from sshared.strict_struct import ( + NonNegativeInt, + PositiveInt, +) + +from utils.postgres import get_jpep_conn + + +class CreditRecord(Table, frozen=True): + time: datetime + user_id: PositiveInt + credit: NonNegativeInt + + @classmethod + async def _create_table(cls) -> None: + conn = await get_jpep_conn() + await conn.execute( + """ + CREATE TABLE IF NOT EXISTS credit_records ( + time TIMESTAMP NOT NULL, + user_id INTEGER NOT NULL, + credit INTEGER NOT NULL, + CONSTRAINT pk_credit_records_time_user_id PRIMARY KEY (time, user_id) + ); + """ + ) + + async def create(self) -> None: + self.validate() + + conn = await get_jpep_conn() + await conn.execute( + "INSERT INTO credit_records (time, user_id, credit) VALUES " + "(%s, %s, %s);", + (self.time, self.user_id, self.credit), + ) + + @classmethod + async def get_latest_credit(cls, user_id: int) -> Optional[int]: + conn = await get_jpep_conn() + cursor = await conn.execute( + "SELECT credit FROM credit_records WHERE user_id = %s " + "ORDER BY time DESC LIMIT 1;", + (user_id,), + ) + + data = await cursor.fetchone() + if not data: + return None + + return data[0] diff --git a/models/jpep/user.py b/models/jpep/user.py index 2c72067..42e902e 100644 --- a/models/jpep/user.py +++ b/models/jpep/user.py @@ -1,96 +1,119 @@ from datetime import datetime -from typing import Any, Optional +from typing import Optional -from jkit.msgspec_constraints import NonNegativeInt, PositiveInt -from sshared.mongo import Document, Field, Index +from sshared.postgres import Table +from sshared.strict_struct import ( + NonEmptyStr, + PositiveInt, +) -from utils.mongo import JPEP_DB +from utils.postgres import get_jpep_conn -class CreditHistoryFieldItem(Field, frozen=True): - time: datetime - value: NonNegativeInt +class User(Table, frozen=True): + id: PositiveInt + update_time: datetime + name: NonEmptyStr + hashed_name: NonEmptyStr + avatar_url: Optional[NonEmptyStr] + @classmethod + async def _create_table(cls) -> None: + conn = await get_jpep_conn() + await conn.execute( + """ + CREATE TABLE IF NOT EXISTS users ( + id INTEGER NOT NULL CONSTRAINT pk_users_id PRIMARY KEY, + update_time TIMESTAMP NOT NULL, + name TEXT NOT NULL, + hashed_name VARCHAR(9) NOT NULL, + avatar_url TEXT + ); + """ + ) -class UserDocument(Document, frozen=True): - updated_at: datetime - id: PositiveInt - name: str - hashed_name: Optional[str] - avatar_url: Optional[str] - - class Meta: # type: ignore - collection = JPEP_DB.users - indexes = ( - Index(keys=("id",), unique=True), - Index(keys=("updatedAt",)), + async def create(self) -> None: + self.validate() + + conn = await get_jpep_conn() + await conn.execute( + "INSERT INTO users (id, update_time, name, hashed_name, avatar_url) VALUES " + "(%s, %s, %s, %s, %s);", + (self.id, self.update_time, self.name, self.hashed_name, self.avatar_url), ) @classmethod - async def is_record_exist(cls, id: int) -> bool: # noqa: A002 - return await cls.find_one({"id": id}) is not None + async def get_by_id(cls, id: int) -> Optional["User"]: # noqa: A002 + conn = await get_jpep_conn() + cursor = await conn.execute( + "SELECT update_time, name, hashed_name, avatar_url " + "FROM users WHERE id = %s", + (id,), + ) + + data = await cursor.fetchone() + if not data: + return None + + return cls( + id=id, + update_time=data[0], + name=data[1], + hashed_name=data[2], + avatar_url=data[3], + ) @classmethod - async def insert_or_update_one( + async def upsert( cls, - *, - updated_at: Optional[datetime] = None, id: int, # noqa: A002 name: str, hashed_name: str, - avatar_url: Optional[str], + avatar_url: Optional[str] = None, ) -> None: - if not updated_at: - updated_at = datetime.now() - - if not await cls.is_record_exist(id): - await UserDocument( - updated_at=updated_at, + user = await cls.get_by_id(id) + # 如果不存在,创建用户 + if not user: + await cls( id=id, + update_time=datetime.now(), name=name, hashed_name=hashed_name, avatar_url=avatar_url, - ).save() + ).create() return - db_data = await cls.find_one({"id": id}) - if not db_data: - raise AssertionError("意外的空值") - # 如果数据库中数据的更新时间晚于本次更新时间,则本次数据已不是最新 - # 此时跳过更新 - if updated_at < db_data.updated_at: + # 如果当前数据不是最新,跳过更新 + if user.update_time > datetime.now(): return - update_data: dict[str, Any] = { - "$set": { - # 即使没有要更新的数据,也要刷新更新时间 - "updatedAt": updated_at, - } - } - # 如果昵称不一致,更新之 - if (name is not None and db_data.name is not None) and name != db_data.name: - update_data["$set"]["name"] = name + # 在一个事务中一次性完成全部字段的更新 + conn = await get_jpep_conn() + async with conn.transaction(): + # 更新更新时间 + await conn.execute( + "UPDATE users SET update_time = %s WHERE id = %s", + (datetime.now(), id), + ) - # 如果头像链接有变动,更新之 - if avatar_url is not None and avatar_url != db_data.avatar_url: - update_data["$set"]["avatarUrl"] = avatar_url + # 更新昵称和哈希后昵称 + if user.name and name and user.name != name: + # 哈希后昵称一定会跟随昵称变化,一同更新 + await conn.execute( + "UPDATE users SET name = %s, hashed_name = %s WHERE id = %s", + (name, hashed_name, id), + ) - await cls.get_collection().update_one({"id": id}, update_data) + # 如果没有存储头像链接,进行添加 + if not user.avatar_url and avatar_url: + await conn.execute( + "UPDATE users SET avatar_url = %s WHERE id = %s", + (avatar_url, id), + ) - @classmethod - async def insert_one_if_not_exist( - cls, - *, - updated_at: datetime, - id: int, # noqa: A002 - name: str, - hashed_name: Optional[str], - ) -> None: - if not await cls.is_record_exist(id): - await UserDocument( - updated_at=updated_at, - id=id, - name=name, - hashed_name=hashed_name, - avatar_url=None, - ).save() + # 更新头像链接 + if user.avatar_url and avatar_url and user.avatar_url != avatar_url: + await conn.execute( + "UPDATE users SET avatar_url = %s WHERE id = %s", + (avatar_url, id), + ) diff --git a/utils/postgres.py b/utils/postgres.py index 6c2f243..f7f477a 100644 --- a/utils/postgres.py +++ b/utils/postgres.py @@ -11,4 +11,4 @@ _jpep_connection_manager = ConnectionManager(CONFIG.jpep_postgres.connection_string) get_jianshu_conn = _jianshu_connection_manager.get_conn -get_jianshu_conn = _jpep_connection_manager.get_conn +get_jpep_conn = _jpep_connection_manager.get_conn From 7f0bd0112b0b4a3bb20bd2eb0d10f73b9878630d Mon Sep 17 00:00:00 2001 From: FHU-yezi Date: Fri, 1 Nov 2024 17:45:19 +0800 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=AE=80?= =?UTF-8?q?=E4=B9=A6=E7=A7=AF=E5=88=86=E5=85=91=E6=8D=A2=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E6=8C=82=E5=8D=95=E4=BF=A1=E6=81=AF=E5=8F=8C=E5=86=99=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E5=8F=8A=E8=BF=81=E7=A7=BB=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jobs/jpep/ftn_trade.py | 37 ++++++++++++ migrate_ftn_macket_records.py | 51 +++++++++++++++++ migrate_ftn_order.py | 35 ++++++++++++ models/__init__.py | 6 +- models/jpep/new/ftn_macket_record.py | 61 ++++++++++++++++++++ models/jpep/new/ftn_order.py | 84 ++++++++++++++++++++++++++++ 6 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 migrate_ftn_macket_records.py create mode 100644 migrate_ftn_order.py create mode 100644 models/jpep/new/ftn_macket_record.py create mode 100644 models/jpep/new/ftn_order.py diff --git a/jobs/jpep/ftn_trade.py b/jobs/jpep/ftn_trade.py index 5daff8c..154e287 100644 --- a/jobs/jpep/ftn_trade.py +++ b/jobs/jpep/ftn_trade.py @@ -6,6 +6,8 @@ from models.jpep.credit_record import CreditRecord from models.jpep.ftn_trade_order import AmountField, FTNTradeOrderDocument +from models.jpep.new.ftn_macket_record import FTNMacketRecord +from models.jpep.new.ftn_order import FTNOrder, TypeEnum from models.jpep.user import User from utils.log import log_flow_run_start, log_flow_run_success, logger from utils.prefect_helper import ( @@ -68,6 +70,40 @@ async def process_item( ) +async def transform_and_write_new_data_source( + type: Literal["buy", "sell"], # noqa: A002 + old_data: list[FTNTradeOrderDocument], +) -> None: + new_data: list[FTNMacketRecord] = [] + for item in old_data: + order = await FTNOrder.get_by_id(item.id) + if not order: + await FTNOrder( + id=item.id, + type={"buy": TypeEnum.BUY, "sell": TypeEnum.SELL}[type], + publisher_id=item.publisher_id, + publish_time=item.published_at, + last_seen_time=item.fetch_time, + ).create() + else: + await FTNOrder.update_last_seen_time(order.id, item.fetch_time) + + new_data.append( + FTNMacketRecord( + fetch_time=item.fetch_time, + id=item.id, + price=item.price, + traded_count=item.traded_count, + total_amount=item.amount.total, + traded_amount=item.amount.traded, + remaining_amount=item.amount.tradable, + minimum_trade_amount=item.amount.minimum_trade, + ) + ) + + await FTNMacketRecord.insert_many(new_data) + + @flow( **generate_flow_config( name="采集简书积分兑换平台简书贝交易挂单", @@ -85,6 +121,7 @@ async def main(type: Literal["buy", "sell"]) -> None: # noqa: A002 if data: await FTNTradeOrderDocument.insert_many(data) + await transform_and_write_new_data_source(type, data) else: logger.warn("没有可采集的挂单信息,跳过数据写入") diff --git a/migrate_ftn_macket_records.py b/migrate_ftn_macket_records.py new file mode 100644 index 0000000..10f873f --- /dev/null +++ b/migrate_ftn_macket_records.py @@ -0,0 +1,51 @@ +from asyncio import run as asyncio_run + +from sshared.logging import Logger + +from models.jpep.new.ftn_macket_record import FTNMacketRecord +from utils.mongo import JPEP_DB + +OLD_COLLECTION = JPEP_DB.ftn_trade_orders +logger = Logger() + + +async def main() -> None: + await FTNMacketRecord.init() + + batch: list[FTNMacketRecord] = [] + + logger.info("开始执行数据迁移") + async for item in OLD_COLLECTION.find().sort({"fetchTime": 1}): + batch.append( + FTNMacketRecord( + fetch_time=item["fetchTime"], + id=item["id"], + price=item["price"], + traded_count=item["tradedCount"], + total_amount=item["amount"]["total"], + traded_amount=item["amount"]["traded"], + remaining_amount=item["amount"]["tradable"], + minimum_trade_amount=item["amount"]["minimumTrade"], + ) + ) + + if len(batch) == 10000: + await FTNMacketRecord.insert_many(batch) + logger.debug( + f"已迁移 {batch[0].fetch_time}/{batch[0].id} - " + f"{batch[-1].fetch_time}/{batch[-1].id}" + ) + batch.clear() + + if batch: + await FTNMacketRecord.insert_many(batch) + logger.debug( + f"已迁移 {batch[0].fetch_time}/{batch[0].id} - " + f"{batch[-1].fetch_time}/{batch[-1].id}" + ) + batch.clear() + + logger.info("数据迁移完成") + + +asyncio_run(main()) diff --git a/migrate_ftn_order.py b/migrate_ftn_order.py new file mode 100644 index 0000000..760c01c --- /dev/null +++ b/migrate_ftn_order.py @@ -0,0 +1,35 @@ +from asyncio import run as asyncio_run + +from sshared.logging import Logger + +from models.jpep.new.ftn_order import FTNOrder, TypeEnum +from utils.mongo import JPEP_DB + +OLD_COLLECTION = JPEP_DB.ftn_trade_orders +logger = Logger() + + +async def main() -> None: + await FTNOrder.init() + + logger.info("开始执行数据迁移") + for order_id in await OLD_COLLECTION.distinct("id"): + last_record = await OLD_COLLECTION.find_one( + {"id": order_id}, sort={"fetchTime": -1} + ) + if not last_record: + raise ValueError + + await FTNOrder( + id=last_record["id"], + type={"buy": TypeEnum.BUY, "sell": TypeEnum.SELL}[last_record["type"]], + publisher_id=last_record["publisherId"], + publish_time=last_record["publishedAt"], + last_seen_time=last_record["fetchTime"], + ).create() + logger.debug(f"已迁移订单 {order_id}") + + logger.info("数据迁移完成") + + +asyncio_run(main()) diff --git a/models/__init__.py b/models/__init__.py index ce66423..7b28f96 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -5,7 +5,8 @@ from models.jianshu.user import User as JianshuUser from models.jianshu.user_assets_ranking_record import UserAssetsRankingRecord from models.jpep.credit_record import CreditRecord -from models.jpep.ftn_trade_order import FTNTradeOrderDocument +from models.jpep.new.ftn_macket_record import FTNMacketRecord +from models.jpep.new.ftn_order import FTNOrder from models.jpep.user import User as JPEPUser @@ -15,5 +16,6 @@ async def init_db() -> None: await JianshuUser.init() await UserAssetsRankingRecord.init() await CreditRecord.init() - await FTNTradeOrderDocument.ensure_indexes() + await FTNMacketRecord.init() + await FTNOrder.init() await JPEPUser.init() diff --git a/models/jpep/new/ftn_macket_record.py b/models/jpep/new/ftn_macket_record.py new file mode 100644 index 0000000..4400b2b --- /dev/null +++ b/models/jpep/new/ftn_macket_record.py @@ -0,0 +1,61 @@ +from datetime import datetime + +from sshared.postgres import Table +from sshared.strict_struct import NonNegativeInt, PositiveFloat, PositiveInt + +from utils.postgres import get_jpep_conn + + +class FTNMacketRecord(Table, frozen=True): + fetch_time: datetime + id: PositiveInt + price: PositiveFloat + traded_count: NonNegativeInt + total_amount: PositiveInt + traded_amount: NonNegativeInt + remaining_amount: int + minimum_trade_amount: PositiveInt + + @classmethod + async def _create_table(cls) -> None: + conn = await get_jpep_conn() + await conn.execute( + """ + CREATE TABLE IF NOT EXISTS ftn_macket_records ( + fetch_time TIMESTAMP NOT NULL, + id INTEGER NOT NULL, + price NUMERIC NOT NULL, + traded_count SMALLINT NOT NULL, + total_amount INTEGER NOT NULL, + traded_amount INTEGER NOT NULL, + remaining_amount INTEGER NOT NULL, + minimum_trade_amount INTEGER NOT NULL, + CONSTRAINT pk_ftn_macket_records_fetch_time_id PRIMARY KEY (fetch_time, id) + ); + """ # noqa: E501 + ) + + @classmethod + async def insert_many(cls, data: list["FTNMacketRecord"]) -> None: + for item in data: + item.validate() + + conn = await get_jpep_conn() + await conn.cursor().executemany( + "INSERT INTO ftn_macket_records (fetch_time, id, price, traded_count, " + "total_amount, traded_amount, remaining_amount, minimum_trade_amount) " + "VALUES (%s, %s, %s, %s, %s, %s, %s, %s);", + [ + ( + item.fetch_time, + item.id, + item.price, + item.traded_count, + item.total_amount, + item.traded_amount, + item.remaining_amount, + item.minimum_trade_amount, + ) + for item in data + ], + ) diff --git a/models/jpep/new/ftn_order.py b/models/jpep/new/ftn_order.py new file mode 100644 index 0000000..f758921 --- /dev/null +++ b/models/jpep/new/ftn_order.py @@ -0,0 +1,84 @@ +from datetime import datetime +from enum import Enum +from typing import Optional + +from sshared.postgres import Table, create_enum +from sshared.strict_struct import PositiveInt + +from utils.postgres import get_jpep_conn + + +class TypeEnum(Enum): + BUY = "BUY" + SELL = "SELL" + + +class FTNOrder(Table, frozen=True): + id: PositiveInt + type: TypeEnum + publisher_id: PositiveInt + publish_time: datetime + last_seen_time: Optional[datetime] + + @classmethod + async def _create_enum(cls) -> None: + conn = await get_jpep_conn() + await create_enum(conn=conn, name="enum_ftn_orders_type", enum_class=TypeEnum) + + @classmethod + async def _create_table(cls) -> None: + conn = await get_jpep_conn() + await conn.execute( + """ + CREATE TABLE IF NOT EXISTS ftn_orders ( + id INTEGER CONSTRAINT pk_ftn_orders_id PRIMARY KEY, + type enum_ftn_orders_type NOT NULL, + publisher_id INTEGER NOT NULL, + publish_time TIMESTAMP NOT NULL, + last_seen_time TIMESTAMP + ); + """ + ) + + async def create(self) -> None: + conn = await get_jpep_conn() + await conn.execute( + "INSERT INTO ftn_orders (id, type, publisher_id, publish_time, " + "last_seen_time) VALUES (%s, %s, %s, %s, %s);", + ( + self.id, + self.type, + self.publisher_id, + self.publish_time, + self.last_seen_time, + ), + ) + + @classmethod + async def get_by_id(cls, id: int) -> Optional["FTNOrder"]: # noqa: A002 + conn = await get_jpep_conn() + cursor = await conn.execute( + "SELECT type, publisher_id, publish_time, last_seen_time " + "FROM ftn_orders WHERE id = %s;", + (id,), + ) + + data = await cursor.fetchone() + if not data: + return None + + return cls( + id=id, + type=data[0], + publisher_id=data[1], + publish_time=data[2], + last_seen_time=data[3], + ) + + @classmethod + async def update_last_seen_time(cls, id: int, last_seen_time: datetime) -> None: # noqa: A002 + conn = await get_jpep_conn() + await conn.execute( + "UPDATE ftn_orders SET last_seen_time = %s WHERE id = %s;", + (last_seen_time, id), + ) From 2724d480b13da05ad0973d96cfd429a1c7d44b84 Mon Sep 17 00:00:00 2001 From: FHU-yezi Date: Fri, 1 Nov 2024 21:44:50 +0800 Subject: [PATCH 5/7] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=20README=20?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5cacef3..6497878 100644 --- a/README.md +++ b/README.md @@ -1 +1,99 @@ -# JFetcher \ No newline at end of file +# 部署 + +## 环境 + +- Python 3.9+ +- MongoDB +- PostgreSQL +- Prefect 2 + +## 数据库准备 + +创建用户: + +```sql +CREATE ROLE jfetcher LOGIN PASSWORD 'jfetcher'; +``` + +创建数据库: + +```sql +CREATE DATABASE jianshu WITH OWNER = jfetcher; +CREATE DATABASE jpep WITH OWNER = jfetcher; +CREATE DATABASE logs; +``` + +## 配置 + +复制 `config.example.toml` 文件,将其重命名为 `config.toml`。 + +```shell +cp config.example.toml config.toml +``` + +如果您使用 Docker 进行部署: + +- mongo.host 填写 `mongodb` +- jianshu_postgres.host 填写 `postgres` +- jpep_postgres.host 填写 `postgres` +- logging.host 填写 `postgres` +- notify.host 填写 `gotify` + +同时,您需要填写正确的 `postgres.user` 和 `postgres.password`。 + +## 使用 Docker 部署 + +创建 Docker 网络: + +```shell +docker network create gotify +docker network create mongodb +docker network create postgres +docker network create prefect +``` + +您需要在 `gotify` 网络的 `27017` 端口上运行一个 Gotify 服务。 + +您需要在 `mongodb` 网络的 `27017` 端口上运行一个 MongoDB 服务,该服务不开启身份验证。 + +您需要在 `postgres` 网络的 `5173` 端口上运行一个 PostgreSQL 服务,身份验证相关信息请参考 `部署 - 数据库准备` 一节。 + +您需要在 `prefect` 网络的 `4200` 端口上运行一个 Prefect 服务。 + +如您希望更换 Docker 网络名称或服务端口号,请同时调整 `config.toml` 中的相关配置。 + +启动服务: + +```shell +docker compose up -d +``` + +## 传统部署(不推荐) + +下载 Python 项目管理工具 [uv](https://github.com/astral-sh/uv): + +```shell +pip install uv +``` + +安装依赖库(将自动创建虚拟环境): + +```shell +uv install +``` + +您需要在 `8701` 端口上运行一个 Gotify 服务。 + +您需要在 `27017` 端口上运行一个 MongoDB 服务,该服务不开启身份验证。 + +您需要在 `5173` 端口上运行一个 PostgreSQL 服务,身份验证相关信息请参考 `部署 - 数据库准备` 一节。 + +您需要在 `4200` 端口上运行一个 Prefect 服务。 + +如您希望更换服务端口号,请同时调整 `config.toml` 中的相关配置。 + +启动服务: + +```shell +uv run main.py +``` From 1552565843b1e9352f15713339a22d306936fee7 Mon Sep 17 00:00:00 2001 From: FHU-yezi Date: Fri, 1 Nov 2024 21:02:43 +0800 Subject: [PATCH 6/7] =?UTF-8?q?perf:=20=E4=BD=BF=E7=94=A8=E5=88=86?= =?UTF-8?q?=E5=8C=BA=E8=A1=A8=E4=BC=98=E5=8C=96=E7=AE=80=E4=B9=A6=E7=A7=AF?= =?UTF-8?q?=E5=88=86=E5=85=91=E6=8D=A2=E5=B9=B3=E5=8F=B0=E5=B8=82=E5=9C=BA?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E8=A1=A8=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/jpep/new/ftn_macket_record.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/models/jpep/new/ftn_macket_record.py b/models/jpep/new/ftn_macket_record.py index 4400b2b..b59117f 100644 --- a/models/jpep/new/ftn_macket_record.py +++ b/models/jpep/new/ftn_macket_record.py @@ -31,9 +31,24 @@ async def _create_table(cls) -> None: remaining_amount INTEGER NOT NULL, minimum_trade_amount INTEGER NOT NULL, CONSTRAINT pk_ftn_macket_records_fetch_time_id PRIMARY KEY (fetch_time, id) - ); + ) PARTITION BY RANGE (fetch_time); """ # noqa: E501 ) + await conn.execute( + "CREATE TABLE IF NOT EXISTS ftn_macket_records_2023 PARTITION " + "OF ftn_macket_records FOR VALUES FROM ('2023-01-01 00:00:00') " + "TO ('2023-12-31 23:59:59');" + ) + await conn.execute( + "CREATE TABLE IF NOT EXISTS ftn_macket_records_2024 PARTITION " + "OF ftn_macket_records FOR VALUES FROM ('2024-01-01 00:00:00') " + "TO ('2024-12-31 23:59:59');" + ) + await conn.execute( + "CREATE TABLE IF NOT EXISTS ftn_macket_records_2025 PARTITION " + "OF ftn_macket_records FOR VALUES FROM ('2025-01-01 00:00:00') " + "TO ('2025-12-31 23:59:59');" + ) @classmethod async def insert_many(cls, data: list["FTNMacketRecord"]) -> None: From adf2f155bb912ccda2f36dc892d4ea724952d68c Mon Sep 17 00:00:00 2001 From: FHU-yezi Date: Fri, 1 Nov 2024 21:55:41 +0800 Subject: [PATCH 7/7] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 2 +- pyproject.toml | 2 +- uv.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 499e79f..b4d26bd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ networks: services: main: - image: jfetcher:3.7.0 + image: jfetcher:3.8.0 container_name: jfetcher build: . volumes: diff --git a/pyproject.toml b/pyproject.toml index e4617a8..1403fe9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "jfetcher" -version = "3.7.0" +version = "3.8.0" description = "简书数据采集工具" readme = "README.md" license = {file = "LICENSE"} diff --git a/uv.lock b/uv.lock index 6612d38..eb5fafd 100644 --- a/uv.lock +++ b/uv.lock @@ -707,7 +707,7 @@ wheels = [ [[package]] name = "jfetcher" -version = "3.7.0" +version = "3.8.0" source = { virtual = "." } dependencies = [ { name = "jkit" },