From b04f5bcd6f914291ca4e7ad361d65228cb0460a3 Mon Sep 17 00:00:00 2001 From: persist-1 Date: Sat, 6 Sep 2025 06:08:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(database):=20=E4=BC=98=E5=8C=96=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E6=A8=A1=E5=9E=8B=E5=92=8C=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加cryptography依赖用于加密功能 - 重构数据库模型字段类型和约束 - 增加数据库自动创建功能 - 改进数据库连接管理和错误处理 - 更新相关依赖文件(pyproject.toml, requirements.txt) --- database/db_session.py | 29 ++- database/models.py | 470 +++++++++++++++++++------------------- database/sqlite_tables.db | Bin 262144 -> 303104 bytes pyproject.toml | 1 + requirements.txt | 6 +- uv.lock | 127 ++++++++++ 6 files changed, 392 insertions(+), 241 deletions(-) diff --git a/database/db_session.py b/database/db_session.py index 4c98edb..d8bcbb1 100644 --- a/database/db_session.py +++ b/database/db_session.py @@ -1,16 +1,28 @@ +from sqlalchemy import text from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession from sqlalchemy.orm import sessionmaker from contextlib import asynccontextmanager from .models import Base -from config import SAVE_DATA_OPTION +import config from config.db_config import mysql_db_config, sqlite_db_config # Keep a cache of engines _engines = {} + +async def create_database_if_not_exists(db_type: str): + if db_type == "mysql" or db_type == "db": + # Connect to the server without a database + server_url = f"mysql+asyncmy://{mysql_db_config['user']}:{mysql_db_config['password']}@{mysql_db_config['host']}:{mysql_db_config['port']}" + engine = create_async_engine(server_url, echo=False) + async with engine.connect() as conn: + await conn.execute(text(f"CREATE DATABASE IF NOT EXISTS {mysql_db_config['db_name']}")) + await engine.dispose() + + def get_async_engine(db_type: str = None): if db_type is None: - db_type = SAVE_DATA_OPTION + db_type = config.SAVE_DATA_OPTION if db_type in _engines: return _engines[db_type] @@ -31,14 +43,21 @@ def get_async_engine(db_type: str = None): async def create_tables(db_type: str = None): + if db_type is None: + db_type = config.SAVE_DATA_OPTION + await create_database_if_not_exists(db_type) engine = get_async_engine(db_type) - async with engine.begin() as conn: - await conn.run_sync(Base.metadata.create_all) + if engine: + async with engine.begin() as conn: + await conn.run_sync(Base.metadata.create_all) @asynccontextmanager async def get_session() -> AsyncSession: - engine = get_async_engine(SAVE_DATA_OPTION) + engine = get_async_engine(config.SAVE_DATA_OPTION) + if not engine: + yield None + return AsyncSessionFactory = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False) session = AsyncSessionFactory() try: diff --git a/database/models.py b/database/models.py index a13766e..8e41bca 100644 --- a/database/models.py +++ b/database/models.py @@ -1,4 +1,4 @@ -from sqlalchemy import create_engine, Column, Integer, String, Text, BigInteger +from sqlalchemy import create_engine, Column, Integer, Text, String, BigInteger from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker @@ -7,54 +7,54 @@ Base = declarative_base() class BilibiliVideo(Base): __tablename__ = 'bilibili_video' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - avatar = Column(String) + video_id = Column(BigInteger, nullable=False, index=True, unique=True) + video_url = Column(Text, nullable=False) + user_id = Column(BigInteger, index=True) + nickname = Column(Text) + avatar = Column(Text) + liked_count = Column(Integer) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - video_id = Column(String, index=True) - video_type = Column(String) - title = Column(String) + video_type = Column(Text) + title = Column(Text) desc = Column(Text) create_time = Column(BigInteger, index=True) - liked_count = Column(String) - disliked_count = Column(String) - video_play_count = Column(String) - video_favorite_count = Column(String) - video_share_count = Column(String) - video_coin_count = Column(String) - video_danmaku = Column(String) - video_comment = Column(String) - video_url = Column(String) - video_cover_url = Column(String) - source_keyword = Column(String, default='') + disliked_count = Column(Text) + video_play_count = Column(Text) + video_favorite_count = Column(Text) + video_share_count = Column(Text) + video_coin_count = Column(Text) + video_danmaku = Column(Text) + video_comment = Column(Text) + video_cover_url = Column(Text) + source_keyword = Column(Text, default='') class BilibiliVideoComment(Base): __tablename__ = 'bilibili_video_comment' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - sex = Column(String) - sign = Column(String) - avatar = Column(String) + user_id = Column(String(255)) + nickname = Column(Text) + sex = Column(Text) + sign = Column(Text) + avatar = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - comment_id = Column(String, index=True) - video_id = Column(String, index=True) + comment_id = Column(BigInteger, index=True) + video_id = Column(BigInteger, index=True) content = Column(Text) create_time = Column(BigInteger) - sub_comment_count = Column(String) - parent_comment_id = Column(String) - like_count = Column(String, default='0') + sub_comment_count = Column(Text) + parent_comment_id = Column(String(255)) + like_count = Column(Text, default='0') class BilibiliUpInfo(Base): __tablename__ = 'bilibili_up_info' id = Column(Integer, primary_key=True) - user_id = Column(String, index=True) - nickname = Column(String) - sex = Column(String) - sign = Column(String) - avatar = Column(String) + user_id = Column(BigInteger, index=True) + nickname = Column(Text) + sex = Column(Text) + sign = Column(Text) + avatar = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) total_fans = Column(Integer) @@ -65,25 +65,25 @@ class BilibiliUpInfo(Base): class BilibiliContactInfo(Base): __tablename__ = 'bilibili_contact_info' id = Column(Integer, primary_key=True) - up_id = Column(String, index=True) - fan_id = Column(String, index=True) - up_name = Column(String) - fan_name = Column(String) - up_sign = Column(String) - fan_sign = Column(String) - up_avatar = Column(String) - fan_avatar = Column(String) + up_id = Column(BigInteger, index=True) + fan_id = Column(BigInteger, index=True) + up_name = Column(Text) + fan_name = Column(Text) + up_sign = Column(Text) + fan_sign = Column(Text) + up_avatar = Column(Text) + fan_avatar = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) class BilibiliUpDynamic(Base): __tablename__ = 'bilibili_up_dynamic' id = Column(Integer, primary_key=True) - dynamic_id = Column(String, index=True) - user_id = Column(String) - user_name = Column(String) + dynamic_id = Column(BigInteger, index=True) + user_id = Column(String(255)) + user_name = Column(Text) text = Column(Text) - type = Column(String) + type = Column(Text) pub_ts = Column(BigInteger) total_comments = Column(Integer) total_forwards = Column(Integer) @@ -94,296 +94,296 @@ class BilibiliUpDynamic(Base): class DouyinAweme(Base): __tablename__ = 'douyin_aweme' id = Column(Integer, primary_key=True) - user_id = Column(String) - sec_uid = Column(String) - short_user_id = Column(String) - user_unique_id = Column(String) - nickname = Column(String) - avatar = Column(String) - user_signature = Column(String) - ip_location = Column(String) + user_id = Column(String(255)) + sec_uid = Column(String(255)) + short_user_id = Column(String(255)) + user_unique_id = Column(String(255)) + nickname = Column(Text) + avatar = Column(Text) + user_signature = Column(Text) + ip_location = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - aweme_id = Column(String, index=True) - aweme_type = Column(String) - title = Column(String) + aweme_id = Column(BigInteger, index=True) + aweme_type = Column(Text) + title = Column(Text) desc = Column(Text) create_time = Column(BigInteger, index=True) - liked_count = Column(String) - comment_count = Column(String) - share_count = Column(String) - collected_count = Column(String) - aweme_url = Column(String) - cover_url = Column(String) - video_download_url = Column(String) - music_download_url = Column(String) - note_download_url = Column(String) - source_keyword = Column(String, default='') + liked_count = Column(Text) + comment_count = Column(Text) + share_count = Column(Text) + collected_count = Column(Text) + aweme_url = Column(Text) + cover_url = Column(Text) + video_download_url = Column(Text) + music_download_url = Column(Text) + note_download_url = Column(Text) + source_keyword = Column(Text, default='') class DouyinAwemeComment(Base): __tablename__ = 'douyin_aweme_comment' id = Column(Integer, primary_key=True) - user_id = Column(String) - sec_uid = Column(String) - short_user_id = Column(String) - user_unique_id = Column(String) - nickname = Column(String) - avatar = Column(String) - user_signature = Column(String) - ip_location = Column(String) + user_id = Column(String(255)) + sec_uid = Column(String(255)) + short_user_id = Column(String(255)) + user_unique_id = Column(String(255)) + nickname = Column(Text) + avatar = Column(Text) + user_signature = Column(Text) + ip_location = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - comment_id = Column(String, index=True) - aweme_id = Column(String, index=True) + comment_id = Column(BigInteger, index=True) + aweme_id = Column(BigInteger, index=True) content = Column(Text) create_time = Column(BigInteger) - sub_comment_count = Column(String) - parent_comment_id = Column(String) - like_count = Column(String, default='0') - pictures = Column(String, default='') + sub_comment_count = Column(Text) + parent_comment_id = Column(String(255)) + like_count = Column(Text, default='0') + pictures = Column(Text, default='') class DyCreator(Base): __tablename__ = 'dy_creator' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - avatar = Column(String) - ip_location = Column(String) + user_id = Column(String(255)) + nickname = Column(Text) + avatar = Column(Text) + ip_location = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) desc = Column(Text) - gender = Column(String) - follows = Column(String) - fans = Column(String) - interaction = Column(String) - videos_count = Column(String) + gender = Column(Text) + follows = Column(Text) + fans = Column(Text) + interaction = Column(Text) + videos_count = Column(String(255)) class KuaishouVideo(Base): __tablename__ = 'kuaishou_video' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - avatar = Column(String) + user_id = Column(String(255)) + nickname = Column(Text) + avatar = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - video_id = Column(String, index=True) - video_type = Column(String) - title = Column(String) + video_id = Column(BigInteger, index=True) + video_type = Column(Text) + title = Column(Text) desc = Column(Text) create_time = Column(BigInteger, index=True) - liked_count = Column(String) - viewd_count = Column(String) - video_url = Column(String) - video_cover_url = Column(String) - video_play_url = Column(String) - source_keyword = Column(String, default='') + liked_count = Column(Text) + viewd_count = Column(Text) + video_url = Column(Text) + video_cover_url = Column(Text) + video_play_url = Column(Text) + source_keyword = Column(Text, default='') class KuaishouVideoComment(Base): __tablename__ = 'kuaishou_video_comment' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - avatar = Column(String) + user_id = Column(Integer) + nickname = Column(Text) + avatar = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - comment_id = Column(String, index=True) - video_id = Column(String, index=True) + comment_id = Column(BigInteger, index=True) + video_id = Column(BigInteger, index=True) content = Column(Text) create_time = Column(BigInteger) - sub_comment_count = Column(String) + sub_comment_count = Column(Text) class WeiboNote(Base): __tablename__ = 'weibo_note' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - avatar = Column(String) - gender = Column(String) - profile_url = Column(String) - ip_location = Column(String, default='') + user_id = Column(String(255)) + nickname = Column(Text) + avatar = Column(Text) + gender = Column(Text) + profile_url = Column(Text) + ip_location = Column(Text, default='') add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - note_id = Column(String, index=True) + note_id = Column(BigInteger, index=True) content = Column(Text) create_time = Column(BigInteger, index=True) - create_date_time = Column(String, index=True) - liked_count = Column(String) - comments_count = Column(String) - shared_count = Column(String) - note_url = Column(String) - source_keyword = Column(String, default='') + create_date_time = Column(BigInteger, index=True) + liked_count = Column(Text) + comments_count = Column(Text) + shared_count = Column(Text) + note_url = Column(Text) + source_keyword = Column(Text, default='') class WeiboNoteComment(Base): __tablename__ = 'weibo_note_comment' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - avatar = Column(String) - gender = Column(String) - profile_url = Column(String) - ip_location = Column(String, default='') + user_id = Column(String(255)) + nickname = Column(Text) + avatar = Column(Text) + gender = Column(Text) + profile_url = Column(Text) + ip_location = Column(Text, default='') add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - comment_id = Column(String, index=True) - note_id = Column(String, index=True) + comment_id = Column(BigInteger, index=True) + note_id = Column(BigInteger, index=True) content = Column(Text) create_time = Column(BigInteger) - create_date_time = Column(String, index=True) - comment_like_count = Column(String) - sub_comment_count = Column(String) - parent_comment_id = Column(String) + create_date_time = Column(BigInteger, index=True) + comment_like_count = Column(Text) + sub_comment_count = Column(Text) + parent_comment_id = Column(String(255)) class WeiboCreator(Base): __tablename__ = 'weibo_creator' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - avatar = Column(String) - ip_location = Column(String) + user_id = Column(String(255)) + nickname = Column(Text) + avatar = Column(Text) + ip_location = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) desc = Column(Text) - gender = Column(String) - follows = Column(String) - fans = Column(String) - tag_list = Column(String) + gender = Column(Text) + follows = Column(Text) + fans = Column(Text) + tag_list = Column(Text) class XhsCreator(Base): __tablename__ = 'xhs_creator' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - avatar = Column(String) - ip_location = Column(String) + user_id = Column(String(255)) + nickname = Column(Text) + avatar = Column(Text) + ip_location = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) desc = Column(Text) - gender = Column(String) - follows = Column(String) - fans = Column(String) - interaction = Column(String) - tag_list = Column(String) + gender = Column(Text) + follows = Column(Text) + fans = Column(Text) + interaction = Column(Text) + tag_list = Column(Text) class XhsNote(Base): __tablename__ = 'xhs_note' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - avatar = Column(String) - ip_location = Column(String) + user_id = Column(String(255)) + nickname = Column(Text) + avatar = Column(Text) + ip_location = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - note_id = Column(String, index=True) - type = Column(String) - title = Column(String) + note_id = Column(BigInteger, index=True) + type = Column(Text) + title = Column(Text) desc = Column(Text) - video_url = Column(String) + video_url = Column(Text) time = Column(BigInteger, index=True) last_update_time = Column(BigInteger) - liked_count = Column(String) - collected_count = Column(String) - comment_count = Column(String) - share_count = Column(String) + liked_count = Column(Text) + collected_count = Column(Text) + comment_count = Column(Text) + share_count = Column(Text) image_list = Column(Text) tag_list = Column(Text) - note_url = Column(String) - source_keyword = Column(String, default='') - xsec_token = Column(String) + note_url = Column(Text) + source_keyword = Column(Text, default='') + xsec_token = Column(Text) class XhsNoteComment(Base): __tablename__ = 'xhs_note_comment' id = Column(Integer, primary_key=True) - user_id = Column(String) - nickname = Column(String) - avatar = Column(String) - ip_location = Column(String) + user_id = Column(String(255)) + nickname = Column(Text) + avatar = Column(Text) + ip_location = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - comment_id = Column(String, index=True) + comment_id = Column(BigInteger, index=True) create_time = Column(BigInteger, index=True) - note_id = Column(String) + note_id = Column(String(255)) content = Column(Text) sub_comment_count = Column(Integer) pictures = Column(Text) - parent_comment_id = Column(String) - like_count = Column(String) + parent_comment_id = Column(String(255)) + like_count = Column(Text) class TiebaNote(Base): __tablename__ = 'tieba_note' id = Column(Integer, primary_key=True) - note_id = Column(String, index=True) - title = Column(String) + note_id = Column(BigInteger, index=True) + title = Column(Text) desc = Column(Text) - note_url = Column(String) - publish_time = Column(String, index=True) - user_link = Column(String, default='') - user_nickname = Column(String, default='') - user_avatar = Column(String, default='') - tieba_id = Column(String, default='') - tieba_name = Column(String) - tieba_link = Column(String) + note_url = Column(Text) + publish_time = Column(BigInteger, index=True) + user_link = Column(Text, default='') + user_nickname = Column(Text, default='') + user_avatar = Column(Text, default='') + tieba_id = Column(Integer, default='') + tieba_name = Column(Text) + tieba_link = Column(Text) total_replay_num = Column(Integer, default=0) total_replay_page = Column(Integer, default=0) - ip_location = Column(String, default='') + ip_location = Column(Text, default='') add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - source_keyword = Column(String, default='') + source_keyword = Column(Text, default='') class TiebaComment(Base): __tablename__ = 'tieba_comment' id = Column(Integer, primary_key=True) - comment_id = Column(String, index=True) - parent_comment_id = Column(String, default='') + comment_id = Column(BigInteger, index=True) + parent_comment_id = Column(String(255), default='') content = Column(Text) - user_link = Column(String, default='') - user_nickname = Column(String, default='') - user_avatar = Column(String, default='') - tieba_id = Column(String, default='') - tieba_name = Column(String) - tieba_link = Column(String) - publish_time = Column(String, index=True) - ip_location = Column(String, default='') + user_link = Column(Text, default='') + user_nickname = Column(Text, default='') + user_avatar = Column(Text, default='') + tieba_id = Column(String(255), default='') + tieba_name = Column(Text) + tieba_link = Column(Text) + publish_time = Column(BigInteger, index=True) + ip_location = Column(Text, default='') sub_comment_count = Column(Integer, default=0) - note_id = Column(String, index=True) - note_url = Column(String) + note_id = Column(BigInteger, index=True) + note_url = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) class TiebaCreator(Base): __tablename__ = 'tieba_creator' id = Column(Integer, primary_key=True) - user_id = Column(String) - user_name = Column(String) - nickname = Column(String) - avatar = Column(String) - ip_location = Column(String) + user_id = Column(String(255)) + user_name = Column(Text) + nickname = Column(Text) + avatar = Column(Text) + ip_location = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) - gender = Column(String) - follows = Column(String) - fans = Column(String) - registration_duration = Column(String) + gender = Column(Text) + follows = Column(Text) + fans = Column(Text) + registration_duration = Column(Text) class ZhihuContent(Base): __tablename__ = 'zhihu_content' id = Column(Integer, primary_key=True) - content_id = Column(String, index=True) - content_type = Column(String) + content_id = Column(BigInteger, index=True) + content_type = Column(Text) content_text = Column(Text) - content_url = Column(String) - question_id = Column(String) - title = Column(String) + content_url = Column(Text) + question_id = Column(String(255)) + title = Column(Text) desc = Column(Text) - created_time = Column(String, index=True) - updated_time = Column(String) + created_time = Column(BigInteger, index=True) + updated_time = Column(Text) voteup_count = Column(Integer, default=0) comment_count = Column(Integer, default=0) - source_keyword = Column(String) - user_id = Column(String) - user_link = Column(String) - user_nickname = Column(String) - user_avatar = Column(String) - user_url_token = Column(String) + source_keyword = Column(Text) + user_id = Column(String(255)) + user_link = Column(Text) + user_nickname = Column(Text) + user_avatar = Column(Text) + user_url_token = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) @@ -395,33 +395,33 @@ class ZhihuContent(Base): class ZhihuComment(Base): __tablename__ = 'zhihu_comment' id = Column(Integer, primary_key=True) - comment_id = Column(String, index=True) - parent_comment_id = Column(String) + comment_id = Column(BigInteger, index=True) + parent_comment_id = Column(String(255)) content = Column(Text) - publish_time = Column(String, index=True) - ip_location = Column(String) + publish_time = Column(BigInteger, index=True) + ip_location = Column(Text) sub_comment_count = Column(Integer, default=0) like_count = Column(Integer, default=0) dislike_count = Column(Integer, default=0) - content_id = Column(String, index=True) - content_type = Column(String) - user_id = Column(String) - user_link = Column(String) - user_nickname = Column(String) - user_avatar = Column(String) + content_id = Column(BigInteger, index=True) + content_type = Column(Text) + user_id = Column(String(255)) + user_link = Column(Text) + user_nickname = Column(Text) + user_avatar = Column(Text) add_ts = Column(BigInteger) last_modify_ts = Column(BigInteger) class ZhihuCreator(Base): __tablename__ = 'zhihu_creator' id = Column(Integer, primary_key=True) - user_id = Column(String, unique=True, index=True) - user_link = Column(String) - user_nickname = Column(String) - user_avatar = Column(String) - url_token = Column(String) - gender = Column(String) - ip_location = Column(String) + user_id = Column(Integer, unique=True, index=True) + user_link = Column(Text) + user_nickname = Column(Text) + user_avatar = Column(Text) + url_token = Column(Text) + gender = Column(Text) + ip_location = Column(Text) follows = Column(Integer, default=0) fans = Column(Integer, default=0) anwser_count = Column(Integer, default=0) diff --git a/database/sqlite_tables.db b/database/sqlite_tables.db index b04aae90a6d9e0de46d2f9a6c02b809e5830a22a..0da1bfae8feb01f6452c84013852b733d237e2df 100644 GIT binary patch literal 303104 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 Y8aKDa%FU|MM5KJH8BgvyO`hBTf9UD(uK)l5 literal 262144 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 ffam`sIH;Tw0tg_000IagfB*srAb=0.21.0", "alembic>=1.16.5", "asyncmy>=0.2.10", + "cryptography>=45.0.7", "fastapi==0.110.2", "httpx==0.28.1", "jieba==0.42.1", diff --git a/requirements.txt b/requirements.txt index 034439e..cd1c3e3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,4 +18,8 @@ parsel==1.9.1 pyexecjs==1.5.1 pandas==2.2.3 aiosqlite==0.21.0 -pyhumps==3.8.0 \ No newline at end of file +pyhumps==3.8.0 +cryptography>=45.0.7 +alembic>=1.16.5 +asyncmy>=0.2.10 +sqlalchemy>=2.0.43 diff --git a/uv.lock b/uv.lock index ec52445..758e4d0 100644 --- a/uv.lock +++ b/uv.lock @@ -156,6 +156,75 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, ] +[[package]] +name = "cffi" +version = "1.17.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "pycparser" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191, upload-time = "2024-09-04T20:43:30.027Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592, upload-time = "2024-09-04T20:43:32.108Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024, upload-time = "2024-09-04T20:43:34.186Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188, upload-time = "2024-09-04T20:43:36.286Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571, upload-time = "2024-09-04T20:43:38.586Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687, upload-time = "2024-09-04T20:43:40.084Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211, upload-time = "2024-09-04T20:43:41.526Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325, upload-time = "2024-09-04T20:43:43.117Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784, upload-time = "2024-09-04T20:43:45.256Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564, upload-time = "2024-09-04T20:43:46.779Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804, upload-time = "2024-09-04T20:43:48.186Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299, upload-time = "2024-09-04T20:43:49.812Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload-time = "2024-09-04T20:43:51.124Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload-time = "2024-09-04T20:43:52.872Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload-time = "2024-09-04T20:43:57.891Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload-time = "2024-09-04T20:44:00.18Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload-time = "2024-09-04T20:44:01.585Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload-time = "2024-09-04T20:44:03.467Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload-time = "2024-09-04T20:44:05.023Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload-time = "2024-09-04T20:44:06.444Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload-time = "2024-09-04T20:44:08.206Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload-time = "2024-09-04T20:44:09.481Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload-time = "2024-09-04T20:44:10.873Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/ea/8bb50596b8ffbc49ddd7a1ad305035daa770202a6b782fc164647c2673ad/cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16", size = 182220, upload-time = "2024-09-04T20:45:01.577Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ae/11/e77c8cd24f58285a82c23af484cf5b124a376b32644e445960d1a4654c3a/cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36", size = 178605, upload-time = "2024-09-04T20:45:03.837Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ed/65/25a8dc32c53bf5b7b6c2686b42ae2ad58743f7ff644844af7cdb29b49361/cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8", size = 424910, upload-time = "2024-09-04T20:45:05.315Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/42/7a/9d086fab7c66bd7c4d0f27c57a1b6b068ced810afc498cc8c49e0088661c/cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576", size = 447200, upload-time = "2024-09-04T20:45:06.903Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/63/1785ced118ce92a993b0ec9e0d0ac8dc3e5dbfbcaa81135be56c69cabbb6/cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", size = 454565, upload-time = "2024-09-04T20:45:08.975Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/74/06/90b8a44abf3556599cdec107f7290277ae8901a58f75e6fe8f970cd72418/cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0", size = 435635, upload-time = "2024-09-04T20:45:10.64Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bd/62/a1f468e5708a70b1d86ead5bab5520861d9c7eacce4a885ded9faa7729c3/cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3", size = 445218, upload-time = "2024-09-04T20:45:12.366Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/95/b34462f3ccb09c2594aa782d90a90b045de4ff1f70148ee79c69d37a0a5a/cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595", size = 460486, upload-time = "2024-09-04T20:45:13.935Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/fc/a1e4bebd8d680febd29cf6c8a40067182b64f00c7d105f8f26b5bc54317b/cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a", size = 437911, upload-time = "2024-09-04T20:45:15.696Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/c3/21cab7a6154b6a5ea330ae80de386e7665254835b9e98ecc1340b3a7de9a/cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e", size = 460632, upload-time = "2024-09-04T20:45:17.284Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/b5/fd9f8b5a84010ca169ee49f4e4ad6f8c05f4e3545b72ee041dbbcb159882/cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7", size = 171820, upload-time = "2024-09-04T20:45:18.762Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/52/b08750ce0bce45c143e1b5d7357ee8c55341b52bdef4b0f081af1eb248c2/cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662", size = 181290, upload-time = "2024-09-04T20:45:20.226Z" }, +] + [[package]] name = "charset-normalizer" version = "3.4.2" @@ -438,6 +507,53 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/68/7f46fb537958e87427d98a4074bcde4b67a70b04900cfc5ce29bc2f556c1/contourpy-1.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8c5acb8dddb0752bf252e01a3035b21443158910ac16a3b0d20e7fed7d534ce5", size = 221791, upload-time = "2025-04-15T17:45:24.794Z" }, ] +[[package]] +name = "cryptography" +version = "45.0.7" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a7/35/c495bffc2056f2dadb32434f1feedd79abde2a7f8363e1974afa9c33c7e2/cryptography-45.0.7.tar.gz", hash = "sha256:4b1654dfc64ea479c242508eb8c724044f1e964a47d1d1cacc5132292d851971", size = 744980, upload-time = "2025-09-01T11:15:03.146Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/91/925c0ac74362172ae4516000fe877912e33b5983df735ff290c653de4913/cryptography-45.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:3be4f21c6245930688bd9e162829480de027f8bf962ede33d4f8ba7d67a00cee", size = 7041105, upload-time = "2025-09-01T11:13:59.684Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/63/43641c5acce3a6105cf8bd5baeceeb1846bb63067d26dae3e5db59f1513a/cryptography-45.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:67285f8a611b0ebc0857ced2081e30302909f571a46bfa7a3cc0ad303fe015c6", size = 4205799, upload-time = "2025-09-01T11:14:02.517Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/29/c238dd9107f10bfde09a4d1c52fd38828b1aa353ced11f358b5dd2507d24/cryptography-45.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:577470e39e60a6cd7780793202e63536026d9b8641de011ed9d8174da9ca5339", size = 4430504, upload-time = "2025-09-01T11:14:04.522Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/62/24203e7cbcc9bd7c94739428cd30680b18ae6b18377ae66075c8e4771b1b/cryptography-45.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4bd3e5c4b9682bc112d634f2c6ccc6736ed3635fc3319ac2bb11d768cc5a00d8", size = 4209542, upload-time = "2025-09-01T11:14:06.309Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cd/e3/e7de4771a08620eef2389b86cd87a2c50326827dea5528feb70595439ce4/cryptography-45.0.7-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:465ccac9d70115cd4de7186e60cfe989de73f7bb23e8a7aa45af18f7412e75bf", size = 3889244, upload-time = "2025-09-01T11:14:08.152Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/b8/bca71059e79a0bb2f8e4ec61d9c205fbe97876318566cde3b5092529faa9/cryptography-45.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:16ede8a4f7929b4b7ff3642eba2bf79aa1d71f24ab6ee443935c0d269b6bc513", size = 4461975, upload-time = "2025-09-01T11:14:09.755Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/58/67/3f5b26937fe1218c40e95ef4ff8d23c8dc05aa950d54200cc7ea5fb58d28/cryptography-45.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8978132287a9d3ad6b54fcd1e08548033cc09dc6aacacb6c004c73c3eb5d3ac3", size = 4209082, upload-time = "2025-09-01T11:14:11.229Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/e4/b3e68a4ac363406a56cf7b741eeb80d05284d8c60ee1a55cdc7587e2a553/cryptography-45.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b6a0e535baec27b528cb07a119f321ac024592388c5681a5ced167ae98e9fff3", size = 4460397, upload-time = "2025-09-01T11:14:12.924Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/49/2c93f3cd4e3efc8cb22b02678c1fad691cff9dd71bb889e030d100acbfe0/cryptography-45.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a24ee598d10befaec178efdff6054bc4d7e883f615bfbcd08126a0f4931c83a6", size = 4337244, upload-time = "2025-09-01T11:14:14.431Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/19/030f400de0bccccc09aa262706d90f2ec23d56bc4eb4f4e8268d0ddf3fb8/cryptography-45.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:fa26fa54c0a9384c27fcdc905a2fb7d60ac6e47d14bc2692145f2b3b1e2cfdbd", size = 4568862, upload-time = "2025-09-01T11:14:16.185Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/29/56/3034a3a353efa65116fa20eb3c990a8c9f0d3db4085429040a7eef9ada5f/cryptography-45.0.7-cp311-abi3-win32.whl", hash = "sha256:bef32a5e327bd8e5af915d3416ffefdbe65ed975b646b3805be81b23580b57b8", size = 2936578, upload-time = "2025-09-01T11:14:17.638Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/61/0ab90f421c6194705a99d0fa9f6ee2045d916e4455fdbb095a9c2c9a520f/cryptography-45.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:3808e6b2e5f0b46d981c24d79648e5c25c35e59902ea4391a0dcb3e667bf7443", size = 3405400, upload-time = "2025-09-01T11:14:18.958Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/63/e8/c436233ddf19c5f15b25ace33979a9dd2e7aa1a59209a0ee8554179f1cc0/cryptography-45.0.7-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bfb4c801f65dd61cedfc61a83732327fafbac55a47282e6f26f073ca7a41c3b2", size = 7021824, upload-time = "2025-09-01T11:14:20.954Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/4c/8f57f2500d0ccd2675c5d0cc462095adf3faa8c52294ba085c036befb901/cryptography-45.0.7-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:81823935e2f8d476707e85a78a405953a03ef7b7b4f55f93f7c2d9680e5e0691", size = 4202233, upload-time = "2025-09-01T11:14:22.454Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/ac/59b7790b4ccaed739fc44775ce4645c9b8ce54cbec53edf16c74fd80cb2b/cryptography-45.0.7-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3994c809c17fc570c2af12c9b840d7cea85a9fd3e5c0e0491f4fa3c029216d59", size = 4423075, upload-time = "2025-09-01T11:14:24.287Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b8/56/d4f07ea21434bf891faa088a6ac15d6d98093a66e75e30ad08e88aa2b9ba/cryptography-45.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dad43797959a74103cb59c5dac71409f9c27d34c8a05921341fb64ea8ccb1dd4", size = 4204517, upload-time = "2025-09-01T11:14:25.679Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e8/ac/924a723299848b4c741c1059752c7cfe09473b6fd77d2920398fc26bfb53/cryptography-45.0.7-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ce7a453385e4c4693985b4a4a3533e041558851eae061a58a5405363b098fcd3", size = 3882893, upload-time = "2025-09-01T11:14:27.1Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/dc/4dab2ff0a871cc2d81d3ae6d780991c0192b259c35e4d83fe1de18b20c70/cryptography-45.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b04f85ac3a90c227b6e5890acb0edbaf3140938dbecf07bff618bf3638578cf1", size = 4450132, upload-time = "2025-09-01T11:14:28.58Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/dd/b2882b65db8fc944585d7fb00d67cf84a9cef4e77d9ba8f69082e911d0de/cryptography-45.0.7-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:48c41a44ef8b8c2e80ca4527ee81daa4c527df3ecbc9423c41a420a9559d0e27", size = 4204086, upload-time = "2025-09-01T11:14:30.572Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5d/fa/1d5745d878048699b8eb87c984d4ccc5da4f5008dfd3ad7a94040caca23a/cryptography-45.0.7-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f3df7b3d0f91b88b2106031fd995802a2e9ae13e02c36c1fc075b43f420f3a17", size = 4449383, upload-time = "2025-09-01T11:14:32.046Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/8b/fc61f87931bc030598e1876c45b936867bb72777eac693e905ab89832670/cryptography-45.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dd342f085542f6eb894ca00ef70236ea46070c8a13824c6bde0dfdcd36065b9b", size = 4332186, upload-time = "2025-09-01T11:14:33.95Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0b/11/09700ddad7443ccb11d674efdbe9a832b4455dc1f16566d9bd3834922ce5/cryptography-45.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1993a1bb7e4eccfb922b6cd414f072e08ff5816702a0bdb8941c247a6b1b287c", size = 4561639, upload-time = "2025-09-01T11:14:35.343Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/ed/8f4c1337e9d3b94d8e50ae0b08ad0304a5709d483bfcadfcc77a23dbcb52/cryptography-45.0.7-cp37-abi3-win32.whl", hash = "sha256:18fcf70f243fe07252dcb1b268a687f2358025ce32f9f88028ca5c364b123ef5", size = 2926552, upload-time = "2025-09-01T11:14:36.929Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/ff/026513ecad58dacd45d1d24ebe52b852165a26e287177de1d545325c0c25/cryptography-45.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:7285a89df4900ed3bfaad5679b1e668cb4b38a8de1ccbfc84b05f34512da0a90", size = 3392742, upload-time = "2025-09-01T11:14:38.368Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/13/3e/e42f1528ca1ea82256b835191eab1be014e0f9f934b60d98b0be8a38ed70/cryptography-45.0.7-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:de58755d723e86175756f463f2f0bddd45cc36fbd62601228a3f8761c9f58252", size = 3572442, upload-time = "2025-09-01T11:14:39.836Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/59/aa/e947693ab08674a2663ed2534cd8d345cf17bf6a1facf99273e8ec8986dc/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a20e442e917889d1a6b3c570c9e3fa2fdc398c20868abcea268ea33c024c4083", size = 4142233, upload-time = "2025-09-01T11:14:41.305Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/24/06/09b6f6a2fc43474a32b8fe259038eef1500ee3d3c141599b57ac6c57612c/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:258e0dff86d1d891169b5af222d362468a9570e2532923088658aa866eb11130", size = 4376202, upload-time = "2025-09-01T11:14:43.047Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/00/f2/c166af87e95ce6ae6d38471a7e039d3a0549c2d55d74e059680162052824/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d97cf502abe2ab9eff8bd5e4aca274da8d06dd3ef08b759a8d6143f4ad65d4b4", size = 4141900, upload-time = "2025-09-01T11:14:45.089Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/b9/e96e0b6cb86eae27ea51fa8a3151535a18e66fe7c451fa90f7f89c85f541/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:c987dad82e8c65ebc985f5dae5e74a3beda9d0a2a4daf8a1115f3772b59e5141", size = 4375562, upload-time = "2025-09-01T11:14:47.166Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/d0/36e8ee39274e9d77baf7d0dafda680cba6e52f3936b846f0d56d64fec915/cryptography-45.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c13b1e3afd29a5b3b2656257f14669ca8fa8d7956d509926f0b130b600b50ab7", size = 3322781, upload-time = "2025-09-01T11:14:48.747Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/99/4e/49199a4c82946938a3e05d2e8ad9482484ba48bbc1e809e3d506c686d051/cryptography-45.0.7-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a862753b36620af6fc54209264f92c716367f2f0ff4624952276a6bbd18cbde", size = 3584634, upload-time = "2025-09-01T11:14:50.593Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/ce/5f6ff59ea9c7779dba51b84871c19962529bdcc12e1a6ea172664916c550/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:06ce84dc14df0bf6ea84666f958e6080cdb6fe1231be2a51f3fc1267d9f3fb34", size = 4149533, upload-time = "2025-09-01T11:14:52.091Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ce/13/b3cfbd257ac96da4b88b46372e662009b7a16833bfc5da33bb97dd5631ae/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d0c5c6bac22b177bf8da7435d9d27a6834ee130309749d162b26c3105c0795a9", size = 4385557, upload-time = "2025-09-01T11:14:53.551Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/c5/8c59d6b7c7b439ba4fc8d0cab868027fd095f215031bc123c3a070962912/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:2f641b64acc00811da98df63df7d59fd4706c0df449da71cb7ac39a0732b40ae", size = 4149023, upload-time = "2025-09-01T11:14:55.022Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/55/32/05385c86d6ca9ab0b4d5bb442d2e3d85e727939a11f3e163fc776ce5eb40/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:f5414a788ecc6ee6bc58560e85ca624258a55ca434884445440a810796ea0e0b", size = 4385722, upload-time = "2025-09-01T11:14:57.319Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/23/87/7ce86f3fa14bc11a5a48c30d8103c26e09b6465f8d8e9d74cf7a0714f043/cryptography-45.0.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:1f3d56f73595376f4244646dd5c5870c14c196949807be39e79e7bd9bac3da63", size = 3332908, upload-time = "2025-09-01T11:14:58.78Z" }, +] + [[package]] name = "cssselect" version = "1.3.0" @@ -1088,6 +1204,7 @@ dependencies = [ { name = "aiosqlite" }, { name = "alembic" }, { name = "asyncmy" }, + { name = "cryptography" }, { name = "fastapi" }, { name = "httpx" }, { name = "jieba" }, @@ -1116,6 +1233,7 @@ requires-dist = [ { name = "aiosqlite", specifier = ">=0.21.0" }, { name = "alembic", specifier = ">=1.16.5" }, { name = "asyncmy", specifier = ">=0.2.10" }, + { name = "cryptography", specifier = ">=45.0.7" }, { name = "fastapi", specifier = "==0.110.2" }, { name = "httpx", specifier = "==0.28.1" }, { name = "jieba", specifier = "==0.42.1" }, @@ -1495,6 +1613,15 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/0f/c8dcadb2f0dcfdab6052d5ecf57ccf19b439c0adc29fc510ed0830349345/playwright-1.45.0-py3-none-win_amd64.whl", hash = "sha256:701db496928429aec103739e48e3110806bd5cf49456cc95b89f28e1abda71da", size = 29692683, upload-time = "2024-07-03T10:33:07.171Z" }, ] +[[package]] +name = "pycparser" +version = "2.22" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, +] + [[package]] name = "pydantic" version = "2.5.2"