From 7ba6a32015cfe477ed1010ec0f8974c5ace64a3b Mon Sep 17 00:00:00 2001 From: SerinaNya <34389622+SerinaNya@users.noreply.github.com> Date: Mon, 22 Jun 2026 23:58:01 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20init?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/fluxent/.gitignore | 10 + packages/fluxent/.python-version | 1 + packages/fluxent/README.md | 0 packages/fluxent/main.py | 6 + packages/fluxent/models/__init__.py | 0 packages/fluxent/models/account.py | 74 ++++++++ packages/fluxent/models/channel.py | 93 ++++++++++ packages/fluxent/models/ref.py | 31 ++++ packages/fluxent/models/transaction.py | 187 +++++++++++++++++++ packages/fluxent/pyproject.toml | 25 +++ packages/fluxent/uv.lock | 243 +++++++++++++++++++++++++ 11 files changed, 670 insertions(+) create mode 100644 packages/fluxent/.gitignore create mode 100644 packages/fluxent/.python-version create mode 100644 packages/fluxent/README.md create mode 100644 packages/fluxent/main.py create mode 100644 packages/fluxent/models/__init__.py create mode 100644 packages/fluxent/models/account.py create mode 100644 packages/fluxent/models/channel.py create mode 100644 packages/fluxent/models/ref.py create mode 100644 packages/fluxent/models/transaction.py create mode 100644 packages/fluxent/pyproject.toml create mode 100644 packages/fluxent/uv.lock diff --git a/packages/fluxent/.gitignore b/packages/fluxent/.gitignore new file mode 100644 index 0000000..505a3b1 --- /dev/null +++ b/packages/fluxent/.gitignore @@ -0,0 +1,10 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv diff --git a/packages/fluxent/.python-version b/packages/fluxent/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/packages/fluxent/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/packages/fluxent/README.md b/packages/fluxent/README.md new file mode 100644 index 0000000..e69de29 diff --git a/packages/fluxent/main.py b/packages/fluxent/main.py new file mode 100644 index 0000000..249a293 --- /dev/null +++ b/packages/fluxent/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from fluxent!") + + +if __name__ == "__main__": + main() diff --git a/packages/fluxent/models/__init__.py b/packages/fluxent/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/packages/fluxent/models/account.py b/packages/fluxent/models/account.py new file mode 100644 index 0000000..199da48 --- /dev/null +++ b/packages/fluxent/models/account.py @@ -0,0 +1,74 @@ +from __future__ import annotations + +from datetime import UTC, datetime +from enum import StrEnum +from typing import Annotated, Literal + +from annotated_types import MinLen +from pydantic import BaseModel, Field +from pydantic_extra_types.currency_code import Currency +from ulid import ULID + +from .ref import AccountRef + + +class AccountType(StrEnum): + """资金性质""" + + ASSET = "ASSET" + LIABILITY = "LIABILITY" + EQUITY = "EQUITY" + + +class BaseAccount(BaseModel): + """基础账户模型""" + + id: ULID = Field(default_factory=ULID) + name: Annotated[str, "用户自定义名称", MinLen(1)] + account_type: AccountType + primary_currency: Annotated[Currency | None, "主币种(可选)", Field(default=None)] + supported_currencies: Annotated[ + list[Currency] | None, "支持的币种列表(None=全币种)", Field(default=None) + ] + is_active: Annotated[bool, "是否启用", Field(default=True)] + remark: Annotated[str | None, "备注", Field(default=None)] + created_at: Annotated[datetime, "创建时间", Field(default_factory=lambda: datetime.now(UTC))] + updated_at: Annotated[datetime, "更新时间", Field(default_factory=lambda: datetime.now(UTC))] + deleted_at: Annotated[datetime | None, "软删除时间(None=未删除)", Field(default=None)] + + +class BankAccount(BaseAccount): + """银行账户""" + + account_type: Literal[AccountType.ASSET, AccountType.LIABILITY] = AccountType.ASSET + issuer_name: Annotated[str, "银行名称", MinLen(1)] + account_number: Annotated[str | None, "完整账户号(敏感信息)", Field(default=None)] + account_suffix: Annotated[ + str | None, "账户号末尾部分,用于识别", MinLen(1), Field(default=None) + ] + sub_accounts: Annotated[list[AccountRef], "子账户引用", Field(default_factory=list)] + + +class EWalletAccount(BaseAccount): + """电子钱包账户""" + + account_type: Literal[AccountType.ASSET] = AccountType.ASSET + platform: Annotated[ + str, + "平台名称: Alipay/WeChat/PayMe/AlipayHK/MPay/Octopus/Tap&Go/AlipayMO", + MinLen(1), + ] + account_id: Annotated[str | None, "平台账户ID", Field(default=None)] + + +class CashAccount(BaseAccount): + """现金账户""" + + account_type: Literal[AccountType.ASSET] = AccountType.ASSET + location: Annotated[str | None, "存放位置描述", Field(default=None)] + + +type Account = Annotated[ + BankAccount | EWalletAccount | CashAccount, + Field(discriminator="account_type"), +] diff --git a/packages/fluxent/models/channel.py b/packages/fluxent/models/channel.py new file mode 100644 index 0000000..c63f887 --- /dev/null +++ b/packages/fluxent/models/channel.py @@ -0,0 +1,93 @@ +from __future__ import annotations + +from datetime import UTC, datetime +from enum import StrEnum +from typing import Annotated + +from annotated_types import MinLen +from pydantic import BaseModel, Field +from pydantic_extra_types.country import CountryAlpha2 +from ulid import ULID + +from .ref import AccountRef + + +class ChannelType(StrEnum): + """渠道类型""" + + PAYMENT_CARD = "PAYMENT_CARD" + E_WALLET = "E_WALLET" + CASH = "CASH" + + +class PaymentInstrumentType(StrEnum): + """支付工具类型""" + + CREDIT = "CREDIT" + DEBIT = "DEBIT" + + # 暂无实现的必要 + # PREPAID = "PREPAID" + # BNPL = "BNPL" + # CONSUMER_LOAN = "CONSUMER_LOAN" + + +class BaseChannel(BaseModel): + """基础渠道模型""" + + id: ULID = Field(default_factory=ULID) + ref_accounts: Annotated[list[AccountRef], "关联的账户引用列表", MinLen(1)] + created_at: Annotated[datetime, "创建时间", Field(default_factory=lambda: datetime.now(UTC))] + updated_at: Annotated[datetime, "更新时间", Field(default_factory=lambda: datetime.now(UTC))] + deleted_at: Annotated[datetime | None, "软删除时间(None=未删除)", Field(default=None)] + + +class PaymentCardChannel(BaseChannel): + """支付卡渠道""" + + channel_type = ChannelType.PAYMENT_CARD + region: Annotated[CountryAlpha2, "发卡地/清算区域"] + issuer_name: Annotated[str, "发卡方名称", MinLen(1)] + card_type: Annotated[PaymentInstrumentType, "卡类型"] + card_suffix: Annotated[str, "卡号末尾部分,可为后4/5位或完整卡号", MinLen(1)] + card_brand: Annotated[ + str | None, + "卡组织: UnionPay/Visa/Mastercard/JCB/AMEX/Octopus。通常可由完整卡号自动推断", + Field(default=None), + ] + + +class EWalletChannel(BaseChannel): + """电子钱包渠道""" + + channel_type = ChannelType.E_WALLET + region: Annotated[CountryAlpha2, "钱包所属区域"] + platform: Annotated[ + str, + "平台名: Alipay/WeChatPay/PayMe/AlipayHK/MPay/Octopus/AlipayMO", + MinLen(1), + ] + platform_account_id: Annotated[str | None, "平台账户ID/手机号掩码", Field(default=None)] + + sub_channel: Annotated[ + str | None, "子渠道: 余额/花呗/信用卡快捷/八达通App等", Field(default=None) + ] + sub_channel_type: Annotated[PaymentInstrumentType, "子渠道类型"] + + +class CashChannel(BaseChannel): + """现金渠道""" + + channel_type = ChannelType.CASH + + +class TransferChannel(BaseChannel): + """转账渠道""" + + channel_type = ChannelType.TRANSFER + + +type Channel = Annotated[ + PaymentCardChannel | EWalletChannel | CashChannel, + Field(discriminator="channel_type"), +] diff --git a/packages/fluxent/models/ref.py b/packages/fluxent/models/ref.py new file mode 100644 index 0000000..8592cd1 --- /dev/null +++ b/packages/fluxent/models/ref.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +from typing import Literal + +from pydantic import BaseModel +from ulid import ULID + + +class BaseRef(BaseModel): + """基础引用模型""" + + ref_type: str + ref_id: ULID + + +class AccountRef(BaseRef): + """账户引用""" + + ref_type: Literal["ACCOUNT"] = "ACCOUNT" + + +class ChannelRef(BaseRef): + """渠道引用""" + + ref_type: Literal["CHANNEL"] = "CHANNEL" + + +class TransactionRef(BaseRef): + """交易引用""" + + ref_type: Literal["TRANSACTION"] = "TRANSACTION" diff --git a/packages/fluxent/models/transaction.py b/packages/fluxent/models/transaction.py new file mode 100644 index 0000000..3ad4eb7 --- /dev/null +++ b/packages/fluxent/models/transaction.py @@ -0,0 +1,187 @@ +from datetime import UTC, datetime +from decimal import Decimal +from enum import StrEnum +from typing import Annotated, Self + +from pydantic import BaseModel, Field, model_validator +from pydantic_extra_types.country import CountryAlpha2 +from pydantic_extra_types.currency_code import Currency +from ulid import ULID + +from .ref import ChannelRef, TransactionRef + + +class TransactionStatus(StrEnum): + """交易状态""" + + PENDING = "PENDING" + COMPLETED = "COMPLETED" + FAILED = "FAILED" + REFUNDED = "REFUNDED" + + +class DcFlag(StrEnum): + """借贷方向""" + + DEBIT = "DEBIT" + CREDIT = "CREDIT" + + +class FxRate(BaseModel): + """汇率快照""" + + from_ccy: Annotated[Currency, "源币种"] + to_ccy: Annotated[Currency, "目标币种"] + rate: Annotated[Decimal, "汇率"] + + +class BaseTransaction(BaseModel): + """基础交易模型""" + + id: ULID = Field(default_factory=ULID) + version: Annotated[int, "乐观锁版本号", Field(default=0)] + ref_transactions: Annotated[ + list[TransactionRef], "关联的交易引用列表", Field(default_factory=list) + ] + txn_date: Annotated[datetime, "交易日期"] + clearing_date: Annotated[datetime | None, "清算日期", Field(default=None)] + posting_date: Annotated[datetime | None, "入账日期", Field(default=None)] + created_at: Annotated[datetime, "创建时间", Field(default_factory=lambda: datetime.now(UTC))] + updated_at: Annotated[datetime, "更新时间", Field(default_factory=lambda: datetime.now(UTC))] + deleted_at: Annotated[datetime | None, "软删除时间(None=未删除)", Field(default=None)] + txn_amt: Annotated[Decimal, "交易金额"] + txn_ccy: Annotated[Currency, "交易币种"] + posting_amt: Annotated[Decimal | None, "入账金额", Field(default=None)] + posting_ccy: Annotated[Currency | None, "入账币种", Field(default=None)] + comm_amt: Annotated[Decimal | None, "手续费金额", Field(default=None)] + comm_ccy: Annotated[Currency | None, "手续费币种", Field(default=None)] + surcharge_amt: Annotated[Decimal | None, "服务费金额", Field(default=None)] + surcharge_ccy: Annotated[Currency | None, "服务费币种", Field(default=None)] + disc_amt: Annotated[Decimal | None, "折扣金额", Field(default=None)] + disc_ccy: Annotated[Currency | None, "折扣币种", Field(default=None)] + fx_rates: Annotated[list[FxRate] | None, "汇率快照列表", Field(default=None)] + dc_flag: Annotated[DcFlag, "借贷方向"] + ref_channel: Annotated[ChannelRef, "关联的渠道引用列表"] + cp: Annotated[str | ChannelRef, "对手方(字符串描述或渠道引用)"] + acq_inst: Annotated[str | None, "收单机构", Field(default=None)] + clearing_network: Annotated[str | None, "清算网络", Field(default=None)] + txn_sts: Annotated[TransactionStatus, "交易状态", Field(default=TransactionStatus.COMPLETED)] + description: Annotated[str | None, "交易描述", Field(default=None)] + memo: Annotated[str | None, "备注", Field(default=None)] + raw_description: Annotated[str | None, "原始交易描述", Field(default=None)] + raw_data: Annotated[dict | None, "原始数据", Field(default=None)] + + txn_scene: Annotated[str | None, "交易场景", Field(default=None)] + + @model_validator(mode="after") + def _validate_amt_ccy_pairs(self) -> Self: + pairs = [ + ("posting_amt", "posting_ccy"), + ("comm_amt", "comm_ccy"), + ("surcharge_amt", "surcharge_ccy"), + ("disc_amt", "disc_ccy"), + ] + for amt_field, ccy_field in pairs: + amt = getattr(self, amt_field) + ccy = getattr(self, ccy_field) + if (amt is None) != (ccy is None): + msg = f"{amt_field} and {ccy_field} must both be None or both have values" + raise ValueError(msg) + return self + + @model_validator(mode="after") + def _validate_accounting_equation(self) -> Self: + """ + 会计恒等式校验(同币种) + + - CREDIT: posting_amt = txn_amt + surcharge_amt - comm_amt - disc_amt + - DEBIT: posting_amt = txn_amt + surcharge_amt + comm_amt - disc_amt + """ + if self.posting_amt is None or self.posting_ccy != self.txn_ccy: + return self + + expected = self.txn_amt + if self.surcharge_amt is not None and self.surcharge_ccy == self.txn_ccy: + expected += self.surcharge_amt + if self.disc_amt is not None and self.disc_ccy == self.txn_ccy: + expected -= self.disc_amt + + if self.dc_flag == DcFlag.CREDIT: + if self.comm_amt is not None and self.comm_ccy == self.txn_ccy: + expected -= self.comm_amt + elif self.dc_flag == DcFlag.DEBIT: + if self.comm_amt is not None and self.comm_ccy == self.txn_ccy: + expected += self.comm_amt + + if self.posting_amt != expected: + msg = ( + f"Accounting equation mismatch ({self.dc_flag.value}): " + f"posting_amt({self.posting_amt}) != " + f"txn_amt({self.txn_amt}) + surcharge_amt({self.surcharge_amt})" + f" {'+' if self.dc_flag == DcFlag.DEBIT else '-'} comm_amt({self.comm_amt})" + f" - disc_amt({self.disc_amt})" + ) + raise ValueError(msg) + return self + + +class MiscInTransaction(BaseTransaction): + """其他收入交易""" + + txn_scene = "MISC_IN" + + +class MiscOutTransaction(BaseTransaction): + """其他支出交易""" + + txn_scene = "MISC_OUT" + + +class PaymentTransaction(MiscOutTransaction): + """支付交易""" + + txn_scene = "PAYMENT" + merchant_name: Annotated[str | None, "商户名称", Field(default=None)] + + +class EcomPaymentTransaction(PaymentTransaction): + """电子商务支付交易""" + + txn_scene = "ECOM_PAYMENT" + order_id: Annotated[str | None, "订单ID", Field(default=None)] + + +class PosPaymentTransaction(PaymentTransaction): + """POS支付交易""" + + txn_scene = "POS_PAYMENT" + geo: Annotated[ + tuple[CountryAlpha2] | tuple[CountryAlpha2, str] | None, "地理信息", Field(default=None) + ] + + +class ATMTransaction(BaseTransaction): + """ATM交易""" + + txn_scene = "ATM" + geo: Annotated[ + tuple[CountryAlpha2] | tuple[CountryAlpha2, str] | None, "地理信息", Field(default=None) + ] + + +class TransferTransaction(BaseTransaction): + """转账交易""" + + txn_scene = "TRANSFER" + + +type Transaction = Annotated[ + MiscInTransaction + | MiscOutTransaction + | TransferTransaction + | PaymentTransaction + | EcomPaymentTransaction + | PosPaymentTransaction + | ATMTransaction, + Field(discriminator="txn_scene"), +] diff --git a/packages/fluxent/pyproject.toml b/packages/fluxent/pyproject.toml new file mode 100644 index 0000000..62962b9 --- /dev/null +++ b/packages/fluxent/pyproject.toml @@ -0,0 +1,25 @@ +[project] +name = "fluxent" +version = "0.1.0" +description = "Trace the cost within every flow." +requires-python = ">=3.12" +dependencies = [ + "pycountry>=26.2.16", + "pydantic>=2.13.4", + "pydantic-extra-types>=2.11.1", + "python-ulid[pydantic]>=3.1.0", +] + + +[dependency-groups] +dev = [ + "pytest>=9.1.1", +] + +[tool.pytest.ini_options] +pythonpath = ["."] +testpaths = ["tests"] + +[tool.ruff] +target-version = "py312" +line-length = 100 diff --git a/packages/fluxent/uv.lock b/packages/fluxent/uv.lock new file mode 100644 index 0000000..5fc3ff2 --- /dev/null +++ b/packages/fluxent/uv.lock @@ -0,0 +1,243 @@ +version = 1 +revision = 1 +requires-python = ">=3.12" + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" }, +] + +[[package]] +name = "fluxent" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "pycountry" }, + { name = "pydantic" }, + { name = "pydantic-extra-types" }, + { name = "python-ulid", extra = ["pydantic"] }, +] + +[package.dev-dependencies] +dev = [ + { name = "pytest" }, +] + +[package.metadata] +requires-dist = [ + { name = "pycountry", specifier = ">=26.2.16" }, + { name = "pydantic", specifier = ">=2.13.4" }, + { name = "pydantic-extra-types", specifier = ">=2.11.1" }, + { name = "python-ulid", extras = ["pydantic"], specifier = ">=3.1.0" }, +] + +[package.metadata.requires-dev] +dev = [{ name = "pytest", specifier = ">=9.1.1" }] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" }, +] + +[[package]] +name = "pycountry" +version = "26.2.16" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/de/1d/061b9e7a48b85cfd69f33c33d2ef784a531c359399ad764243399673c8f5/pycountry-26.2.16.tar.gz", hash = "sha256:5b6027d453fcd6060112b951dd010f01f168b51b4bf8a1f1fc8c95c8d94a0801" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/9c/42/7703bd45b62fecd44cd7d3495423097e2f7d28bc2e99e7c1af68892ab157/pycountry-26.2.16-py3-none-any.whl", hash = "sha256:115c4baf7cceaa30f59a4694d79483c9167dbce7a9de4d3d571c5f3ea77c305a" }, +] + +[[package]] +name = "pydantic" +version = "2.13.4" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.4" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464 } +wheels = [ + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624 }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325 }, +] + +[[package]] +name = "pydantic-extra-types" +version = "2.11.1" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/66/71/dba38ee2651f84f7842206adbd2233d8bbdb59fb85e9fa14232486a8c471/pydantic_extra_types-2.11.1.tar.gz", hash = "sha256:46792d2307383859e923d8fcefa82108b1a141f8a9c0198982b3832ab5ef1049" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/17/c1/3226e6d7f5a4f736f38ac11a6fbb262d701889802595cdb0f53a885ac2e0/pydantic_extra_types-2.11.1-py3-none-any.whl", hash = "sha256:1722ea2bddae5628ace25f2aa685b69978ef533123e5638cfbddb999e0100ec1" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c" }, +] + +[[package]] +name = "python-ulid" +version = "3.1.0" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/40/7e/0d6c82b5ccc71e7c833aed43d9e8468e1f2ff0be1b3f657a6fcafbb8433d/python_ulid-3.1.0.tar.gz", hash = "sha256:ff0410a598bc5f6b01b602851a3296ede6f91389f913a5d5f8c496003836f636" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/6c/a0/4ed6632b70a52de845df056654162acdebaf97c20e3212c559ac43e7216e/python_ulid-3.1.0-py3-none-any.whl", hash = "sha256:e2cdc979c8c877029b4b7a38a6fba3bc4578e4f109a308419ff4d3ccf0a46619" }, +] + +[package.optional-dependencies] +pydantic = [ + { name = "pydantic" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://mirror.sjtu.edu.cn/pypi/web/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://mirror.sjtu.edu.cn/pypi-packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464" } +wheels = [ + { url = "https://mirror.sjtu.edu.cn/pypi-packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7" }, +]