initial commit
This commit is contained in:
commit
90fe4ac2ad
1
.python-version
Normal file
1
.python-version
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.13
|
12
.vscode/settings.json
vendored
Normal file
12
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"APPLEPAY",
|
||||||
|
"CARDNO",
|
||||||
|
"Comgate",
|
||||||
|
"ESHOP",
|
||||||
|
"GOOGLEPAY",
|
||||||
|
"RDPART",
|
||||||
|
"THIRDPARTY",
|
||||||
|
"THREEDS"
|
||||||
|
]
|
||||||
|
}
|
17
pyproject.toml
Normal file
17
pyproject.toml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[project]
|
||||||
|
name = "comgate"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "A Python Client for Comgate API"
|
||||||
|
readme = "README.md"
|
||||||
|
authors = [
|
||||||
|
{ name = "Radek Goláň jr.", email = "shield@shielddagger.com" }
|
||||||
|
]
|
||||||
|
requires-python = ">=3.13"
|
||||||
|
dependencies = [
|
||||||
|
"pydantic[email]>=2.11.7",
|
||||||
|
"requests>=2.32.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["hatchling"]
|
||||||
|
build-backend = "hatchling.build"
|
12
src/comgate/__init__.py
Normal file
12
src/comgate/__init__.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from .client import Comgate
|
||||||
|
from .models import Category, Country, Currency, Delivery, PaymentRequest, RefundRequest
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Comgate",
|
||||||
|
"Category",
|
||||||
|
"Country",
|
||||||
|
"Currency",
|
||||||
|
"Delivery",
|
||||||
|
"PaymentRequest",
|
||||||
|
"RefundRequest",
|
||||||
|
]
|
64
src/comgate/client.py
Normal file
64
src/comgate/client.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import json
|
||||||
|
import logging
|
||||||
|
from typing import final
|
||||||
|
|
||||||
|
from requests import Session
|
||||||
|
from requests.auth import HTTPBasicAuth
|
||||||
|
|
||||||
|
from .models import Country, Currency, Payment, PaymentMethod, PaymentRequest
|
||||||
|
|
||||||
|
|
||||||
|
@final
|
||||||
|
class Comgate:
|
||||||
|
"""Comgate Payments API Client"""
|
||||||
|
|
||||||
|
def __init__(self, merchant: int, password: str, test: bool = False):
|
||||||
|
"""Create a Comgate API Client
|
||||||
|
|
||||||
|
Args:
|
||||||
|
merchant (int): Merchant Connection ID
|
||||||
|
password (str): Merchant Connection Password
|
||||||
|
test (bool): Configure the client for testing purposes
|
||||||
|
"""
|
||||||
|
self.session = Session()
|
||||||
|
self.session.auth = HTTPBasicAuth(str(merchant), password)
|
||||||
|
self.test = test
|
||||||
|
|
||||||
|
self.base_url = "https://payments.comgate.cz"
|
||||||
|
self.create_endpoint = "/v2.0/payment.json"
|
||||||
|
self.payment_endpoint = "/v2.0/payment/transId/%s.json"
|
||||||
|
self.refund_endpoint = "/v2.0/refund.json"
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self,
|
||||||
|
country: Country,
|
||||||
|
price: int,
|
||||||
|
currency: Currency,
|
||||||
|
label: str,
|
||||||
|
refId: str,
|
||||||
|
fullName: str,
|
||||||
|
email: str | None = None,
|
||||||
|
phone: str | None = None,
|
||||||
|
method: PaymentMethod = PaymentMethod.ALL,
|
||||||
|
**kwargs, # pyright: ignore[reportMissingParameterType, reportUnknownParameterType]
|
||||||
|
) -> Payment:
|
||||||
|
request = PaymentRequest(
|
||||||
|
test=self.test,
|
||||||
|
country=country,
|
||||||
|
price=price * 100,
|
||||||
|
curr=currency,
|
||||||
|
label=label,
|
||||||
|
refId=refId,
|
||||||
|
fullName=fullName,
|
||||||
|
email=email,
|
||||||
|
phone=phone,
|
||||||
|
method=method,
|
||||||
|
**kwargs, # pyright: ignore[reportUnknownArgumentType]
|
||||||
|
)
|
||||||
|
response = self.session.post(
|
||||||
|
self.base_url + self.create_endpoint,
|
||||||
|
json=json.loads(request.model_dump_json()), # pyright: ignore[reportAny]
|
||||||
|
)
|
||||||
|
if not response.ok:
|
||||||
|
logging.root.error("Failed Comgate Request: %s", request.model_dump_json())
|
||||||
|
return Payment.model_validate_json(response.content)
|
281
src/comgate/models.py
Normal file
281
src/comgate/models.py
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
from enum import Enum, IntEnum
|
||||||
|
import sys
|
||||||
|
from pydantic import BaseModel, EmailStr, HttpUrl, Field, model_validator
|
||||||
|
|
||||||
|
|
||||||
|
class Country(Enum):
|
||||||
|
ALL = "ALL"
|
||||||
|
AT = "AT"
|
||||||
|
BE = "BE"
|
||||||
|
CY = "CY"
|
||||||
|
CZ = "CZ"
|
||||||
|
DE = "DE"
|
||||||
|
EE = "EE"
|
||||||
|
EL = "EL"
|
||||||
|
ES = "ES"
|
||||||
|
FI = "FI"
|
||||||
|
FR = "FR"
|
||||||
|
GB = "GB"
|
||||||
|
HR = "HR"
|
||||||
|
HU = "HU"
|
||||||
|
IE = "IE"
|
||||||
|
IT = "IT"
|
||||||
|
LT = "LT"
|
||||||
|
LU = "LU"
|
||||||
|
LV = "LV"
|
||||||
|
MT = "MT"
|
||||||
|
NL = "NL"
|
||||||
|
NO = "NO"
|
||||||
|
PL = "PL"
|
||||||
|
PT = "PT"
|
||||||
|
RO = "RO"
|
||||||
|
SI = "SI"
|
||||||
|
SK = "SK"
|
||||||
|
SE = "SE"
|
||||||
|
US = "US"
|
||||||
|
|
||||||
|
|
||||||
|
class Currency(Enum):
|
||||||
|
CZK = "CZK"
|
||||||
|
EUR = "EUR"
|
||||||
|
PLN = "PLN"
|
||||||
|
HUF = "HUF"
|
||||||
|
USD = "USD"
|
||||||
|
GBP = "GBP"
|
||||||
|
RON = "RON"
|
||||||
|
HRK = "HRK"
|
||||||
|
NOK = "NOK"
|
||||||
|
SEK = "SEK"
|
||||||
|
|
||||||
|
|
||||||
|
PRICE_RANGE = {
|
||||||
|
Currency.CZK: (1_00, 1_000_000_00),
|
||||||
|
Currency.EUR: (10, 40_000_00),
|
||||||
|
Currency.PLN: (1_00, 170_000_00),
|
||||||
|
Currency.HUF: (100_00, 12_500_000_00),
|
||||||
|
Currency.USD: (1_00, 45_000_00),
|
||||||
|
Currency.GBP: (1_00, 35_000_00),
|
||||||
|
Currency.RON: (5_00, 190_000_00),
|
||||||
|
Currency.HRK: (
|
||||||
|
1_00,
|
||||||
|
sys.maxsize,
|
||||||
|
), # HACK: This seems like a doc gaffe. We don't have a value so we just use maxsize, but it's probably much lower than that
|
||||||
|
Currency.NOK: (50, 400_000_00),
|
||||||
|
Currency.SEK: (50, 390_000_00),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class PaymentMethod(Enum):
|
||||||
|
ALL = "ALL"
|
||||||
|
BANK_ALL = "BANK_ALL"
|
||||||
|
BANK_ONLY = "BANK_ONLY"
|
||||||
|
CARD_ALL = "CARD_ALL"
|
||||||
|
LATER_ALL = "LATER_ALL"
|
||||||
|
LOAN_ALL = "LOAN_ALL"
|
||||||
|
PART_ALL = "PART_ALL"
|
||||||
|
APPLEPAY_REDIRECT = "APPLEPAY_REDIRECT"
|
||||||
|
GOOGLEPAY_REDIRECT = "GOOGLEPAY_REDIRECT"
|
||||||
|
|
||||||
|
|
||||||
|
class Delivery(Enum):
|
||||||
|
HOME_DELIVERY = "HOME_DELIVERY"
|
||||||
|
PICKUP = "PICKUP"
|
||||||
|
ELECTRONIC_DELIVERY = "ELECTRONIC_DELIVERY"
|
||||||
|
|
||||||
|
|
||||||
|
class Category(Enum):
|
||||||
|
PHYSICAL_GOODS_ONLY = "PHYSICAL_GOODS_ONLY"
|
||||||
|
OTHER = "OTHER"
|
||||||
|
|
||||||
|
|
||||||
|
class PaymentRequest(BaseModel):
|
||||||
|
test: bool = False
|
||||||
|
country: Country = Country.CZ
|
||||||
|
price: int
|
||||||
|
curr: Currency
|
||||||
|
label: str = Field(max_length=16, min_length=1)
|
||||||
|
refId: str
|
||||||
|
method: PaymentMethod
|
||||||
|
account: str | None = None
|
||||||
|
|
||||||
|
email: EmailStr | None = None
|
||||||
|
phone: str | None = None
|
||||||
|
|
||||||
|
fullName: str
|
||||||
|
|
||||||
|
billingAddrCity: str | None = None
|
||||||
|
billingAddrStreet: str | None = None
|
||||||
|
billingAddrPostalCode: str | None = None
|
||||||
|
billingAddrCountry: str | None = None
|
||||||
|
|
||||||
|
homeDeliveryCity: str | None = None
|
||||||
|
homeDeliveryStreet: str | None = None
|
||||||
|
homeDeliveryPostalCode: str | None = None
|
||||||
|
homeDeliveryCountry: str | None = None
|
||||||
|
|
||||||
|
category: Category | None = None
|
||||||
|
name: str | None = None
|
||||||
|
lang: str | None = "en"
|
||||||
|
preauth: bool = False
|
||||||
|
initRecurring: bool = False
|
||||||
|
verification: bool = False
|
||||||
|
|
||||||
|
expirationTime: str | None = Field(default=None, pattern=r"^[1-9][0-9]*(m|h|d)$")
|
||||||
|
dynamicExpiration: bool = True
|
||||||
|
|
||||||
|
url_paid: str | None = None
|
||||||
|
url_cancelled: str | None = None
|
||||||
|
url_pending: str | None = None
|
||||||
|
chargeUnregulatedCardFees: bool | None = None
|
||||||
|
enableApplePayGooglePay: bool | None = None
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def _check_price(self):
|
||||||
|
v_min, v_max = PRICE_RANGE[self.curr]
|
||||||
|
if self.price not in range(v_min, v_max):
|
||||||
|
raise ValueError(
|
||||||
|
f"Unsupported price value: {self.price}, it must be between {v_min} amd {v_max}"
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def _check_contact(self):
|
||||||
|
if self.phone is None and self.email is None:
|
||||||
|
raise ValueError("At least phone or email must be provided")
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class PaymentCode(IntEnum):
|
||||||
|
OK = 0
|
||||||
|
UNKNOWN_ERROR = 1100
|
||||||
|
UNSUPPORTED_LANGUAGE = 1102
|
||||||
|
INCORRECT_METHOD = 1103
|
||||||
|
PAYMENT_LOAD_ERROR = 1104
|
||||||
|
UNSUPPORTED_PRICE = 1107
|
||||||
|
DATABASE_ERROR = 1200
|
||||||
|
UNKNOWN_STORE = 1301
|
||||||
|
MISSING_LINK_LANG = 1303
|
||||||
|
INVALID_CATEGORY = 1304
|
||||||
|
MISSING_PRODUCT_DESC = 1305
|
||||||
|
CHANGE_METHOD = 1306
|
||||||
|
METHOD_NOT_ALLOWED = 1308
|
||||||
|
WRONG_AMOUNT = 1309
|
||||||
|
UNKNOWN_CURRENCY = 1310
|
||||||
|
INVALID_BANK_ID = 1311
|
||||||
|
RECURRING_UNAVAILABLE = 1316
|
||||||
|
RECURRING_UNSUPPORTED = 1317
|
||||||
|
PAYMENT_SETUP_ERROR = 1319
|
||||||
|
UNEXPECTED_DB_RESULT = 1399
|
||||||
|
BAD_REQUEST = 1400
|
||||||
|
UNEXPECTED_ERROR = 1500
|
||||||
|
|
||||||
|
|
||||||
|
class Payment(BaseModel):
|
||||||
|
code: PaymentCode
|
||||||
|
message: str
|
||||||
|
transId: str | None = None
|
||||||
|
redirect: HttpUrl | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class CancellationCode(IntEnum):
|
||||||
|
OK = 0
|
||||||
|
CANNOT_CANCEL = 1400
|
||||||
|
|
||||||
|
|
||||||
|
class Cancellation(BaseModel):
|
||||||
|
code: CancellationCode
|
||||||
|
message: str
|
||||||
|
|
||||||
|
|
||||||
|
class StatusCode(IntEnum):
|
||||||
|
OK = 0
|
||||||
|
UNKNOWN_ERROR = 1100
|
||||||
|
DATABASE_ERROR = 1200
|
||||||
|
WRONG_QUERY = 1400
|
||||||
|
UNEXPECTED_ERROR = 1500
|
||||||
|
|
||||||
|
|
||||||
|
class PaymentStatus(Enum):
|
||||||
|
PENDING = "PENDING"
|
||||||
|
PAID = "PAID"
|
||||||
|
CANCELLED = "CANCELLED"
|
||||||
|
AUTHORIZED = "AUTHORIZED"
|
||||||
|
|
||||||
|
|
||||||
|
class FeeType(Enum):
|
||||||
|
EU_UNREGULATED = "EU_UNREGULATED"
|
||||||
|
NON_EU_BUSINESS = "NON_EU_BUSINESS"
|
||||||
|
NON_EU_CONSUMER = "NON_EU_CONSUMER"
|
||||||
|
EU_CONSUMER = "EU_CONSUMER"
|
||||||
|
|
||||||
|
|
||||||
|
class PaymentErrReason(Enum):
|
||||||
|
CUSTOMER_CLICK = "CUSTOMER_CLICK"
|
||||||
|
FRAUD_SUSPECTED = "FRAUD_SUSPECTED"
|
||||||
|
ESHOP_CANCELLED = "ESHOP_CANCELLED"
|
||||||
|
PROVIDER_REPORT = "PROVIDER_REPORT"
|
||||||
|
PROVIDER_TIMEOUT = "PROVIDER_TIMEOUT"
|
||||||
|
CUSTOMER_TIMEOUT = "CUSTOMER_TIMEOUT"
|
||||||
|
ACS_TIMEOUT = "ACS_TIMEOUT"
|
||||||
|
INVALID_CARDNO_EXPIRY = "INVALID_CARDNO_EXPIRY"
|
||||||
|
INVALID_CVC = "INVALID_CVC"
|
||||||
|
LIMIT_EXCEEDED = "LIMIT_EXCEEDED"
|
||||||
|
NO_FUNDS = "NO_FUNDS"
|
||||||
|
REJECTED_BY_BANK = "REJECTED_BY_BANK"
|
||||||
|
THREEDS_AUTH_FAIL = "3DS_AUTH_FAIL"
|
||||||
|
BANK_TIMEOUT = "BANK_TIMEOUT"
|
||||||
|
BANK_FORBIDDEN = "BANK_FORBIDDEN"
|
||||||
|
TRANSACTION_CANCELLED = "TRANSACTION_CANCELLED"
|
||||||
|
THIRDPARTY_APP_LIMIT_EXCEEDED = "3RDPART_APP_LIMIT_EXCEEDED"
|
||||||
|
UNAVAILABLE = "UNAVAILABLE"
|
||||||
|
BAD_ACCOUNT_TYPE = "BAD_ACCOUNT_TYPE"
|
||||||
|
NOT_SPECIFIED = "NOT_SPECIFIED"
|
||||||
|
|
||||||
|
|
||||||
|
class Status(BaseModel):
|
||||||
|
code: StatusCode
|
||||||
|
message: str
|
||||||
|
test: bool
|
||||||
|
price: int
|
||||||
|
curr: Currency
|
||||||
|
label: str
|
||||||
|
refId: str
|
||||||
|
payerId: str | None = None
|
||||||
|
method: PaymentMethod | None = None
|
||||||
|
account: str | None = None
|
||||||
|
email: EmailStr
|
||||||
|
name: str | None = None
|
||||||
|
phone: str | None = None
|
||||||
|
transId: str
|
||||||
|
status: PaymentStatus
|
||||||
|
payerName: str | None = None
|
||||||
|
payerAcc: str | None = None
|
||||||
|
fee: str | None = None
|
||||||
|
vs: str | None = None
|
||||||
|
cardValid: str | None = None
|
||||||
|
cardNumber: str | None = None
|
||||||
|
appliedFee: int | None = None
|
||||||
|
appliedFeeType: FeeType | None = None
|
||||||
|
paymentErrorReason: PaymentErrReason | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class RefundRequest(BaseModel):
|
||||||
|
transId: str
|
||||||
|
amount: int
|
||||||
|
test: bool = False
|
||||||
|
refId: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class RefundCode(IntEnum):
|
||||||
|
OK = 0
|
||||||
|
UNKNOWN_ERROR = 1100
|
||||||
|
DATABASE_ERROR = 1200
|
||||||
|
WRONG_QUERY = 1400
|
||||||
|
PAYMENT_CANCELLED = 1401
|
||||||
|
AMOUNT_TOO_HIGH = 1402
|
||||||
|
UNEXPECTED_ERROR = 1500
|
||||||
|
|
||||||
|
|
||||||
|
class Refund(BaseModel):
|
||||||
|
code: RefundCode
|
||||||
|
message: str
|
0
src/comgate/py.typed
Normal file
0
src/comgate/py.typed
Normal file
181
uv.lock
generated
Normal file
181
uv.lock
generated
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
version = 1
|
||||||
|
requires-python = ">=3.13"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "annotated-types"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "certifi"
|
||||||
|
version = "2025.7.14"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/b3/76/52c535bcebe74590f296d6c77c86dabf761c41980e1347a2422e4aa2ae41/certifi-2025.7.14.tar.gz", hash = "sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995", size = 163981 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2", size = 162722 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "charset-normalizer"
|
||||||
|
version = "3.4.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "comgate"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = { editable = "." }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "pydantic", extra = ["email"] },
|
||||||
|
{ name = "requests" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [
|
||||||
|
{ name = "pydantic", extras = ["email"], specifier = ">=2.11.7" },
|
||||||
|
{ name = "requests", specifier = ">=2.32.4" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dnspython"
|
||||||
|
version = "2.7.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/b5/4a/263763cb2ba3816dd94b08ad3a33d5fdae34ecb856678773cc40a3605829/dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1", size = 345197 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "email-validator"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "dnspython" },
|
||||||
|
{ name = "idna" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "3.10"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pydantic"
|
||||||
|
version = "2.11.7"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "annotated-types" },
|
||||||
|
{ name = "pydantic-core" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
{ name = "typing-inspection" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.optional-dependencies]
|
||||||
|
email = [
|
||||||
|
{ name = "email-validator" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pydantic-core"
|
||||||
|
version = "2.33.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "requests"
|
||||||
|
version = "2.32.4"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "certifi" },
|
||||||
|
{ name = "charset-normalizer" },
|
||||||
|
{ name = "idna" },
|
||||||
|
{ name = "urllib3" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-extensions"
|
||||||
|
version = "4.14.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-inspection"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "urllib3"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795 },
|
||||||
|
]
|
Loading…
x
Reference in New Issue
Block a user