From 413bb22511b1f28190eae3da910bac35fb1de841 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 19:13:18 +0000 Subject: [PATCH 01/30] feat: generate more types that are used as request bodies (#649) --- src/lithic/types/__init__.py | 3 + src/lithic/types/kyb_param.py | 219 +++++++++++++++++++++++++++ src/lithic/types/kyc_exempt_param.py | 48 ++++++ src/lithic/types/kyc_param.py | 75 +++++++++ 4 files changed, 345 insertions(+) create mode 100644 src/lithic/types/kyb_param.py create mode 100644 src/lithic/types/kyc_exempt_param.py create mode 100644 src/lithic/types/kyc_param.py diff --git a/src/lithic/types/__init__.py b/src/lithic/types/__init__.py index a1191ea3..3511a23c 100644 --- a/src/lithic/types/__init__.py +++ b/src/lithic/types/__init__.py @@ -20,6 +20,8 @@ from .balance import Balance as Balance from .dispute import Dispute as Dispute from .payment import Payment as Payment +from .kyb_param import KYBParam as KYBParam +from .kyc_param import KYCParam as KYCParam from .api_status import APIStatus as APIStatus from .owner_type import OwnerType as OwnerType from .transaction import Transaction as Transaction @@ -31,6 +33,7 @@ from .digital_card_art import DigitalCardArt as DigitalCardArt from .dispute_evidence import DisputeEvidence as DisputeEvidence from .external_payment import ExternalPayment as ExternalPayment +from .kyc_exempt_param import KYCExemptParam as KYCExemptParam from .aggregate_balance import AggregateBalance as AggregateBalance from .card_embed_params import CardEmbedParams as CardEmbedParams from .card_renew_params import CardRenewParams as CardRenewParams diff --git a/src/lithic/types/kyb_param.py b/src/lithic/types/kyb_param.py new file mode 100644 index 00000000..31a83080 --- /dev/null +++ b/src/lithic/types/kyb_param.py @@ -0,0 +1,219 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Iterable +from typing_extensions import Literal, Required, TypedDict + +from .shared_params.address import Address + +__all__ = ["KYBParam", "BeneficialOwnerEntity", "BeneficialOwnerIndividual", "BusinessEntity", "ControlPerson"] + + +class BeneficialOwnerEntity(TypedDict, total=False): + address: Required[Address] + """ + Business's physical address - PO boxes, UPS drops, and FedEx drops are not + acceptable; APO/FPO are acceptable. + """ + + government_id: Required[str] + """Government-issued identification number. + + US Federal Employer Identification Numbers (EIN) are currently supported, + entered as full nine-digits, with or without hyphens. + """ + + legal_business_name: Required[str] + """Legal (formal) business name.""" + + phone_numbers: Required[List[str]] + """ + One or more of the business's phone number(s), entered as a list in E.164 + format. + """ + + dba_business_name: str + """ + Any name that the business operates under that is not its legal business name + (if applicable). + """ + + parent_company: str + """Parent company name (if applicable).""" + + +class BeneficialOwnerIndividual(TypedDict, total=False): + address: Required[Address] + """ + Individual's current address - PO boxes, UPS drops, and FedEx drops are not + acceptable; APO/FPO are acceptable. Only USA addresses are currently supported. + """ + + dob: Required[str] + """Individual's date of birth, as an RFC 3339 date.""" + + email: Required[str] + """ + Individual's email address. If utilizing Lithic for chargeback processing, this + customer email address may be used to communicate dispute status and resolution. + """ + + first_name: Required[str] + """Individual's first name, as it appears on government-issued identity documents.""" + + government_id: Required[str] + """ + Government-issued identification number (required for identity verification and + compliance with banking regulations). Social Security Numbers (SSN) and + Individual Taxpayer Identification Numbers (ITIN) are currently supported, + entered as full nine-digits, with or without hyphens + """ + + last_name: Required[str] + """Individual's last name, as it appears on government-issued identity documents.""" + + phone_number: str + """Individual's phone number, entered in E.164 format.""" + + +class BusinessEntity(TypedDict, total=False): + address: Required[Address] + """ + Business's physical address - PO boxes, UPS drops, and FedEx drops are not + acceptable; APO/FPO are acceptable. + """ + + government_id: Required[str] + """Government-issued identification number. + + US Federal Employer Identification Numbers (EIN) are currently supported, + entered as full nine-digits, with or without hyphens. + """ + + legal_business_name: Required[str] + """Legal (formal) business name.""" + + phone_numbers: Required[List[str]] + """ + One or more of the business's phone number(s), entered as a list in E.164 + format. + """ + + dba_business_name: str + """ + Any name that the business operates under that is not its legal business name + (if applicable). + """ + + parent_company: str + """Parent company name (if applicable).""" + + +class ControlPerson(TypedDict, total=False): + address: Required[Address] + """ + Individual's current address - PO boxes, UPS drops, and FedEx drops are not + acceptable; APO/FPO are acceptable. Only USA addresses are currently supported. + """ + + dob: Required[str] + """Individual's date of birth, as an RFC 3339 date.""" + + email: Required[str] + """ + Individual's email address. If utilizing Lithic for chargeback processing, this + customer email address may be used to communicate dispute status and resolution. + """ + + first_name: Required[str] + """Individual's first name, as it appears on government-issued identity documents.""" + + government_id: Required[str] + """ + Government-issued identification number (required for identity verification and + compliance with banking regulations). Social Security Numbers (SSN) and + Individual Taxpayer Identification Numbers (ITIN) are currently supported, + entered as full nine-digits, with or without hyphens + """ + + last_name: Required[str] + """Individual's last name, as it appears on government-issued identity documents.""" + + phone_number: str + """Individual's phone number, entered in E.164 format.""" + + +class KYBParam(TypedDict, total=False): + beneficial_owner_entities: Required[Iterable[BeneficialOwnerEntity]] + """List of all entities with >25% ownership in the company. + + If no entity or individual owns >25% of the company, and the largest shareholder + is an entity, please identify them in this field. See + [FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf) + (Section I) for more background. If no business owner is an entity, pass in an + empty list. However, either this parameter or `beneficial_owner_individuals` + must be populated. on entities that should be included. + """ + + beneficial_owner_individuals: Required[Iterable[BeneficialOwnerIndividual]] + """List of all direct and indirect individuals with >25% ownership in the company. + + If no entity or individual owns >25% of the company, and the largest shareholder + is an individual, please identify them in this field. See + [FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf) + (Section I) for more background on individuals that should be included. If no + individual is an entity, pass in an empty list. However, either this parameter + or `beneficial_owner_entities` must be populated. + """ + + business_entity: Required[BusinessEntity] + """ + Information for business for which the account is being opened and KYB is being + run. + """ + + control_person: Required[ControlPerson] + """ + An individual with significant responsibility for managing the legal entity + (e.g., a Chief Executive Officer, Chief Financial Officer, Chief Operating + Officer, Managing Member, General Partner, President, Vice President, or + Treasurer). This can be an executive, or someone who will have program-wide + access to the cards that Lithic will provide. In some cases, this individual + could also be a beneficial owner listed above. See + [FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf) + (Section II) for more background. + """ + + nature_of_business: Required[str] + """ + Short description of the company's line of business (i.e., what does the company + do?). + """ + + tos_timestamp: Required[str] + """ + An RFC 3339 timestamp indicating when the account holder accepted the applicable + legal agreements (e.g., cardholder terms) as agreed upon during API customer's + implementation with Lithic. + """ + + workflow: Required[Literal["KYB_BASIC", "KYB_BYO"]] + """Specifies the type of KYB workflow to run.""" + + external_id: str + """ + A user provided id that can be used to link an account holder with an external + system + """ + + kyb_passed_timestamp: str + """ + An RFC 3339 timestamp indicating when precomputed KYC was completed on the + business with a pass result. + + This field is required only if workflow type is `KYB_BYO`. + """ + + website_url: str + """Company website URL.""" diff --git a/src/lithic/types/kyc_exempt_param.py b/src/lithic/types/kyc_exempt_param.py new file mode 100644 index 00000000..0157f7be --- /dev/null +++ b/src/lithic/types/kyc_exempt_param.py @@ -0,0 +1,48 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +from .shared_params.address import Address + +__all__ = ["KYCExemptParam"] + + +class KYCExemptParam(TypedDict, total=False): + address: Required[Address] + """ + KYC Exempt user's current address - PO boxes, UPS drops, and FedEx drops are not + acceptable; APO/FPO are acceptable. + """ + + email: Required[str] + """The KYC Exempt user's email""" + + first_name: Required[str] + """The KYC Exempt user's first name""" + + kyc_exemption_type: Required[Literal["AUTHORIZED_USER", "PREPAID_CARD_USER"]] + """Specifies the type of KYC Exempt user""" + + last_name: Required[str] + """The KYC Exempt user's last name""" + + phone_number: Required[str] + """The KYC Exempt user's phone number""" + + workflow: Required[Literal["KYC_EXEMPT"]] + """Specifies the workflow type. This must be 'KYC_EXEMPT'""" + + business_account_token: str + """ + Only applicable for customers using the KYC-Exempt workflow to enroll authorized + users of businesses. Pass the account_token of the enrolled business associated + with the AUTHORIZED_USER in this field. + """ + + external_id: str + """ + A user provided id that can be used to link an account holder with an external + system + """ diff --git a/src/lithic/types/kyc_param.py b/src/lithic/types/kyc_param.py new file mode 100644 index 00000000..4089af2b --- /dev/null +++ b/src/lithic/types/kyc_param.py @@ -0,0 +1,75 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +from .shared_params.address import Address + +__all__ = ["KYCParam", "Individual"] + + +class Individual(TypedDict, total=False): + address: Required[Address] + """ + Individual's current address - PO boxes, UPS drops, and FedEx drops are not + acceptable; APO/FPO are acceptable. Only USA addresses are currently supported. + """ + + dob: Required[str] + """Individual's date of birth, as an RFC 3339 date.""" + + email: Required[str] + """ + Individual's email address. If utilizing Lithic for chargeback processing, this + customer email address may be used to communicate dispute status and resolution. + """ + + first_name: Required[str] + """Individual's first name, as it appears on government-issued identity documents.""" + + government_id: Required[str] + """ + Government-issued identification number (required for identity verification and + compliance with banking regulations). Social Security Numbers (SSN) and + Individual Taxpayer Identification Numbers (ITIN) are currently supported, + entered as full nine-digits, with or without hyphens + """ + + last_name: Required[str] + """Individual's last name, as it appears on government-issued identity documents.""" + + phone_number: Required[str] + """Individual's phone number, entered in E.164 format.""" + + +class KYCParam(TypedDict, total=False): + individual: Required[Individual] + """ + Information on individual for whom the account is being opened and KYC is being + run. + """ + + tos_timestamp: Required[str] + """ + An RFC 3339 timestamp indicating when the account holder accepted the applicable + legal agreements (e.g., cardholder terms) as agreed upon during API customer's + implementation with Lithic. + """ + + workflow: Required[Literal["KYC_ADVANCED", "KYC_BASIC", "KYC_BYO"]] + """Specifies the type of KYC workflow to run.""" + + external_id: str + """ + A user provided id that can be used to link an account holder with an external + system + """ + + kyc_passed_timestamp: str + """ + An RFC 3339 timestamp indicating when precomputed KYC was completed on the + individual with a pass result. + + This field is required only if workflow type is `KYC_BYO`. + """ From 1406b81f7ca5e58d787afa86b723f4f271d361a4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 12:14:38 +0000 Subject: [PATCH 02/30] chore(internal): bump pyright (#651) --- requirements-dev.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.lock b/requirements-dev.lock index af8ea8ad..cf76b21c 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -68,7 +68,7 @@ pydantic-core==2.27.1 # via pydantic pygments==2.18.0 # via rich -pyright==1.1.389 +pyright==1.1.390 pytest==8.3.3 # via pytest-asyncio pytest-asyncio==0.24.0 From 988f2a016c98cef5a3558c08f8568af27776a0fb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 12:42:00 +0000 Subject: [PATCH 03/30] chore(internal): add support for TypeAliasType (#652) --- pyproject.toml | 2 +- src/lithic/_legacy_response.py | 20 ++++++++++---------- src/lithic/_models.py | 3 +++ src/lithic/_response.py | 20 ++++++++++---------- src/lithic/_utils/__init__.py | 1 + src/lithic/_utils/_typing.py | 31 ++++++++++++++++++++++++++++++- tests/test_models.py | 18 +++++++++++++++++- tests/utils.py | 4 ++++ 8 files changed, 76 insertions(+), 23 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2a38b190..83756763 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ authors = [ dependencies = [ "httpx>=0.23.0, <1", "pydantic>=1.9.0, <3", - "typing-extensions>=4.7, <5", + "typing-extensions>=4.10, <5", "anyio>=3.5.0, <5", "distro>=1.7.0, <2", "sniffio", diff --git a/src/lithic/_legacy_response.py b/src/lithic/_legacy_response.py index 8d00883e..c2cfe80c 100644 --- a/src/lithic/_legacy_response.py +++ b/src/lithic/_legacy_response.py @@ -24,7 +24,7 @@ import pydantic from ._types import NoneType -from ._utils import is_given, extract_type_arg, is_annotated_type +from ._utils import is_given, extract_type_arg, is_annotated_type, is_type_alias_type from ._models import BaseModel, is_basemodel from ._constants import RAW_RESPONSE_HEADER from ._streaming import Stream, AsyncStream, is_stream_class_type, extract_stream_chunk_type @@ -188,9 +188,15 @@ def elapsed(self) -> datetime.timedelta: return self.http_response.elapsed def _parse(self, *, to: type[_T] | None = None) -> R | _T: + cast_to = to if to is not None else self._cast_to + + # unwrap `TypeAlias('Name', T)` -> `T` + if is_type_alias_type(cast_to): + cast_to = cast_to.__value__ # type: ignore[unreachable] + # unwrap `Annotated[T, ...]` -> `T` - if to and is_annotated_type(to): - to = extract_type_arg(to, 0) + if cast_to and is_annotated_type(cast_to): + cast_to = extract_type_arg(cast_to, 0) if self._stream: if to: @@ -226,18 +232,12 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T: return cast( R, stream_cls( - cast_to=self._cast_to, + cast_to=cast_to, response=self.http_response, client=cast(Any, self._client), ), ) - cast_to = to if to is not None else self._cast_to - - # unwrap `Annotated[T, ...]` -> `T` - if is_annotated_type(cast_to): - cast_to = extract_type_arg(cast_to, 0) - if cast_to is NoneType: return cast(R, None) diff --git a/src/lithic/_models.py b/src/lithic/_models.py index 6cb469e2..7a547ce5 100644 --- a/src/lithic/_models.py +++ b/src/lithic/_models.py @@ -46,6 +46,7 @@ strip_not_given, extract_type_arg, is_annotated_type, + is_type_alias_type, strip_annotated_type, ) from ._compat import ( @@ -428,6 +429,8 @@ def construct_type(*, value: object, type_: object) -> object: # we allow `object` as the input type because otherwise, passing things like # `Literal['value']` will be reported as a type error by type checkers type_ = cast("type[object]", type_) + if is_type_alias_type(type_): + type_ = type_.__value__ # type: ignore[unreachable] # unwrap `Annotated[T, ...]` -> `T` if is_annotated_type(type_): diff --git a/src/lithic/_response.py b/src/lithic/_response.py index 4ee27ec4..58660e33 100644 --- a/src/lithic/_response.py +++ b/src/lithic/_response.py @@ -25,7 +25,7 @@ import pydantic from ._types import NoneType -from ._utils import is_given, extract_type_arg, is_annotated_type, extract_type_var_from_base +from ._utils import is_given, extract_type_arg, is_annotated_type, is_type_alias_type, extract_type_var_from_base from ._models import BaseModel, is_basemodel from ._constants import RAW_RESPONSE_HEADER, OVERRIDE_CAST_TO_HEADER from ._streaming import Stream, AsyncStream, is_stream_class_type, extract_stream_chunk_type @@ -126,9 +126,15 @@ def __repr__(self) -> str: ) def _parse(self, *, to: type[_T] | None = None) -> R | _T: + cast_to = to if to is not None else self._cast_to + + # unwrap `TypeAlias('Name', T)` -> `T` + if is_type_alias_type(cast_to): + cast_to = cast_to.__value__ # type: ignore[unreachable] + # unwrap `Annotated[T, ...]` -> `T` - if to and is_annotated_type(to): - to = extract_type_arg(to, 0) + if cast_to and is_annotated_type(cast_to): + cast_to = extract_type_arg(cast_to, 0) if self._is_sse_stream: if to: @@ -164,18 +170,12 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T: return cast( R, stream_cls( - cast_to=self._cast_to, + cast_to=cast_to, response=self.http_response, client=cast(Any, self._client), ), ) - cast_to = to if to is not None else self._cast_to - - # unwrap `Annotated[T, ...]` -> `T` - if is_annotated_type(cast_to): - cast_to = extract_type_arg(cast_to, 0) - if cast_to is NoneType: return cast(R, None) diff --git a/src/lithic/_utils/__init__.py b/src/lithic/_utils/__init__.py index a7cff3c0..d4fda26f 100644 --- a/src/lithic/_utils/__init__.py +++ b/src/lithic/_utils/__init__.py @@ -39,6 +39,7 @@ is_iterable_type as is_iterable_type, is_required_type as is_required_type, is_annotated_type as is_annotated_type, + is_type_alias_type as is_type_alias_type, strip_annotated_type as strip_annotated_type, extract_type_var_from_base as extract_type_var_from_base, ) diff --git a/src/lithic/_utils/_typing.py b/src/lithic/_utils/_typing.py index c036991f..278749b1 100644 --- a/src/lithic/_utils/_typing.py +++ b/src/lithic/_utils/_typing.py @@ -1,8 +1,17 @@ from __future__ import annotations +import sys +import typing +import typing_extensions from typing import Any, TypeVar, Iterable, cast from collections import abc as _c_abc -from typing_extensions import Required, Annotated, get_args, get_origin +from typing_extensions import ( + TypeIs, + Required, + Annotated, + get_args, + get_origin, +) from .._types import InheritsGeneric from .._compat import is_union as _is_union @@ -36,6 +45,26 @@ def is_typevar(typ: type) -> bool: return type(typ) == TypeVar # type: ignore +_TYPE_ALIAS_TYPES: tuple[type[typing_extensions.TypeAliasType], ...] = (typing_extensions.TypeAliasType,) +if sys.version_info >= (3, 12): + _TYPE_ALIAS_TYPES = (*_TYPE_ALIAS_TYPES, typing.TypeAliasType) + + +def is_type_alias_type(tp: Any, /) -> TypeIs[typing_extensions.TypeAliasType]: + """Return whether the provided argument is an instance of `TypeAliasType`. + + ```python + type Int = int + is_type_alias_type(Int) + # > True + Str = TypeAliasType("Str", str) + is_type_alias_type(Str) + # > True + ``` + """ + return isinstance(tp, _TYPE_ALIAS_TYPES) + + # Extracts T from Annotated[T, ...] or from Required[Annotated[T, ...]] def strip_annotated_type(typ: type) -> type: if is_required_type(typ) or is_annotated_type(typ): diff --git a/tests/test_models.py b/tests/test_models.py index 790991b5..a5aebd46 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,7 +1,7 @@ import json from typing import Any, Dict, List, Union, Optional, cast from datetime import datetime, timezone -from typing_extensions import Literal, Annotated +from typing_extensions import Literal, Annotated, TypeAliasType import pytest import pydantic @@ -828,3 +828,19 @@ class B(BaseModel): # if the discriminator details object stays the same between invocations then # we hit the cache assert UnionType.__discriminator__ is discriminator + + +@pytest.mark.skipif(not PYDANTIC_V2, reason="TypeAliasType is not supported in Pydantic v1") +def test_type_alias_type() -> None: + Alias = TypeAliasType("Alias", str) + + class Model(BaseModel): + alias: Alias + union: Union[int, Alias] + + m = construct_type(value={"alias": "foo", "union": "bar"}, type_=Model) + assert isinstance(m, Model) + assert isinstance(m.alias, str) + assert m.alias == "foo" + assert isinstance(m.union, str) + assert m.union == "bar" diff --git a/tests/utils.py b/tests/utils.py index 8ddc2926..afd0d680 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -16,6 +16,7 @@ is_union_type, extract_type_arg, is_annotated_type, + is_type_alias_type, ) from lithic._compat import PYDANTIC_V2, field_outer_type, get_model_fields from lithic._models import BaseModel @@ -51,6 +52,9 @@ def assert_matches_type( path: list[str], allow_none: bool = False, ) -> None: + if is_type_alias_type(type_): + type_ = type_.__value__ + # unwrap `Annotated[T, ...]` -> `T` if is_annotated_type(type_): type_ = extract_type_arg(type_, 0) From c446d74a9fd059d45d93966dd63894a68a76a965 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:16:20 +0000 Subject: [PATCH 04/30] chore(internal): remove some duplicated imports (#653) --- src/lithic/resources/auth_rules/auth_rules.py | 3 +-- .../financial_accounts/financial_accounts.py | 17 ++++++++--------- .../resources/transactions/transactions.py | 17 ++++++++--------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/lithic/resources/auth_rules/auth_rules.py b/src/lithic/resources/auth_rules/auth_rules.py index 6ce45ef9..00b99da4 100644 --- a/src/lithic/resources/auth_rules/auth_rules.py +++ b/src/lithic/resources/auth_rules/auth_rules.py @@ -2,7 +2,7 @@ from __future__ import annotations -from .v2 import ( +from .v2.v2 import ( V2, AsyncV2, V2WithRawResponse, @@ -10,7 +10,6 @@ V2WithStreamingResponse, AsyncV2WithStreamingResponse, ) -from .v2.v2 import V2, AsyncV2 from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource diff --git a/src/lithic/resources/financial_accounts/financial_accounts.py b/src/lithic/resources/financial_accounts/financial_accounts.py index decb67ac..4834891d 100644 --- a/src/lithic/resources/financial_accounts/financial_accounts.py +++ b/src/lithic/resources/financial_accounts/financial_accounts.py @@ -35,14 +35,6 @@ LoanTapesWithStreamingResponse, AsyncLoanTapesWithStreamingResponse, ) -from .statements import ( - Statements, - AsyncStatements, - StatementsWithRawResponse, - AsyncStatementsWithRawResponse, - StatementsWithStreamingResponse, - AsyncStatementsWithStreamingResponse, -) from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from ...pagination import SyncSinglePage, AsyncSinglePage @@ -55,7 +47,14 @@ CreditConfigurationWithStreamingResponse, AsyncCreditConfigurationWithStreamingResponse, ) -from .statements.statements import Statements, AsyncStatements +from .statements.statements import ( + Statements, + AsyncStatements, + StatementsWithRawResponse, + AsyncStatementsWithRawResponse, + StatementsWithStreamingResponse, + AsyncStatementsWithStreamingResponse, +) from .financial_transactions import ( FinancialTransactions, AsyncFinancialTransactions, diff --git a/src/lithic/resources/transactions/transactions.py b/src/lithic/resources/transactions/transactions.py index eebb2a7c..f38206ee 100644 --- a/src/lithic/resources/transactions/transactions.py +++ b/src/lithic/resources/transactions/transactions.py @@ -9,14 +9,6 @@ import httpx from ... import _legacy_response -from .events import ( - Events, - AsyncEvents, - EventsWithRawResponse, - AsyncEventsWithRawResponse, - EventsWithStreamingResponse, - AsyncEventsWithStreamingResponse, -) from ...types import ( transaction_list_params, transaction_simulate_void_params, @@ -36,7 +28,14 @@ from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from ...pagination import SyncCursorPage, AsyncCursorPage -from .events.events import Events, AsyncEvents +from .events.events import ( + Events, + AsyncEvents, + EventsWithRawResponse, + AsyncEventsWithRawResponse, + EventsWithStreamingResponse, + AsyncEventsWithStreamingResponse, +) from ..._base_client import AsyncPaginator, make_request_options from ...types.transaction import Transaction from .enhanced_commercial_data import ( From b0b1b644dcc1db989c22ba9def0fa4712e2e18d3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:10:04 +0000 Subject: [PATCH 05/30] chore(internal): updated imports (#654) --- src/lithic/_client.py | 452 ++++++++++++++++++++++++------------------ 1 file changed, 254 insertions(+), 198 deletions(-) diff --git a/src/lithic/_client.py b/src/lithic/_client.py index c37138af..2d0aab22 100644 --- a/src/lithic/_client.py +++ b/src/lithic/_client.py @@ -8,7 +8,7 @@ import httpx -from . import resources, _exceptions, _legacy_response +from . import _exceptions, _legacy_response from ._qs import Querystring from ._types import ( NOT_GIVEN, @@ -29,6 +29,24 @@ ) from ._version import __version__ from ._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper +from .resources import ( + accounts, + balances, + disputes, + payments, + webhooks, + card_programs, + tokenizations, + book_transfers, + account_holders, + digital_card_art, + external_payments, + aggregate_balances, + responder_endpoints, + management_operations, + auth_stream_enrollment, + tokenization_decisioning, +) from ._streaming import Stream as Stream, AsyncStream as AsyncStream from ._exceptions import LithicError, APIStatusError from ._base_client import ( @@ -40,7 +58,16 @@ AsyncHttpxClientWrapper, make_request_options, ) +from .resources.cards import cards +from .resources.events import events from .types.api_status import APIStatus +from .resources.reports import reports +from .resources.three_ds import three_ds +from .resources.auth_rules import auth_rules +from .resources.transactions import transactions +from .resources.credit_products import credit_products +from .resources.financial_accounts import financial_accounts +from .resources.external_bank_accounts import external_bank_accounts __all__ = [ "ENVIRONMENTS", @@ -48,7 +75,6 @@ "Transport", "ProxiesTypes", "RequestOptions", - "resources", "Lithic", "AsyncLithic", "Client", @@ -62,31 +88,31 @@ class Lithic(SyncAPIClient): - accounts: resources.Accounts - account_holders: resources.AccountHolders - auth_rules: resources.AuthRules - auth_stream_enrollment: resources.AuthStreamEnrollment - tokenization_decisioning: resources.TokenizationDecisioning - tokenizations: resources.Tokenizations - cards: resources.Cards - balances: resources.Balances - aggregate_balances: resources.AggregateBalances - disputes: resources.Disputes - events: resources.Events - financial_accounts: resources.FinancialAccounts - transactions: resources.Transactions - responder_endpoints: resources.ResponderEndpoints - webhooks: resources.Webhooks - external_bank_accounts: resources.ExternalBankAccounts - payments: resources.Payments - three_ds: resources.ThreeDS - reports: resources.Reports - card_programs: resources.CardPrograms - digital_card_art: resources.DigitalCardArtResource - book_transfers: resources.BookTransfers - credit_products: resources.CreditProducts - external_payments: resources.ExternalPayments - management_operations: resources.ManagementOperations + accounts: accounts.Accounts + account_holders: account_holders.AccountHolders + auth_rules: auth_rules.AuthRules + auth_stream_enrollment: auth_stream_enrollment.AuthStreamEnrollment + tokenization_decisioning: tokenization_decisioning.TokenizationDecisioning + tokenizations: tokenizations.Tokenizations + cards: cards.Cards + balances: balances.Balances + aggregate_balances: aggregate_balances.AggregateBalances + disputes: disputes.Disputes + events: events.Events + financial_accounts: financial_accounts.FinancialAccounts + transactions: transactions.Transactions + responder_endpoints: responder_endpoints.ResponderEndpoints + webhooks: webhooks.Webhooks + external_bank_accounts: external_bank_accounts.ExternalBankAccounts + payments: payments.Payments + three_ds: three_ds.ThreeDS + reports: reports.Reports + card_programs: card_programs.CardPrograms + digital_card_art: digital_card_art.DigitalCardArtResource + book_transfers: book_transfers.BookTransfers + credit_products: credit_products.CreditProducts + external_payments: external_payments.ExternalPayments + management_operations: management_operations.ManagementOperations with_raw_response: LithicWithRawResponse with_streaming_response: LithicWithStreamedResponse @@ -185,31 +211,31 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - self.accounts = resources.Accounts(self) - self.account_holders = resources.AccountHolders(self) - self.auth_rules = resources.AuthRules(self) - self.auth_stream_enrollment = resources.AuthStreamEnrollment(self) - self.tokenization_decisioning = resources.TokenizationDecisioning(self) - self.tokenizations = resources.Tokenizations(self) - self.cards = resources.Cards(self) - self.balances = resources.Balances(self) - self.aggregate_balances = resources.AggregateBalances(self) - self.disputes = resources.Disputes(self) - self.events = resources.Events(self) - self.financial_accounts = resources.FinancialAccounts(self) - self.transactions = resources.Transactions(self) - self.responder_endpoints = resources.ResponderEndpoints(self) - self.webhooks = resources.Webhooks(self) - self.external_bank_accounts = resources.ExternalBankAccounts(self) - self.payments = resources.Payments(self) - self.three_ds = resources.ThreeDS(self) - self.reports = resources.Reports(self) - self.card_programs = resources.CardPrograms(self) - self.digital_card_art = resources.DigitalCardArtResource(self) - self.book_transfers = resources.BookTransfers(self) - self.credit_products = resources.CreditProducts(self) - self.external_payments = resources.ExternalPayments(self) - self.management_operations = resources.ManagementOperations(self) + self.accounts = accounts.Accounts(self) + self.account_holders = account_holders.AccountHolders(self) + self.auth_rules = auth_rules.AuthRules(self) + self.auth_stream_enrollment = auth_stream_enrollment.AuthStreamEnrollment(self) + self.tokenization_decisioning = tokenization_decisioning.TokenizationDecisioning(self) + self.tokenizations = tokenizations.Tokenizations(self) + self.cards = cards.Cards(self) + self.balances = balances.Balances(self) + self.aggregate_balances = aggregate_balances.AggregateBalances(self) + self.disputes = disputes.Disputes(self) + self.events = events.Events(self) + self.financial_accounts = financial_accounts.FinancialAccounts(self) + self.transactions = transactions.Transactions(self) + self.responder_endpoints = responder_endpoints.ResponderEndpoints(self) + self.webhooks = webhooks.Webhooks(self) + self.external_bank_accounts = external_bank_accounts.ExternalBankAccounts(self) + self.payments = payments.Payments(self) + self.three_ds = three_ds.ThreeDS(self) + self.reports = reports.Reports(self) + self.card_programs = card_programs.CardPrograms(self) + self.digital_card_art = digital_card_art.DigitalCardArtResource(self) + self.book_transfers = book_transfers.BookTransfers(self) + self.credit_products = credit_products.CreditProducts(self) + self.external_payments = external_payments.ExternalPayments(self) + self.management_operations = management_operations.ManagementOperations(self) self.with_raw_response = LithicWithRawResponse(self) self.with_streaming_response = LithicWithStreamedResponse(self) @@ -362,31 +388,31 @@ def _make_status_error( class AsyncLithic(AsyncAPIClient): - accounts: resources.AsyncAccounts - account_holders: resources.AsyncAccountHolders - auth_rules: resources.AsyncAuthRules - auth_stream_enrollment: resources.AsyncAuthStreamEnrollment - tokenization_decisioning: resources.AsyncTokenizationDecisioning - tokenizations: resources.AsyncTokenizations - cards: resources.AsyncCards - balances: resources.AsyncBalances - aggregate_balances: resources.AsyncAggregateBalances - disputes: resources.AsyncDisputes - events: resources.AsyncEvents - financial_accounts: resources.AsyncFinancialAccounts - transactions: resources.AsyncTransactions - responder_endpoints: resources.AsyncResponderEndpoints - webhooks: resources.AsyncWebhooks - external_bank_accounts: resources.AsyncExternalBankAccounts - payments: resources.AsyncPayments - three_ds: resources.AsyncThreeDS - reports: resources.AsyncReports - card_programs: resources.AsyncCardPrograms - digital_card_art: resources.AsyncDigitalCardArtResource - book_transfers: resources.AsyncBookTransfers - credit_products: resources.AsyncCreditProducts - external_payments: resources.AsyncExternalPayments - management_operations: resources.AsyncManagementOperations + accounts: accounts.AsyncAccounts + account_holders: account_holders.AsyncAccountHolders + auth_rules: auth_rules.AsyncAuthRules + auth_stream_enrollment: auth_stream_enrollment.AsyncAuthStreamEnrollment + tokenization_decisioning: tokenization_decisioning.AsyncTokenizationDecisioning + tokenizations: tokenizations.AsyncTokenizations + cards: cards.AsyncCards + balances: balances.AsyncBalances + aggregate_balances: aggregate_balances.AsyncAggregateBalances + disputes: disputes.AsyncDisputes + events: events.AsyncEvents + financial_accounts: financial_accounts.AsyncFinancialAccounts + transactions: transactions.AsyncTransactions + responder_endpoints: responder_endpoints.AsyncResponderEndpoints + webhooks: webhooks.AsyncWebhooks + external_bank_accounts: external_bank_accounts.AsyncExternalBankAccounts + payments: payments.AsyncPayments + three_ds: three_ds.AsyncThreeDS + reports: reports.AsyncReports + card_programs: card_programs.AsyncCardPrograms + digital_card_art: digital_card_art.AsyncDigitalCardArtResource + book_transfers: book_transfers.AsyncBookTransfers + credit_products: credit_products.AsyncCreditProducts + external_payments: external_payments.AsyncExternalPayments + management_operations: management_operations.AsyncManagementOperations with_raw_response: AsyncLithicWithRawResponse with_streaming_response: AsyncLithicWithStreamedResponse @@ -485,31 +511,31 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - self.accounts = resources.AsyncAccounts(self) - self.account_holders = resources.AsyncAccountHolders(self) - self.auth_rules = resources.AsyncAuthRules(self) - self.auth_stream_enrollment = resources.AsyncAuthStreamEnrollment(self) - self.tokenization_decisioning = resources.AsyncTokenizationDecisioning(self) - self.tokenizations = resources.AsyncTokenizations(self) - self.cards = resources.AsyncCards(self) - self.balances = resources.AsyncBalances(self) - self.aggregate_balances = resources.AsyncAggregateBalances(self) - self.disputes = resources.AsyncDisputes(self) - self.events = resources.AsyncEvents(self) - self.financial_accounts = resources.AsyncFinancialAccounts(self) - self.transactions = resources.AsyncTransactions(self) - self.responder_endpoints = resources.AsyncResponderEndpoints(self) - self.webhooks = resources.AsyncWebhooks(self) - self.external_bank_accounts = resources.AsyncExternalBankAccounts(self) - self.payments = resources.AsyncPayments(self) - self.three_ds = resources.AsyncThreeDS(self) - self.reports = resources.AsyncReports(self) - self.card_programs = resources.AsyncCardPrograms(self) - self.digital_card_art = resources.AsyncDigitalCardArtResource(self) - self.book_transfers = resources.AsyncBookTransfers(self) - self.credit_products = resources.AsyncCreditProducts(self) - self.external_payments = resources.AsyncExternalPayments(self) - self.management_operations = resources.AsyncManagementOperations(self) + self.accounts = accounts.AsyncAccounts(self) + self.account_holders = account_holders.AsyncAccountHolders(self) + self.auth_rules = auth_rules.AsyncAuthRules(self) + self.auth_stream_enrollment = auth_stream_enrollment.AsyncAuthStreamEnrollment(self) + self.tokenization_decisioning = tokenization_decisioning.AsyncTokenizationDecisioning(self) + self.tokenizations = tokenizations.AsyncTokenizations(self) + self.cards = cards.AsyncCards(self) + self.balances = balances.AsyncBalances(self) + self.aggregate_balances = aggregate_balances.AsyncAggregateBalances(self) + self.disputes = disputes.AsyncDisputes(self) + self.events = events.AsyncEvents(self) + self.financial_accounts = financial_accounts.AsyncFinancialAccounts(self) + self.transactions = transactions.AsyncTransactions(self) + self.responder_endpoints = responder_endpoints.AsyncResponderEndpoints(self) + self.webhooks = webhooks.AsyncWebhooks(self) + self.external_bank_accounts = external_bank_accounts.AsyncExternalBankAccounts(self) + self.payments = payments.AsyncPayments(self) + self.three_ds = three_ds.AsyncThreeDS(self) + self.reports = reports.AsyncReports(self) + self.card_programs = card_programs.AsyncCardPrograms(self) + self.digital_card_art = digital_card_art.AsyncDigitalCardArtResource(self) + self.book_transfers = book_transfers.AsyncBookTransfers(self) + self.credit_products = credit_products.AsyncCreditProducts(self) + self.external_payments = external_payments.AsyncExternalPayments(self) + self.management_operations = management_operations.AsyncManagementOperations(self) self.with_raw_response = AsyncLithicWithRawResponse(self) self.with_streaming_response = AsyncLithicWithStreamedResponse(self) @@ -663,32 +689,38 @@ def _make_status_error( class LithicWithRawResponse: def __init__(self, client: Lithic) -> None: - self.accounts = resources.AccountsWithRawResponse(client.accounts) - self.account_holders = resources.AccountHoldersWithRawResponse(client.account_holders) - self.auth_rules = resources.AuthRulesWithRawResponse(client.auth_rules) - self.auth_stream_enrollment = resources.AuthStreamEnrollmentWithRawResponse(client.auth_stream_enrollment) - self.tokenization_decisioning = resources.TokenizationDecisioningWithRawResponse( + self.accounts = accounts.AccountsWithRawResponse(client.accounts) + self.account_holders = account_holders.AccountHoldersWithRawResponse(client.account_holders) + self.auth_rules = auth_rules.AuthRulesWithRawResponse(client.auth_rules) + self.auth_stream_enrollment = auth_stream_enrollment.AuthStreamEnrollmentWithRawResponse( + client.auth_stream_enrollment + ) + self.tokenization_decisioning = tokenization_decisioning.TokenizationDecisioningWithRawResponse( client.tokenization_decisioning ) - self.tokenizations = resources.TokenizationsWithRawResponse(client.tokenizations) - self.cards = resources.CardsWithRawResponse(client.cards) - self.balances = resources.BalancesWithRawResponse(client.balances) - self.aggregate_balances = resources.AggregateBalancesWithRawResponse(client.aggregate_balances) - self.disputes = resources.DisputesWithRawResponse(client.disputes) - self.events = resources.EventsWithRawResponse(client.events) - self.financial_accounts = resources.FinancialAccountsWithRawResponse(client.financial_accounts) - self.transactions = resources.TransactionsWithRawResponse(client.transactions) - self.responder_endpoints = resources.ResponderEndpointsWithRawResponse(client.responder_endpoints) - self.external_bank_accounts = resources.ExternalBankAccountsWithRawResponse(client.external_bank_accounts) - self.payments = resources.PaymentsWithRawResponse(client.payments) - self.three_ds = resources.ThreeDSWithRawResponse(client.three_ds) - self.reports = resources.ReportsWithRawResponse(client.reports) - self.card_programs = resources.CardProgramsWithRawResponse(client.card_programs) - self.digital_card_art = resources.DigitalCardArtResourceWithRawResponse(client.digital_card_art) - self.book_transfers = resources.BookTransfersWithRawResponse(client.book_transfers) - self.credit_products = resources.CreditProductsWithRawResponse(client.credit_products) - self.external_payments = resources.ExternalPaymentsWithRawResponse(client.external_payments) - self.management_operations = resources.ManagementOperationsWithRawResponse(client.management_operations) + self.tokenizations = tokenizations.TokenizationsWithRawResponse(client.tokenizations) + self.cards = cards.CardsWithRawResponse(client.cards) + self.balances = balances.BalancesWithRawResponse(client.balances) + self.aggregate_balances = aggregate_balances.AggregateBalancesWithRawResponse(client.aggregate_balances) + self.disputes = disputes.DisputesWithRawResponse(client.disputes) + self.events = events.EventsWithRawResponse(client.events) + self.financial_accounts = financial_accounts.FinancialAccountsWithRawResponse(client.financial_accounts) + self.transactions = transactions.TransactionsWithRawResponse(client.transactions) + self.responder_endpoints = responder_endpoints.ResponderEndpointsWithRawResponse(client.responder_endpoints) + self.external_bank_accounts = external_bank_accounts.ExternalBankAccountsWithRawResponse( + client.external_bank_accounts + ) + self.payments = payments.PaymentsWithRawResponse(client.payments) + self.three_ds = three_ds.ThreeDSWithRawResponse(client.three_ds) + self.reports = reports.ReportsWithRawResponse(client.reports) + self.card_programs = card_programs.CardProgramsWithRawResponse(client.card_programs) + self.digital_card_art = digital_card_art.DigitalCardArtResourceWithRawResponse(client.digital_card_art) + self.book_transfers = book_transfers.BookTransfersWithRawResponse(client.book_transfers) + self.credit_products = credit_products.CreditProductsWithRawResponse(client.credit_products) + self.external_payments = external_payments.ExternalPaymentsWithRawResponse(client.external_payments) + self.management_operations = management_operations.ManagementOperationsWithRawResponse( + client.management_operations + ) self.api_status = _legacy_response.to_raw_response_wrapper( client.api_status, @@ -697,32 +729,40 @@ def __init__(self, client: Lithic) -> None: class AsyncLithicWithRawResponse: def __init__(self, client: AsyncLithic) -> None: - self.accounts = resources.AsyncAccountsWithRawResponse(client.accounts) - self.account_holders = resources.AsyncAccountHoldersWithRawResponse(client.account_holders) - self.auth_rules = resources.AsyncAuthRulesWithRawResponse(client.auth_rules) - self.auth_stream_enrollment = resources.AsyncAuthStreamEnrollmentWithRawResponse(client.auth_stream_enrollment) - self.tokenization_decisioning = resources.AsyncTokenizationDecisioningWithRawResponse( + self.accounts = accounts.AsyncAccountsWithRawResponse(client.accounts) + self.account_holders = account_holders.AsyncAccountHoldersWithRawResponse(client.account_holders) + self.auth_rules = auth_rules.AsyncAuthRulesWithRawResponse(client.auth_rules) + self.auth_stream_enrollment = auth_stream_enrollment.AsyncAuthStreamEnrollmentWithRawResponse( + client.auth_stream_enrollment + ) + self.tokenization_decisioning = tokenization_decisioning.AsyncTokenizationDecisioningWithRawResponse( client.tokenization_decisioning ) - self.tokenizations = resources.AsyncTokenizationsWithRawResponse(client.tokenizations) - self.cards = resources.AsyncCardsWithRawResponse(client.cards) - self.balances = resources.AsyncBalancesWithRawResponse(client.balances) - self.aggregate_balances = resources.AsyncAggregateBalancesWithRawResponse(client.aggregate_balances) - self.disputes = resources.AsyncDisputesWithRawResponse(client.disputes) - self.events = resources.AsyncEventsWithRawResponse(client.events) - self.financial_accounts = resources.AsyncFinancialAccountsWithRawResponse(client.financial_accounts) - self.transactions = resources.AsyncTransactionsWithRawResponse(client.transactions) - self.responder_endpoints = resources.AsyncResponderEndpointsWithRawResponse(client.responder_endpoints) - self.external_bank_accounts = resources.AsyncExternalBankAccountsWithRawResponse(client.external_bank_accounts) - self.payments = resources.AsyncPaymentsWithRawResponse(client.payments) - self.three_ds = resources.AsyncThreeDSWithRawResponse(client.three_ds) - self.reports = resources.AsyncReportsWithRawResponse(client.reports) - self.card_programs = resources.AsyncCardProgramsWithRawResponse(client.card_programs) - self.digital_card_art = resources.AsyncDigitalCardArtResourceWithRawResponse(client.digital_card_art) - self.book_transfers = resources.AsyncBookTransfersWithRawResponse(client.book_transfers) - self.credit_products = resources.AsyncCreditProductsWithRawResponse(client.credit_products) - self.external_payments = resources.AsyncExternalPaymentsWithRawResponse(client.external_payments) - self.management_operations = resources.AsyncManagementOperationsWithRawResponse(client.management_operations) + self.tokenizations = tokenizations.AsyncTokenizationsWithRawResponse(client.tokenizations) + self.cards = cards.AsyncCardsWithRawResponse(client.cards) + self.balances = balances.AsyncBalancesWithRawResponse(client.balances) + self.aggregate_balances = aggregate_balances.AsyncAggregateBalancesWithRawResponse(client.aggregate_balances) + self.disputes = disputes.AsyncDisputesWithRawResponse(client.disputes) + self.events = events.AsyncEventsWithRawResponse(client.events) + self.financial_accounts = financial_accounts.AsyncFinancialAccountsWithRawResponse(client.financial_accounts) + self.transactions = transactions.AsyncTransactionsWithRawResponse(client.transactions) + self.responder_endpoints = responder_endpoints.AsyncResponderEndpointsWithRawResponse( + client.responder_endpoints + ) + self.external_bank_accounts = external_bank_accounts.AsyncExternalBankAccountsWithRawResponse( + client.external_bank_accounts + ) + self.payments = payments.AsyncPaymentsWithRawResponse(client.payments) + self.three_ds = three_ds.AsyncThreeDSWithRawResponse(client.three_ds) + self.reports = reports.AsyncReportsWithRawResponse(client.reports) + self.card_programs = card_programs.AsyncCardProgramsWithRawResponse(client.card_programs) + self.digital_card_art = digital_card_art.AsyncDigitalCardArtResourceWithRawResponse(client.digital_card_art) + self.book_transfers = book_transfers.AsyncBookTransfersWithRawResponse(client.book_transfers) + self.credit_products = credit_products.AsyncCreditProductsWithRawResponse(client.credit_products) + self.external_payments = external_payments.AsyncExternalPaymentsWithRawResponse(client.external_payments) + self.management_operations = management_operations.AsyncManagementOperationsWithRawResponse( + client.management_operations + ) self.api_status = _legacy_response.async_to_raw_response_wrapper( client.api_status, @@ -731,32 +771,40 @@ def __init__(self, client: AsyncLithic) -> None: class LithicWithStreamedResponse: def __init__(self, client: Lithic) -> None: - self.accounts = resources.AccountsWithStreamingResponse(client.accounts) - self.account_holders = resources.AccountHoldersWithStreamingResponse(client.account_holders) - self.auth_rules = resources.AuthRulesWithStreamingResponse(client.auth_rules) - self.auth_stream_enrollment = resources.AuthStreamEnrollmentWithStreamingResponse(client.auth_stream_enrollment) - self.tokenization_decisioning = resources.TokenizationDecisioningWithStreamingResponse( + self.accounts = accounts.AccountsWithStreamingResponse(client.accounts) + self.account_holders = account_holders.AccountHoldersWithStreamingResponse(client.account_holders) + self.auth_rules = auth_rules.AuthRulesWithStreamingResponse(client.auth_rules) + self.auth_stream_enrollment = auth_stream_enrollment.AuthStreamEnrollmentWithStreamingResponse( + client.auth_stream_enrollment + ) + self.tokenization_decisioning = tokenization_decisioning.TokenizationDecisioningWithStreamingResponse( client.tokenization_decisioning ) - self.tokenizations = resources.TokenizationsWithStreamingResponse(client.tokenizations) - self.cards = resources.CardsWithStreamingResponse(client.cards) - self.balances = resources.BalancesWithStreamingResponse(client.balances) - self.aggregate_balances = resources.AggregateBalancesWithStreamingResponse(client.aggregate_balances) - self.disputes = resources.DisputesWithStreamingResponse(client.disputes) - self.events = resources.EventsWithStreamingResponse(client.events) - self.financial_accounts = resources.FinancialAccountsWithStreamingResponse(client.financial_accounts) - self.transactions = resources.TransactionsWithStreamingResponse(client.transactions) - self.responder_endpoints = resources.ResponderEndpointsWithStreamingResponse(client.responder_endpoints) - self.external_bank_accounts = resources.ExternalBankAccountsWithStreamingResponse(client.external_bank_accounts) - self.payments = resources.PaymentsWithStreamingResponse(client.payments) - self.three_ds = resources.ThreeDSWithStreamingResponse(client.three_ds) - self.reports = resources.ReportsWithStreamingResponse(client.reports) - self.card_programs = resources.CardProgramsWithStreamingResponse(client.card_programs) - self.digital_card_art = resources.DigitalCardArtResourceWithStreamingResponse(client.digital_card_art) - self.book_transfers = resources.BookTransfersWithStreamingResponse(client.book_transfers) - self.credit_products = resources.CreditProductsWithStreamingResponse(client.credit_products) - self.external_payments = resources.ExternalPaymentsWithStreamingResponse(client.external_payments) - self.management_operations = resources.ManagementOperationsWithStreamingResponse(client.management_operations) + self.tokenizations = tokenizations.TokenizationsWithStreamingResponse(client.tokenizations) + self.cards = cards.CardsWithStreamingResponse(client.cards) + self.balances = balances.BalancesWithStreamingResponse(client.balances) + self.aggregate_balances = aggregate_balances.AggregateBalancesWithStreamingResponse(client.aggregate_balances) + self.disputes = disputes.DisputesWithStreamingResponse(client.disputes) + self.events = events.EventsWithStreamingResponse(client.events) + self.financial_accounts = financial_accounts.FinancialAccountsWithStreamingResponse(client.financial_accounts) + self.transactions = transactions.TransactionsWithStreamingResponse(client.transactions) + self.responder_endpoints = responder_endpoints.ResponderEndpointsWithStreamingResponse( + client.responder_endpoints + ) + self.external_bank_accounts = external_bank_accounts.ExternalBankAccountsWithStreamingResponse( + client.external_bank_accounts + ) + self.payments = payments.PaymentsWithStreamingResponse(client.payments) + self.three_ds = three_ds.ThreeDSWithStreamingResponse(client.three_ds) + self.reports = reports.ReportsWithStreamingResponse(client.reports) + self.card_programs = card_programs.CardProgramsWithStreamingResponse(client.card_programs) + self.digital_card_art = digital_card_art.DigitalCardArtResourceWithStreamingResponse(client.digital_card_art) + self.book_transfers = book_transfers.BookTransfersWithStreamingResponse(client.book_transfers) + self.credit_products = credit_products.CreditProductsWithStreamingResponse(client.credit_products) + self.external_payments = external_payments.ExternalPaymentsWithStreamingResponse(client.external_payments) + self.management_operations = management_operations.ManagementOperationsWithStreamingResponse( + client.management_operations + ) self.api_status = to_streamed_response_wrapper( client.api_status, @@ -765,36 +813,44 @@ def __init__(self, client: Lithic) -> None: class AsyncLithicWithStreamedResponse: def __init__(self, client: AsyncLithic) -> None: - self.accounts = resources.AsyncAccountsWithStreamingResponse(client.accounts) - self.account_holders = resources.AsyncAccountHoldersWithStreamingResponse(client.account_holders) - self.auth_rules = resources.AsyncAuthRulesWithStreamingResponse(client.auth_rules) - self.auth_stream_enrollment = resources.AsyncAuthStreamEnrollmentWithStreamingResponse( + self.accounts = accounts.AsyncAccountsWithStreamingResponse(client.accounts) + self.account_holders = account_holders.AsyncAccountHoldersWithStreamingResponse(client.account_holders) + self.auth_rules = auth_rules.AsyncAuthRulesWithStreamingResponse(client.auth_rules) + self.auth_stream_enrollment = auth_stream_enrollment.AsyncAuthStreamEnrollmentWithStreamingResponse( client.auth_stream_enrollment ) - self.tokenization_decisioning = resources.AsyncTokenizationDecisioningWithStreamingResponse( + self.tokenization_decisioning = tokenization_decisioning.AsyncTokenizationDecisioningWithStreamingResponse( client.tokenization_decisioning ) - self.tokenizations = resources.AsyncTokenizationsWithStreamingResponse(client.tokenizations) - self.cards = resources.AsyncCardsWithStreamingResponse(client.cards) - self.balances = resources.AsyncBalancesWithStreamingResponse(client.balances) - self.aggregate_balances = resources.AsyncAggregateBalancesWithStreamingResponse(client.aggregate_balances) - self.disputes = resources.AsyncDisputesWithStreamingResponse(client.disputes) - self.events = resources.AsyncEventsWithStreamingResponse(client.events) - self.financial_accounts = resources.AsyncFinancialAccountsWithStreamingResponse(client.financial_accounts) - self.transactions = resources.AsyncTransactionsWithStreamingResponse(client.transactions) - self.responder_endpoints = resources.AsyncResponderEndpointsWithStreamingResponse(client.responder_endpoints) - self.external_bank_accounts = resources.AsyncExternalBankAccountsWithStreamingResponse( + self.tokenizations = tokenizations.AsyncTokenizationsWithStreamingResponse(client.tokenizations) + self.cards = cards.AsyncCardsWithStreamingResponse(client.cards) + self.balances = balances.AsyncBalancesWithStreamingResponse(client.balances) + self.aggregate_balances = aggregate_balances.AsyncAggregateBalancesWithStreamingResponse( + client.aggregate_balances + ) + self.disputes = disputes.AsyncDisputesWithStreamingResponse(client.disputes) + self.events = events.AsyncEventsWithStreamingResponse(client.events) + self.financial_accounts = financial_accounts.AsyncFinancialAccountsWithStreamingResponse( + client.financial_accounts + ) + self.transactions = transactions.AsyncTransactionsWithStreamingResponse(client.transactions) + self.responder_endpoints = responder_endpoints.AsyncResponderEndpointsWithStreamingResponse( + client.responder_endpoints + ) + self.external_bank_accounts = external_bank_accounts.AsyncExternalBankAccountsWithStreamingResponse( client.external_bank_accounts ) - self.payments = resources.AsyncPaymentsWithStreamingResponse(client.payments) - self.three_ds = resources.AsyncThreeDSWithStreamingResponse(client.three_ds) - self.reports = resources.AsyncReportsWithStreamingResponse(client.reports) - self.card_programs = resources.AsyncCardProgramsWithStreamingResponse(client.card_programs) - self.digital_card_art = resources.AsyncDigitalCardArtResourceWithStreamingResponse(client.digital_card_art) - self.book_transfers = resources.AsyncBookTransfersWithStreamingResponse(client.book_transfers) - self.credit_products = resources.AsyncCreditProductsWithStreamingResponse(client.credit_products) - self.external_payments = resources.AsyncExternalPaymentsWithStreamingResponse(client.external_payments) - self.management_operations = resources.AsyncManagementOperationsWithStreamingResponse( + self.payments = payments.AsyncPaymentsWithStreamingResponse(client.payments) + self.three_ds = three_ds.AsyncThreeDSWithStreamingResponse(client.three_ds) + self.reports = reports.AsyncReportsWithStreamingResponse(client.reports) + self.card_programs = card_programs.AsyncCardProgramsWithStreamingResponse(client.card_programs) + self.digital_card_art = digital_card_art.AsyncDigitalCardArtResourceWithStreamingResponse( + client.digital_card_art + ) + self.book_transfers = book_transfers.AsyncBookTransfersWithStreamingResponse(client.book_transfers) + self.credit_products = credit_products.AsyncCreditProductsWithStreamingResponse(client.credit_products) + self.external_payments = external_payments.AsyncExternalPaymentsWithStreamingResponse(client.external_payments) + self.management_operations = management_operations.AsyncManagementOperationsWithStreamingResponse( client.management_operations ) From 6412dcd78bae44cd35a742c357ec1e56948144e1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:15:11 +0000 Subject: [PATCH 06/30] chore(api): new ConvertPhysical endpoint to convert a virtual card to a physical card (#656) - adds `name` and `excluded_card_tokens` params to AuthRules - adds `CARD_TRANSACTION_COUNT` attributes to AuthRules - adds `pin` to Transaction simulations - small updates to documentation on Cards - adds `card.converted` Event - adds `RETURNED_PAYMENT` and `RETURNED_PAYMENT_REVERSAL` Event types --- .stats.yml | 2 +- api.md | 1 + src/lithic/resources/auth_rules/v2/v2.py | 64 ++++- src/lithic/resources/cards/cards.py | 237 +++++++++++++++--- src/lithic/resources/events/events.py | 2 + src/lithic/resources/events/subscriptions.py | 6 + src/lithic/resources/management_operations.py | 4 + .../resources/transactions/transactions.py | 8 + src/lithic/types/__init__.py | 1 + .../types/auth_rules/v2_apply_params.py | 3 + .../types/auth_rules/v2_apply_response.py | 18 ++ .../types/auth_rules/v2_create_params.py | 32 ++- .../types/auth_rules/v2_create_response.py | 18 ++ .../types/auth_rules/v2_draft_params.py | 6 + .../types/auth_rules/v2_draft_response.py | 18 ++ .../types/auth_rules/v2_list_response.py | 18 ++ .../types/auth_rules/v2_promote_response.py | 18 ++ .../types/auth_rules/v2_retrieve_response.py | 18 ++ .../types/auth_rules/v2_update_params.py | 4 + .../types/auth_rules/v2_update_response.py | 18 ++ src/lithic/types/card.py | 5 +- .../types/card_convert_physical_params.py | 41 +++ src/lithic/types/card_create_params.py | 7 +- src/lithic/types/event.py | 3 + src/lithic/types/event_list_params.py | 1 + src/lithic/types/event_subscription.py | 1 + .../events/subscription_create_params.py | 1 + ...scription_send_simulated_example_params.py | 1 + .../events/subscription_update_params.py | 1 + .../statements/line_item_list_response.py | 2 + .../statements/statement_line_items.py | 2 + src/lithic/types/financial_transaction.py | 2 + .../management_operation_create_params.py | 2 + .../types/management_operation_transaction.py | 2 + src/lithic/types/transaction.py | 55 ++++ ...ansaction_simulate_authorization_params.py | 3 + tests/api_resources/auth_rules/test_v2.py | 28 +++ tests/api_resources/test_account_holders.py | 72 +++--- tests/api_resources/test_cards.py | 206 ++++++++++++++- tests/api_resources/test_transactions.py | 2 + 40 files changed, 854 insertions(+), 79 deletions(-) create mode 100644 src/lithic/types/card_convert_physical_params.py diff --git a/.stats.yml b/.stats.yml index 8d78762c..d831e60e 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1 +1 @@ -configured_endpoints: 152 +configured_endpoints: 153 diff --git a/api.md b/api.md index 9ff4ac64..338cf798 100644 --- a/api.md +++ b/api.md @@ -187,6 +187,7 @@ Methods: - client.cards.retrieve(card_token) -> Card - client.cards.update(card_token, \*\*params) -> Card - client.cards.list(\*\*params) -> SyncCursorPage[Card] +- client.cards.convert_physical(card_token, \*\*params) -> Card - client.cards.embed(\*\*params) -> str - client.cards.provision(card_token, \*\*params) -> CardProvisionResponse - client.cards.reissue(card_token, \*\*params) -> Card diff --git a/src/lithic/resources/auth_rules/v2/v2.py b/src/lithic/resources/auth_rules/v2/v2.py index f0c1fd5e..8c74d701 100644 --- a/src/lithic/resources/auth_rules/v2/v2.py +++ b/src/lithic/resources/auth_rules/v2/v2.py @@ -69,6 +69,7 @@ def create( self, *, account_tokens: List[str], + name: Optional[str] | NotGiven = NOT_GIVEN, parameters: v2_create_params.CreateAuthRuleRequestAccountTokensParameters | NotGiven = NOT_GIVEN, type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT"] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -84,6 +85,8 @@ def create( Args: account_tokens: Account tokens to which the Auth Rule applies. + name: Auth Rule Name + parameters: Parameters for the current version of the Auth Rule type: The type of Auth Rule @@ -103,6 +106,7 @@ def create( self, *, card_tokens: List[str], + name: Optional[str] | NotGiven = NOT_GIVEN, parameters: v2_create_params.CreateAuthRuleRequestCardTokensParameters | NotGiven = NOT_GIVEN, type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT"] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -118,6 +122,8 @@ def create( Args: card_tokens: Card tokens to which the Auth Rule applies. + name: Auth Rule Name + parameters: Parameters for the current version of the Auth Rule type: The type of Auth Rule @@ -137,6 +143,8 @@ def create( self, *, program_level: bool, + excluded_card_tokens: List[str] | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, parameters: v2_create_params.CreateAuthRuleRequestProgramLevelParameters | NotGiven = NOT_GIVEN, type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT"] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -152,6 +160,10 @@ def create( Args: program_level: Whether the Auth Rule applies to all authorizations on the card program. + excluded_card_tokens: Card tokens to which the Auth Rule does not apply. + + name: Auth Rule Name + parameters: Parameters for the current version of the Auth Rule type: The type of Auth Rule @@ -171,10 +183,12 @@ def create( self, *, account_tokens: List[str] | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, parameters: v2_create_params.CreateAuthRuleRequestAccountTokensParameters | NotGiven = NOT_GIVEN, type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT"] | NotGiven = NOT_GIVEN, card_tokens: List[str] | NotGiven = NOT_GIVEN, program_level: bool | NotGiven = NOT_GIVEN, + excluded_card_tokens: List[str] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -187,10 +201,12 @@ def create( body=maybe_transform( { "account_tokens": account_tokens, + "name": name, "parameters": parameters, "type": type, "card_tokens": card_tokens, "program_level": program_level, + "excluded_card_tokens": excluded_card_tokens, }, v2_create_params.V2CreateParams, ), @@ -237,6 +253,7 @@ def update( self, auth_rule_token: str, *, + name: Optional[str] | NotGiven = NOT_GIVEN, state: Literal["INACTIVE"] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -249,6 +266,8 @@ def update( Updates an authorization rule's properties Args: + name: Auth Rule Name + state: The desired state of the Auth Rule. Note that only deactivating an Auth Rule through this endpoint is supported at @@ -267,7 +286,13 @@ def update( raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return self._patch( f"/v2/auth_rules/{auth_rule_token}", - body=maybe_transform({"state": state}, v2_update_params.V2UpdateParams), + body=maybe_transform( + { + "name": name, + "state": state, + }, + v2_update_params.V2UpdateParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -407,6 +432,7 @@ def apply( auth_rule_token: str, *, program_level: bool, + excluded_card_tokens: List[str] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -424,6 +450,8 @@ def apply( Args: program_level: Whether the Auth Rule applies to all authorizations on the card program. + excluded_card_tokens: Card tokens to which the Auth Rule does not apply. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -442,6 +470,7 @@ def apply( account_tokens: List[str] | NotGiven = NOT_GIVEN, card_tokens: List[str] | NotGiven = NOT_GIVEN, program_level: bool | NotGiven = NOT_GIVEN, + excluded_card_tokens: List[str] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -458,6 +487,7 @@ def apply( "account_tokens": account_tokens, "card_tokens": card_tokens, "program_level": program_level, + "excluded_card_tokens": excluded_card_tokens, }, v2_apply_params.V2ApplyParams, ), @@ -655,6 +685,7 @@ async def create( self, *, account_tokens: List[str], + name: Optional[str] | NotGiven = NOT_GIVEN, parameters: v2_create_params.CreateAuthRuleRequestAccountTokensParameters | NotGiven = NOT_GIVEN, type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT"] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -670,6 +701,8 @@ async def create( Args: account_tokens: Account tokens to which the Auth Rule applies. + name: Auth Rule Name + parameters: Parameters for the current version of the Auth Rule type: The type of Auth Rule @@ -689,6 +722,7 @@ async def create( self, *, card_tokens: List[str], + name: Optional[str] | NotGiven = NOT_GIVEN, parameters: v2_create_params.CreateAuthRuleRequestCardTokensParameters | NotGiven = NOT_GIVEN, type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT"] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -704,6 +738,8 @@ async def create( Args: card_tokens: Card tokens to which the Auth Rule applies. + name: Auth Rule Name + parameters: Parameters for the current version of the Auth Rule type: The type of Auth Rule @@ -723,6 +759,8 @@ async def create( self, *, program_level: bool, + excluded_card_tokens: List[str] | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, parameters: v2_create_params.CreateAuthRuleRequestProgramLevelParameters | NotGiven = NOT_GIVEN, type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT"] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -738,6 +776,10 @@ async def create( Args: program_level: Whether the Auth Rule applies to all authorizations on the card program. + excluded_card_tokens: Card tokens to which the Auth Rule does not apply. + + name: Auth Rule Name + parameters: Parameters for the current version of the Auth Rule type: The type of Auth Rule @@ -757,10 +799,12 @@ async def create( self, *, account_tokens: List[str] | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, parameters: v2_create_params.CreateAuthRuleRequestAccountTokensParameters | NotGiven = NOT_GIVEN, type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT"] | NotGiven = NOT_GIVEN, card_tokens: List[str] | NotGiven = NOT_GIVEN, program_level: bool | NotGiven = NOT_GIVEN, + excluded_card_tokens: List[str] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -773,10 +817,12 @@ async def create( body=await async_maybe_transform( { "account_tokens": account_tokens, + "name": name, "parameters": parameters, "type": type, "card_tokens": card_tokens, "program_level": program_level, + "excluded_card_tokens": excluded_card_tokens, }, v2_create_params.V2CreateParams, ), @@ -823,6 +869,7 @@ async def update( self, auth_rule_token: str, *, + name: Optional[str] | NotGiven = NOT_GIVEN, state: Literal["INACTIVE"] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -835,6 +882,8 @@ async def update( Updates an authorization rule's properties Args: + name: Auth Rule Name + state: The desired state of the Auth Rule. Note that only deactivating an Auth Rule through this endpoint is supported at @@ -853,7 +902,13 @@ async def update( raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return await self._patch( f"/v2/auth_rules/{auth_rule_token}", - body=await async_maybe_transform({"state": state}, v2_update_params.V2UpdateParams), + body=await async_maybe_transform( + { + "name": name, + "state": state, + }, + v2_update_params.V2UpdateParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -993,6 +1048,7 @@ async def apply( auth_rule_token: str, *, program_level: bool, + excluded_card_tokens: List[str] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -1010,6 +1066,8 @@ async def apply( Args: program_level: Whether the Auth Rule applies to all authorizations on the card program. + excluded_card_tokens: Card tokens to which the Auth Rule does not apply. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1028,6 +1086,7 @@ async def apply( account_tokens: List[str] | NotGiven = NOT_GIVEN, card_tokens: List[str] | NotGiven = NOT_GIVEN, program_level: bool | NotGiven = NOT_GIVEN, + excluded_card_tokens: List[str] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -1044,6 +1103,7 @@ async def apply( "account_tokens": account_tokens, "card_tokens": card_tokens, "program_level": program_level, + "excluded_card_tokens": excluded_card_tokens, }, v2_apply_params.V2ApplyParams, ), diff --git a/src/lithic/resources/cards/cards.py b/src/lithic/resources/cards/cards.py index 1139d633..62deb93c 100644 --- a/src/lithic/resources/cards/cards.py +++ b/src/lithic/resources/cards/cards.py @@ -25,6 +25,7 @@ card_provision_params, card_get_embed_url_params, card_search_by_pan_params, + card_convert_physical_params, ) from ..._types import ( NOT_GIVEN, @@ -140,7 +141,7 @@ def create( ) -> Card: """Create a new virtual or physical card. - Parameters `pin`, `shipping_address`, and + Parameters `shipping_address` and `product_id` only apply to physical cards. Args: @@ -187,7 +188,7 @@ def create( memo: Friendly name to identify the card. - pin: Encrypted PIN block (in base64). Only applies to cards of type `PHYSICAL` and + pin: Encrypted PIN block (in base64). Applies to cards of type `PHYSICAL` and `VIRTUAL`. See [Encrypted PIN Block](https://docs.lithic.com/docs/cards#encrypted-pin-block). @@ -201,8 +202,9 @@ def create( If `replacement_for` is specified and this field is omitted, the replacement card's account will be inferred from the card being replaced. - replacement_for: Only applicable to cards of type `PHYSICAL`. Globally unique identifier for the - card that this physical card will replace. + replacement_for: Globally unique identifier for the card that this card will replace. If the card + type is `PHYSICAL` it will be replaced by a `PHYSICAL` card. If the card type is + `VIRTUAL` it will be replaced by a `VIRTUAL` card. shipping_method: Shipping method for the card. Only applies to cards of type PHYSICAL. Use of options besides `STANDARD` require additional permissions. @@ -337,7 +339,7 @@ def update( """Update the specified properties of the card. Unsupplied properties will remain - unchanged. `pin` parameter only applies to physical cards. + unchanged. _Note: setting a card to a `CLOSED` state is a final action that cannot be undone._ @@ -488,6 +490,84 @@ def list( model=Card, ) + def convert_physical( + self, + card_token: str, + *, + shipping_address: ShippingAddress, + carrier: Carrier | NotGiven = NOT_GIVEN, + product_id: str | NotGiven = NOT_GIVEN, + shipping_method: Literal["2-DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"] + | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Card: + """Convert a virtual card into a physical card and manufacture it. + + Customer must + supply relevant fields for physical card creation including `product_id`, + `carrier`, `shipping_method`, and `shipping_address`. The card token will be + unchanged. The card's type will be altered to `PHYSICAL`. The card will be set + to state `PENDING_FULFILLMENT` and fulfilled at next fulfillment cycle. Virtual + cards created on card programs which do not support physical cards cannot be + converted. The card program cannot be changed as part of the conversion. Cards + must be in a state of either `OPEN` or `PAUSED` to be converted. Only applies to + cards of type `VIRTUAL` (or existing cards with deprecated types of + `DIGITAL_WALLET` and `UNLOCKED`). + + Args: + shipping_address: The shipping address this card will be sent to. + + carrier: If omitted, the previous carrier will be used. + + product_id: Specifies the configuration (e.g. physical card art) that the card should be + manufactured with, and only applies to cards of type `PHYSICAL`. This must be + configured with Lithic before use. + + shipping_method: Shipping method for the card. Use of options besides `STANDARD` require + additional permissions. + + - `STANDARD` - USPS regular mail or similar international option, with no + tracking + - `STANDARD_WITH_TRACKING` - USPS regular mail or similar international option, + with tracking + - `PRIORITY` - USPS Priority, 1-3 day shipping, with tracking + - `EXPRESS` - FedEx Express, 3-day shipping, with tracking + - `2_DAY` - FedEx 2-day shipping, with tracking + - `EXPEDITED` - FedEx Standard Overnight or similar international option, with + tracking + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not card_token: + raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") + return self._post( + f"/v1/cards/{card_token}/convert_physical", + body=maybe_transform( + { + "shipping_address": shipping_address, + "carrier": carrier, + "product_id": product_id, + "shipping_method": shipping_method, + }, + card_convert_physical_params.CardConvertPhysicalParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Card, + ) + def embed( self, *, @@ -510,9 +590,10 @@ def embed( that we provide, optionally styled in the customer's branding using a specified css stylesheet. A user's browser makes the request directly to api.lithic.com, so card PANs and CVVs never touch the API customer's servers while full card - data is displayed to their end-users. The response contains an HTML document. - This means that the url for the request can be inserted straight into the `src` - attribute of an iframe. + data is displayed to their end-users. The response contains an HTML document + (see Embedded Card UI or Changelog for upcoming changes in January). This means + that the url for the request can be inserted straight into the `src` attribute + of an iframe. ```html