diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 58ebf7f2..cadbcc6f 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.123.0" + ".": "0.124.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fdca44b..c786557b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [0.124.0](https://github.com/kernel/kernel-python-sdk/compare/v0.123.0...v0.124.0) (2026-10-13) + + +### Features + +* Accept intent creation without a fixed status ([e6e016a](https://github.com/kernel/kernel-python-sdk/commit/e6e016a5cea493c505b16a05cb8ad2fa6ed9f13b)) +* Complete Visa vault verification and transaction reporting ([fc4b0de](https://github.com/kernel/kernel-python-sdk/commit/fc4b0de79e3242361ef7b11acbd2cbaeb058265e)) + + +### Bug Fixes + +* seal browser pool acquire SDK results ([4d81af2](https://github.com/kernel/kernel-python-sdk/commit/4d81af2b6103571b59cd1bb520eb85e28488b51c)) + ## [0.123.0](https://github.com/kernel/kernel-python-sdk/compare/v0.122.0...v0.123.0) (2026-10-09) diff --git a/api.md b/api.md index 1b71010c..f5243e5a 100644 --- a/api.md +++ b/api.md @@ -571,6 +571,7 @@ from kernel.types.vaults import ( CardVaultItemSpec, CardVaultItemState, CollectVaultItemOperationRequest, + ConfirmTransactionVaultItemOperationRequest, CredentialAccountVaultItem, CredentialAccountVaultItemRequest, CredentialCollectionAction, @@ -610,6 +611,7 @@ from kernel.types.vaults import ( OnePasswordRecoverVaultItemOperationRequest, OnePasswordRequestAccessVaultItemOperationRequest, PrepareCheckoutVaultItemOperationRequest, + RestartVerificationVaultItemOperationRequest, VaultCardAliases, VaultCardFillField, VaultCheckoutContext, diff --git a/pyproject.toml b/pyproject.toml index 6e2be1a4..d86abd33 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kernel" -version = "0.123.0" +version = "0.124.0" description = "The official Python library for the kernel API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/kernel/_response.py b/src/kernel/_response.py index a6c5fa30..95d81625 100644 --- a/src/kernel/_response.py +++ b/src/kernel/_response.py @@ -24,7 +24,7 @@ import httpx import pydantic -from ._types import NoneType +from ._types import NoneType, NoContentAsNone 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 @@ -185,6 +185,13 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T: return cast(R, None) response = self.http_response + if ( + response.status_code == 204 + and to is None + and isinstance(origin, type) + and issubclass(origin, NoContentAsNone) + ): + return cast(R, None) if cast_to == str: return cast(R, response.text) diff --git a/src/kernel/_types.py b/src/kernel/_types.py index d924c204..94982715 100644 --- a/src/kernel/_types.py +++ b/src/kernel/_types.py @@ -44,6 +44,12 @@ Query = Mapping[str, object] Body = object AnyMapping = Mapping[str, object] + + +class NoContentAsNone: + pass + + ModelT = TypeVar("ModelT", bound=pydantic.BaseModel) _T = TypeVar("_T") diff --git a/src/kernel/_version.py b/src/kernel/_version.py index f0320775..e084d175 100644 --- a/src/kernel/_version.py +++ b/src/kernel/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "kernel" -__version__ = "0.123.0" # x-release-please-version +__version__ = "0.124.0" # x-release-please-version diff --git a/src/kernel/resources/browser_pools.py b/src/kernel/resources/browser_pools.py index 5fc7147a..645c0d27 100644 --- a/src/kernel/resources/browser_pools.py +++ b/src/kernel/resources/browser_pools.py @@ -542,7 +542,7 @@ def acquire( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> BrowserPoolAcquireResponse: + ) -> Optional[BrowserPoolAcquireResponse]: """Long-polling endpoint to acquire a browser from the pool. Returns immediately @@ -1199,7 +1199,7 @@ async def acquire( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> BrowserPoolAcquireResponse: + ) -> Optional[BrowserPoolAcquireResponse]: """Long-polling endpoint to acquire a browser from the pool. Returns immediately diff --git a/src/kernel/resources/browsers/playwright/playwright.py b/src/kernel/resources/browsers/playwright/playwright.py index 50ddf810..00f5f10e 100644 --- a/src/kernel/resources/browsers/playwright/playwright.py +++ b/src/kernel/resources/browsers/playwright/playwright.py @@ -114,10 +114,6 @@ def execute( executors are not removed automatically while the browser runs; when it shuts down, they are removed and their tabs closed. - A named call to a browser whose image predates executors fails with 400 instead - of running on the active tab; calls without 'executor' keep working on every - image. - Args: code: TypeScript/JavaScript code to execute. The code has access to 'page', 'context', and 'browser' variables. It runs within a function, so you can use a return @@ -244,10 +240,6 @@ async def execute( executors are not removed automatically while the browser runs; when it shuts down, they are removed and their tabs closed. - A named call to a browser whose image predates executors fails with 400 instead - of running on the active tab; calls without 'executor' keep working on every - image. - Args: code: TypeScript/JavaScript code to execute. The code has access to 'page', 'context', and 'browser' variables. It runs within a function, so you can use a return diff --git a/src/kernel/resources/vaults/items.py b/src/kernel/resources/vaults/items.py index badbd5bc..79ca2ced 100644 --- a/src/kernel/resources/vaults/items.py +++ b/src/kernel/resources/vaults/items.py @@ -440,6 +440,113 @@ def perform_operation( """ ... + @overload + def perform_operation( + self, + key: str, + *, + id_or_name: str, + type: Literal["restart_verification"], + # 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, + ) -> VaultItemOperationResponse: + """ + Retrieve the item first and invoke only an operation listed in + `available_operations`, following its natural-language description. Availability + is rechecked at execution time; unavailable operations return 409. Authorization + and preparation may call an external provider and return updated state. Link + cards advertise authorize without checkout context. Eligible unused AgentCard + cards advertise prepare_checkout, which requires checkout context and obtains + device approval before native Square Pay. Keep the returned approval page open, + poll until ready_to_submit, then submit before preparation.expires_at. Unused + preparations expire automatically and cannot be reused. If spend-request + creation is rejected with a non-retryable provider error, the card item is + deleted and the provider's error code and message are returned. Rate limits + return HTTP 429 and retain the card item; stop, back off, and retry the same + authorize operation. + + Fill returns a value-free execution result. Validation failures before writing + return 400 (invalid request or targets), 403 (access or destination denied), 404 + (resource not found), or 409 (item or browser not ready). Once writing starts, + known partial failures and indeterminate field outcomes return 200 with status + `failed` or `unknown`. Fill never submits the page, so it is safe to retry after + a failure, an `unknown` outcome, or a transport error. + + Args: + 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 + """ + ... + + @overload + def perform_operation( + self, + key: str, + *, + id_or_name: str, + amount: int, + currency: str, + occurred_at: Union[str, datetime], + status: Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"], + transaction_type: Literal[ + "PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD" + ], + type: Literal["confirm_transaction"], + # 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, + ) -> VaultItemOperationResponse: + """ + Retrieve the item first and invoke only an operation listed in + `available_operations`, following its natural-language description. Availability + is rechecked at execution time; unavailable operations return 409. Authorization + and preparation may call an external provider and return updated state. Link + cards advertise authorize without checkout context. Eligible unused AgentCard + cards advertise prepare_checkout, which requires checkout context and obtains + device approval before native Square Pay. Keep the returned approval page open, + poll until ready_to_submit, then submit before preparation.expires_at. Unused + preparations expire automatically and cannot be reused. If spend-request + creation is rejected with a non-retryable provider error, the card item is + deleted and the provider's error code and message are returned. Rate limits + return HTTP 429 and retain the card item; stop, back off, and retry the same + authorize operation. + + Fill returns a value-free execution result. Validation failures before writing + return 400 (invalid request or targets), 403 (access or destination denied), 404 + (resource not found), or 409 (item or browser not ready). Once writing starts, + known partial failures and indeterminate field outcomes return 200 with status + `failed` or `unknown`. Fill never submits the page, so it is safe to retry after + a failure, an `unknown` outcome, or a transport error. + + Args: + amount: Actual transaction amount in minor units, no greater than the approved limit. + + currency: Must match the approved purchase currency. + + occurred_at: Time the merchant outcome was observed. + + 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 + """ + ... + @overload def perform_operation( self, @@ -928,6 +1035,7 @@ def perform_operation( @required_args( ["id_or_name", "type"], + ["id_or_name", "amount", "currency", "occurred_at", "status", "transaction_type", "type"], ["id_or_name", "checkout", "type"], ["id_or_name", "browser_id", "fields", "type"], ["id_or_name", "browser_id", "page_url", "type"], @@ -940,6 +1048,8 @@ def perform_operation( *, id_or_name: str, type: Literal["authorize"] + | Literal["restart_verification"] + | Literal["confirm_transaction"] | Literal["collect"] | Literal["prepare_checkout"] | Literal["fill"] @@ -949,6 +1059,14 @@ def perform_operation( | Literal["1pw_recover"] | Literal["1pw_update_access_token"] | Literal["webmcp_invoke"], + amount: int | Omit = omit, + currency: str | Omit = omit, + occurred_at: Union[str, datetime] | Omit = omit, + status: Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"] | Omit = omit, + transaction_type: Literal[ + "PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD" + ] + | Omit = omit, checkout: VaultCheckoutContextParam | Omit = omit, browser_id: str | Omit = omit, fields: Iterable[VaultFillFieldParam] | Omit = omit, @@ -983,6 +1101,11 @@ def perform_operation( body=maybe_transform( { "type": type, + "amount": amount, + "currency": currency, + "occurred_at": occurred_at, + "status": status, + "transaction_type": transaction_type, "checkout": checkout, "browser_id": browser_id, "fields": fields, @@ -1614,6 +1737,113 @@ async def perform_operation( """ ... + @overload + async def perform_operation( + self, + key: str, + *, + id_or_name: str, + type: Literal["restart_verification"], + # 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, + ) -> VaultItemOperationResponse: + """ + Retrieve the item first and invoke only an operation listed in + `available_operations`, following its natural-language description. Availability + is rechecked at execution time; unavailable operations return 409. Authorization + and preparation may call an external provider and return updated state. Link + cards advertise authorize without checkout context. Eligible unused AgentCard + cards advertise prepare_checkout, which requires checkout context and obtains + device approval before native Square Pay. Keep the returned approval page open, + poll until ready_to_submit, then submit before preparation.expires_at. Unused + preparations expire automatically and cannot be reused. If spend-request + creation is rejected with a non-retryable provider error, the card item is + deleted and the provider's error code and message are returned. Rate limits + return HTTP 429 and retain the card item; stop, back off, and retry the same + authorize operation. + + Fill returns a value-free execution result. Validation failures before writing + return 400 (invalid request or targets), 403 (access or destination denied), 404 + (resource not found), or 409 (item or browser not ready). Once writing starts, + known partial failures and indeterminate field outcomes return 200 with status + `failed` or `unknown`. Fill never submits the page, so it is safe to retry after + a failure, an `unknown` outcome, or a transport error. + + Args: + 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 + """ + ... + + @overload + async def perform_operation( + self, + key: str, + *, + id_or_name: str, + amount: int, + currency: str, + occurred_at: Union[str, datetime], + status: Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"], + transaction_type: Literal[ + "PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD" + ], + type: Literal["confirm_transaction"], + # 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, + ) -> VaultItemOperationResponse: + """ + Retrieve the item first and invoke only an operation listed in + `available_operations`, following its natural-language description. Availability + is rechecked at execution time; unavailable operations return 409. Authorization + and preparation may call an external provider and return updated state. Link + cards advertise authorize without checkout context. Eligible unused AgentCard + cards advertise prepare_checkout, which requires checkout context and obtains + device approval before native Square Pay. Keep the returned approval page open, + poll until ready_to_submit, then submit before preparation.expires_at. Unused + preparations expire automatically and cannot be reused. If spend-request + creation is rejected with a non-retryable provider error, the card item is + deleted and the provider's error code and message are returned. Rate limits + return HTTP 429 and retain the card item; stop, back off, and retry the same + authorize operation. + + Fill returns a value-free execution result. Validation failures before writing + return 400 (invalid request or targets), 403 (access or destination denied), 404 + (resource not found), or 409 (item or browser not ready). Once writing starts, + known partial failures and indeterminate field outcomes return 200 with status + `failed` or `unknown`. Fill never submits the page, so it is safe to retry after + a failure, an `unknown` outcome, or a transport error. + + Args: + amount: Actual transaction amount in minor units, no greater than the approved limit. + + currency: Must match the approved purchase currency. + + occurred_at: Time the merchant outcome was observed. + + 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 + """ + ... + @overload async def perform_operation( self, @@ -2102,6 +2332,7 @@ async def perform_operation( @required_args( ["id_or_name", "type"], + ["id_or_name", "amount", "currency", "occurred_at", "status", "transaction_type", "type"], ["id_or_name", "checkout", "type"], ["id_or_name", "browser_id", "fields", "type"], ["id_or_name", "browser_id", "page_url", "type"], @@ -2114,6 +2345,8 @@ async def perform_operation( *, id_or_name: str, type: Literal["authorize"] + | Literal["restart_verification"] + | Literal["confirm_transaction"] | Literal["collect"] | Literal["prepare_checkout"] | Literal["fill"] @@ -2123,6 +2356,14 @@ async def perform_operation( | Literal["1pw_recover"] | Literal["1pw_update_access_token"] | Literal["webmcp_invoke"], + amount: int | Omit = omit, + currency: str | Omit = omit, + occurred_at: Union[str, datetime] | Omit = omit, + status: Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"] | Omit = omit, + transaction_type: Literal[ + "PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD" + ] + | Omit = omit, checkout: VaultCheckoutContextParam | Omit = omit, browser_id: str | Omit = omit, fields: Iterable[VaultFillFieldParam] | Omit = omit, @@ -2157,6 +2398,11 @@ async def perform_operation( body=await async_maybe_transform( { "type": type, + "amount": amount, + "currency": currency, + "occurred_at": occurred_at, + "status": status, + "transaction_type": transaction_type, "checkout": checkout, "browser_id": browser_id, "fields": fields, diff --git a/src/kernel/types/browser_pool_acquire_response.py b/src/kernel/types/browser_pool_acquire_response.py index 4cbda2d3..8791bb7b 100644 --- a/src/kernel/types/browser_pool_acquire_response.py +++ b/src/kernel/types/browser_pool_acquire_response.py @@ -5,6 +5,7 @@ from typing_extensions import Literal from .tags import Tags +from .._types import NoContentAsNone from .profile import Profile from .._models import BaseModel from .browser_proxy import BrowserProxy @@ -20,7 +21,7 @@ __all__ = ["BrowserPoolAcquireResponse"] -class BrowserPoolAcquireResponse(BaseModel): +class BrowserPoolAcquireResponse(NoContentAsNone, BaseModel): cdp_ws_url: str """Websocket URL for Chrome DevTools Protocol connections to the browser session""" diff --git a/src/kernel/types/vaults/__init__.py b/src/kernel/types/vaults/__init__.py index dc84fc10..ff4183c4 100644 --- a/src/kernel/types/vaults/__init__.py +++ b/src/kernel/types/vaults/__init__.py @@ -113,9 +113,15 @@ from .one_password_fill_vault_item_operation_request_param import ( OnePasswordFillVaultItemOperationRequestParam as OnePasswordFillVaultItemOperationRequestParam, ) +from .confirm_transaction_vault_item_operation_request_param import ( + ConfirmTransactionVaultItemOperationRequestParam as ConfirmTransactionVaultItemOperationRequestParam, +) from .one_password_recover_vault_item_operation_request_param import ( OnePasswordRecoverVaultItemOperationRequestParam as OnePasswordRecoverVaultItemOperationRequestParam, ) +from .restart_verification_vault_item_operation_request_param import ( + RestartVerificationVaultItemOperationRequestParam as RestartVerificationVaultItemOperationRequestParam, +) from .one_password_request_access_vault_item_operation_request_param import ( OnePasswordRequestAccessVaultItemOperationRequestParam as OnePasswordRequestAccessVaultItemOperationRequestParam, ) diff --git a/src/kernel/types/vaults/confirm_transaction_vault_item_operation_request_param.py b/src/kernel/types/vaults/confirm_transaction_vault_item_operation_request_param.py new file mode 100644 index 00000000..3b0e0485 --- /dev/null +++ b/src/kernel/types/vaults/confirm_transaction_vault_item_operation_request_param.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["ConfirmTransactionVaultItemOperationRequestParam"] + + +class ConfirmTransactionVaultItemOperationRequestParam(TypedDict, total=False): + """Report a real merchant transaction outcome for an issued Kernel Visa credential. + + Never infer success from filling checkout or receiving a credential. Supply the observed status, transaction type, actual amount, currency and timestamp. Unknown outcomes require manual reconciliation, not retry. Each purchase accepts one report. + """ + + amount: Required[int] + """Actual transaction amount in minor units, no greater than the approved limit.""" + + currency: Required[str] + """Must match the approved purchase currency.""" + + occurred_at: Required[Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]] + """Time the merchant outcome was observed.""" + + status: Required[Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"]] + + transaction_type: Required[ + Literal["PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD"] + ] + + type: Required[Literal["confirm_transaction"]] diff --git a/src/kernel/types/vaults/credential_account_vault_item.py b/src/kernel/types/vaults/credential_account_vault_item.py index 109d5ce3..a049c193 100644 --- a/src/kernel/types/vaults/credential_account_vault_item.py +++ b/src/kernel/types/vaults/credential_account_vault_item.py @@ -32,6 +32,8 @@ class AvailableOperation(BaseModel): type: Literal[ "authorize", + "restart_verification", + "confirm_transaction", "collect", "prepare_checkout", "fill", diff --git a/src/kernel/types/vaults/credential_vault_item.py b/src/kernel/types/vaults/credential_vault_item.py index 2f28e21b..f9bd1158 100644 --- a/src/kernel/types/vaults/credential_vault_item.py +++ b/src/kernel/types/vaults/credential_vault_item.py @@ -39,6 +39,8 @@ class AvailableOperation(BaseModel): type: Literal[ "authorize", + "restart_verification", + "confirm_transaction", "collect", "prepare_checkout", "fill", diff --git a/src/kernel/types/vaults/item_perform_operation_params.py b/src/kernel/types/vaults/item_perform_operation_params.py index 0abfc780..3db75e75 100644 --- a/src/kernel/types/vaults/item_perform_operation_params.py +++ b/src/kernel/types/vaults/item_perform_operation_params.py @@ -15,6 +15,8 @@ __all__ = [ "ItemPerformOperationParams", "AuthorizeVaultItemOperationRequest", + "RestartVerificationVaultItemOperationRequest", + "ConfirmTransactionVaultItemOperationRequest", "CollectVaultItemOperationRequest", "PrepareCheckoutVaultItemOperationRequest", "FillVaultItemOperationRequest", @@ -33,6 +35,33 @@ class AuthorizeVaultItemOperationRequest(TypedDict, total=False): type: Required[Literal["authorize"]] +class RestartVerificationVaultItemOperationRequest(TypedDict, total=False): + id_or_name: Required[str] + + type: Required[Literal["restart_verification"]] + + +class ConfirmTransactionVaultItemOperationRequest(TypedDict, total=False): + id_or_name: Required[str] + + amount: Required[int] + """Actual transaction amount in minor units, no greater than the approved limit.""" + + currency: Required[str] + """Must match the approved purchase currency.""" + + occurred_at: Required[Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]] + """Time the merchant outcome was observed.""" + + status: Required[Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"]] + + transaction_type: Required[ + Literal["PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD"] + ] + + type: Required[Literal["confirm_transaction"]] + + class CollectVaultItemOperationRequest(TypedDict, total=False): id_or_name: Required[str] @@ -173,6 +202,8 @@ class WebmcpInvokeVaultItemOperationRequest(TypedDict, total=False): ItemPerformOperationParams: TypeAlias = Union[ AuthorizeVaultItemOperationRequest, + RestartVerificationVaultItemOperationRequest, + ConfirmTransactionVaultItemOperationRequest, CollectVaultItemOperationRequest, PrepareCheckoutVaultItemOperationRequest, FillVaultItemOperationRequest, diff --git a/src/kernel/types/vaults/kernel_card_state.py b/src/kernel/types/vaults/kernel_card_state.py index 6983c617..047b5f9e 100644 --- a/src/kernel/types/vaults/kernel_card_state.py +++ b/src/kernel/types/vaults/kernel_card_state.py @@ -44,12 +44,16 @@ class KernelCardState(BaseModel): """ pending_authorization on a Visa purchase waits for the cardholder to approve it through the spend_approval action; an unused link expires after 30 minutes. - recovery_required means approving the purchase or issuing the one-time code has - an unresolved outcome. Kernel never approves again or issues another code for - the item automatically, and the item cannot be deleted or replaced until the - original attempt is reconciled with support. When status_reason says the - provider refused retrieval before acceptance, no code was issued and a later - read retries. declined means the card network refused to issue a code. + recovery_required means verification, approving the purchase or issuing the + one-time code has an unresolved outcome. A server-classified initial attestation + failure before intent dispatch may advertise restart_verification to prepare a + fresh local verification link; this does not approve spending or replay any + provider request. Unclassified legacy recovery and uncertain intent creation + cannot restart. Kernel never approves again or issues another code for the item + automatically, and the item cannot be deleted or replaced until the original + attempt is reconciled with support. When status_reason says the provider refused + retrieval before acceptance, no code was issued and a later read retries. + declined means the card network refused to issue a code. """ domains: Optional[List[str]] = None diff --git a/src/kernel/types/vaults/kernel_card_vault_item_spec.py b/src/kernel/types/vaults/kernel_card_vault_item_spec.py index 85d2d13d..1581c68c 100644 --- a/src/kernel/types/vaults/kernel_card_vault_item_spec.py +++ b/src/kernel/types/vaults/kernel_card_vault_item_spec.py @@ -37,6 +37,15 @@ class KernelCardVaultItemSpec(BaseModel): wallet: str """Key of the Kernel wallet item whose enrolled card pays.""" + merchant_category: Optional[str] = None + """Actual merchant category when known. Omit rather than invent a category.""" + + merchant_category_code: Optional[str] = None + """Actual merchant MCC when known. + + Omit rather than invent a code. 0000 is not accepted. + """ + merchant_country: Optional[str] = None """The merchant's ISO 3166-1 alpha-2 country code. diff --git a/src/kernel/types/vaults/kernel_card_vault_item_spec_param.py b/src/kernel/types/vaults/kernel_card_vault_item_spec_param.py index 096e8c7b..72d6dae8 100644 --- a/src/kernel/types/vaults/kernel_card_vault_item_spec_param.py +++ b/src/kernel/types/vaults/kernel_card_vault_item_spec_param.py @@ -36,6 +36,15 @@ class KernelCardVaultItemSpecParam(TypedDict, total=False): wallet: Required[str] """Key of the Kernel wallet item whose enrolled card pays.""" + merchant_category: str + """Actual merchant category when known. Omit rather than invent a category.""" + + merchant_category_code: str + """Actual merchant MCC when known. + + Omit rather than invent a code. 0000 is not accepted. + """ + merchant_country: str """The merchant's ISO 3166-1 alpha-2 country code. diff --git a/src/kernel/types/vaults/restart_verification_vault_item_operation_request_param.py b/src/kernel/types/vaults/restart_verification_vault_item_operation_request_param.py new file mode 100644 index 00000000..89c4e3db --- /dev/null +++ b/src/kernel/types/vaults/restart_verification_vault_item_operation_request_param.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["RestartVerificationVaultItemOperationRequestParam"] + + +class RestartVerificationVaultItemOperationRequestParam(TypedDict, total=False): + """ + Explicitly prepare a fresh local verification session for the same Kernel Visa purchase and connected wallet, only when restart_verification is advertised. Kernel must have durable proof of an initial attestation failure before intent dispatch. Replaces the spend_approval capability and discards session-bound verification data without calling the provider or granting spend consent. The cardholder must use the new link, verify again and explicitly approve the purchase. Unknown intent creation, legacy unclassified recovery, enrollment completion, issuance and confirmation cannot restart. Do not automatically retry this operation. + """ + + type: Required[Literal["restart_verification"]] diff --git a/src/kernel/types/vaults/vault_item.py b/src/kernel/types/vaults/vault_item.py index c1e8c4f3..697f56d9 100644 --- a/src/kernel/types/vaults/vault_item.py +++ b/src/kernel/types/vaults/vault_item.py @@ -47,6 +47,8 @@ class WalletVaultItemAvailableOperation(BaseModel): type: Literal[ "authorize", + "restart_verification", + "confirm_transaction", "collect", "prepare_checkout", "fill", @@ -122,6 +124,8 @@ class CardVaultItemAvailableOperation(BaseModel): type: Literal[ "authorize", + "restart_verification", + "confirm_transaction", "collect", "prepare_checkout", "fill", diff --git a/src/kernel/types/vaults/vault_item_operation_response.py b/src/kernel/types/vaults/vault_item_operation_response.py index fdc4bf99..0968dab7 100644 --- a/src/kernel/types/vaults/vault_item_operation_response.py +++ b/src/kernel/types/vaults/vault_item_operation_response.py @@ -49,6 +49,8 @@ class WalletVaultItemAvailableOperation(BaseModel): type: Literal[ "authorize", + "restart_verification", + "confirm_transaction", "collect", "prepare_checkout", "fill", @@ -124,6 +126,8 @@ class CardVaultItemAvailableOperation(BaseModel): type: Literal[ "authorize", + "restart_verification", + "confirm_transaction", "collect", "prepare_checkout", "fill", diff --git a/tests/api_resources/vaults/test_items.py b/tests/api_resources/vaults/test_items.py index 0a85a9d1..f69942ef 100644 --- a/tests/api_resources/vaults/test_items.py +++ b/tests/api_resources/vaults/test_items.py @@ -544,7 +544,7 @@ def test_method_perform_operation_overload_2(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", - type="collect", + type="restart_verification", ) assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @@ -554,7 +554,7 @@ def test_raw_response_perform_operation_overload_2(self, client: Kernel) -> None response = client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", - type="collect", + type="restart_verification", ) assert response.is_closed is True @@ -568,7 +568,7 @@ def test_streaming_response_perform_operation_overload_2(self, client: Kernel) - with client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", - type="collect", + type="restart_verification", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -581,6 +581,145 @@ def test_streaming_response_perform_operation_overload_2(self, client: Kernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_path_params_perform_operation_overload_2(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="", + type="restart_verification", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + client.vaults.items.with_raw_response.perform_operation( + key="", + id_or_name="id_or_name", + type="restart_verification", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_perform_operation_overload_3(self, client: Kernel) -> None: + item = client.vaults.items.perform_operation( + key="key", + id_or_name="id_or_name", + amount=0, + currency="SEW", + occurred_at=parse_datetime("2019-12-27T18:11:19.117Z"), + status="APPROVED", + transaction_type="PURCHASE", + type="confirm_transaction", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_perform_operation_overload_3(self, client: Kernel) -> None: + response = client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="id_or_name", + amount=0, + currency="SEW", + occurred_at=parse_datetime("2019-12-27T18:11:19.117Z"), + status="APPROVED", + transaction_type="PURCHASE", + type="confirm_transaction", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_perform_operation_overload_3(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.perform_operation( + key="key", + id_or_name="id_or_name", + amount=0, + currency="SEW", + occurred_at=parse_datetime("2019-12-27T18:11:19.117Z"), + status="APPROVED", + transaction_type="PURCHASE", + type="confirm_transaction", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_perform_operation_overload_3(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="", + amount=0, + currency="SEW", + occurred_at=parse_datetime("2019-12-27T18:11:19.117Z"), + status="APPROVED", + transaction_type="PURCHASE", + type="confirm_transaction", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + client.vaults.items.with_raw_response.perform_operation( + key="", + id_or_name="id_or_name", + amount=0, + currency="SEW", + occurred_at=parse_datetime("2019-12-27T18:11:19.117Z"), + status="APPROVED", + transaction_type="PURCHASE", + type="confirm_transaction", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_perform_operation_overload_4(self, client: Kernel) -> None: + item = client.vaults.items.perform_operation( + key="key", + id_or_name="id_or_name", + type="collect", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_perform_operation_overload_4(self, client: Kernel) -> None: + response = client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="id_or_name", + type="collect", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_perform_operation_overload_4(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.perform_operation( + key="key", + id_or_name="id_or_name", + type="collect", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_perform_operation_overload_4(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.perform_operation( key="key", @@ -597,7 +736,7 @@ def test_path_params_perform_operation_overload_2(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_overload_3(self, client: Kernel) -> None: + def test_method_perform_operation_overload_5(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -612,7 +751,7 @@ def test_method_perform_operation_overload_3(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_with_all_params_overload_3(self, client: Kernel) -> None: + def test_method_perform_operation_with_all_params_overload_5(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -628,7 +767,7 @@ def test_method_perform_operation_with_all_params_overload_3(self, client: Kerne @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_perform_operation_overload_3(self, client: Kernel) -> None: + def test_raw_response_perform_operation_overload_5(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -647,7 +786,7 @@ def test_raw_response_perform_operation_overload_3(self, client: Kernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_perform_operation_overload_3(self, client: Kernel) -> None: + def test_streaming_response_perform_operation_overload_5(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -668,7 +807,7 @@ def test_streaming_response_perform_operation_overload_3(self, client: Kernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_perform_operation_overload_3(self, client: Kernel) -> None: + def test_path_params_perform_operation_overload_5(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.perform_operation( key="key", @@ -695,7 +834,7 @@ def test_path_params_perform_operation_overload_3(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_overload_4(self, client: Kernel) -> None: + def test_method_perform_operation_overload_6(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -724,7 +863,7 @@ def test_method_perform_operation_overload_4(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_with_all_params_overload_4(self, client: Kernel) -> None: + def test_method_perform_operation_with_all_params_overload_6(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -759,7 +898,7 @@ def test_method_perform_operation_with_all_params_overload_4(self, client: Kerne @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_perform_operation_overload_4(self, client: Kernel) -> None: + def test_raw_response_perform_operation_overload_6(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -792,7 +931,7 @@ def test_raw_response_perform_operation_overload_4(self, client: Kernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_perform_operation_overload_4(self, client: Kernel) -> None: + def test_streaming_response_perform_operation_overload_6(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -827,7 +966,7 @@ def test_streaming_response_perform_operation_overload_4(self, client: Kernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_perform_operation_overload_4(self, client: Kernel) -> None: + def test_path_params_perform_operation_overload_6(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.perform_operation( key="key", @@ -882,7 +1021,7 @@ def test_path_params_perform_operation_overload_4(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_overload_5(self, client: Kernel) -> None: + def test_method_perform_operation_overload_7(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -892,7 +1031,7 @@ def test_method_perform_operation_overload_5(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_with_all_params_overload_5(self, client: Kernel) -> None: + def test_method_perform_operation_with_all_params_overload_7(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -905,7 +1044,7 @@ def test_method_perform_operation_with_all_params_overload_5(self, client: Kerne @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_perform_operation_overload_5(self, client: Kernel) -> None: + def test_raw_response_perform_operation_overload_7(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -919,7 +1058,7 @@ def test_raw_response_perform_operation_overload_5(self, client: Kernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_perform_operation_overload_5(self, client: Kernel) -> None: + def test_streaming_response_perform_operation_overload_7(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -935,7 +1074,7 @@ def test_streaming_response_perform_operation_overload_5(self, client: Kernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_perform_operation_overload_5(self, client: Kernel) -> None: + def test_path_params_perform_operation_overload_7(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.perform_operation( key="key", @@ -952,7 +1091,7 @@ def test_path_params_perform_operation_overload_5(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_overload_6(self, client: Kernel) -> None: + def test_method_perform_operation_overload_8(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -962,7 +1101,7 @@ def test_method_perform_operation_overload_6(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_with_all_params_overload_6(self, client: Kernel) -> None: + def test_method_perform_operation_with_all_params_overload_8(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -973,7 +1112,7 @@ def test_method_perform_operation_with_all_params_overload_6(self, client: Kerne @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_perform_operation_overload_6(self, client: Kernel) -> None: + def test_raw_response_perform_operation_overload_8(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -987,7 +1126,7 @@ def test_raw_response_perform_operation_overload_6(self, client: Kernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_perform_operation_overload_6(self, client: Kernel) -> None: + def test_streaming_response_perform_operation_overload_8(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -1003,7 +1142,7 @@ def test_streaming_response_perform_operation_overload_6(self, client: Kernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_perform_operation_overload_6(self, client: Kernel) -> None: + def test_path_params_perform_operation_overload_8(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.perform_operation( key="key", @@ -1020,7 +1159,7 @@ def test_path_params_perform_operation_overload_6(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_overload_7(self, client: Kernel) -> None: + def test_method_perform_operation_overload_9(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -1032,7 +1171,7 @@ def test_method_perform_operation_overload_7(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_with_all_params_overload_7(self, client: Kernel) -> None: + def test_method_perform_operation_with_all_params_overload_9(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -1046,7 +1185,7 @@ def test_method_perform_operation_with_all_params_overload_7(self, client: Kerne @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_perform_operation_overload_7(self, client: Kernel) -> None: + def test_raw_response_perform_operation_overload_9(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -1062,7 +1201,7 @@ def test_raw_response_perform_operation_overload_7(self, client: Kernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_perform_operation_overload_7(self, client: Kernel) -> None: + def test_streaming_response_perform_operation_overload_9(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -1080,7 +1219,7 @@ def test_streaming_response_perform_operation_overload_7(self, client: Kernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_perform_operation_overload_7(self, client: Kernel) -> None: + def test_path_params_perform_operation_overload_9(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.perform_operation( key="key", @@ -1101,7 +1240,7 @@ def test_path_params_perform_operation_overload_7(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_overload_8(self, client: Kernel) -> None: + def test_method_perform_operation_overload_10(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -1111,7 +1250,7 @@ def test_method_perform_operation_overload_8(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_perform_operation_overload_8(self, client: Kernel) -> None: + def test_raw_response_perform_operation_overload_10(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -1125,7 +1264,7 @@ def test_raw_response_perform_operation_overload_8(self, client: Kernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_perform_operation_overload_8(self, client: Kernel) -> None: + def test_streaming_response_perform_operation_overload_10(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -1141,7 +1280,7 @@ def test_streaming_response_perform_operation_overload_8(self, client: Kernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_perform_operation_overload_8(self, client: Kernel) -> None: + def test_path_params_perform_operation_overload_10(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.perform_operation( key="key", @@ -1158,7 +1297,7 @@ def test_path_params_perform_operation_overload_8(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_overload_9(self, client: Kernel) -> None: + def test_method_perform_operation_overload_11(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -1169,7 +1308,7 @@ def test_method_perform_operation_overload_9(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_with_all_params_overload_9(self, client: Kernel) -> None: + def test_method_perform_operation_with_all_params_overload_11(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -1181,7 +1320,7 @@ def test_method_perform_operation_with_all_params_overload_9(self, client: Kerne @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_perform_operation_overload_9(self, client: Kernel) -> None: + def test_raw_response_perform_operation_overload_11(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -1196,7 +1335,7 @@ def test_raw_response_perform_operation_overload_9(self, client: Kernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_perform_operation_overload_9(self, client: Kernel) -> None: + def test_streaming_response_perform_operation_overload_11(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -1213,7 +1352,7 @@ def test_streaming_response_perform_operation_overload_9(self, client: Kernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_perform_operation_overload_9(self, client: Kernel) -> None: + def test_path_params_perform_operation_overload_11(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.perform_operation( key="key", @@ -1232,7 +1371,7 @@ def test_path_params_perform_operation_overload_9(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_overload_10(self, client: Kernel) -> None: + def test_method_perform_operation_overload_12(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -1259,7 +1398,7 @@ def test_method_perform_operation_overload_10(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_perform_operation_with_all_params_overload_10(self, client: Kernel) -> None: + def test_method_perform_operation_with_all_params_overload_12(self, client: Kernel) -> None: item = client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -1289,7 +1428,7 @@ def test_method_perform_operation_with_all_params_overload_10(self, client: Kern @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_perform_operation_overload_10(self, client: Kernel) -> None: + def test_raw_response_perform_operation_overload_12(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -1320,7 +1459,7 @@ def test_raw_response_perform_operation_overload_10(self, client: Kernel) -> Non @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_perform_operation_overload_10(self, client: Kernel) -> None: + def test_streaming_response_perform_operation_overload_12(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -1353,7 +1492,7 @@ def test_streaming_response_perform_operation_overload_10(self, client: Kernel) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_perform_operation_overload_10(self, client: Kernel) -> None: + def test_path_params_perform_operation_overload_12(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.perform_operation( key="key", @@ -2412,7 +2551,7 @@ async def test_method_perform_operation_overload_2(self, async_client: AsyncKern item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", - type="collect", + type="restart_verification", ) assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @@ -2422,7 +2561,7 @@ async def test_raw_response_perform_operation_overload_2(self, async_client: Asy response = await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", - type="collect", + type="restart_verification", ) assert response.is_closed is True @@ -2436,7 +2575,7 @@ async def test_streaming_response_perform_operation_overload_2(self, async_clien async with async_client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", - type="collect", + type="restart_verification", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -2449,6 +2588,145 @@ async def test_streaming_response_perform_operation_overload_2(self, async_clien @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_path_params_perform_operation_overload_2(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + await async_client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="", + type="restart_verification", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.perform_operation( + key="", + id_or_name="id_or_name", + type="restart_verification", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_perform_operation_overload_3(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.perform_operation( + key="key", + id_or_name="id_or_name", + amount=0, + currency="SEW", + occurred_at=parse_datetime("2019-12-27T18:11:19.117Z"), + status="APPROVED", + transaction_type="PURCHASE", + type="confirm_transaction", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_perform_operation_overload_3(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="id_or_name", + amount=0, + currency="SEW", + occurred_at=parse_datetime("2019-12-27T18:11:19.117Z"), + status="APPROVED", + transaction_type="PURCHASE", + type="confirm_transaction", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_perform_operation_overload_3(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.perform_operation( + key="key", + id_or_name="id_or_name", + amount=0, + currency="SEW", + occurred_at=parse_datetime("2019-12-27T18:11:19.117Z"), + status="APPROVED", + transaction_type="PURCHASE", + type="confirm_transaction", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_perform_operation_overload_3(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + await async_client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="", + amount=0, + currency="SEW", + occurred_at=parse_datetime("2019-12-27T18:11:19.117Z"), + status="APPROVED", + transaction_type="PURCHASE", + type="confirm_transaction", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.perform_operation( + key="", + id_or_name="id_or_name", + amount=0, + currency="SEW", + occurred_at=parse_datetime("2019-12-27T18:11:19.117Z"), + status="APPROVED", + transaction_type="PURCHASE", + type="confirm_transaction", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_perform_operation_overload_4(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.perform_operation( + key="key", + id_or_name="id_or_name", + type="collect", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_perform_operation_overload_4(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="id_or_name", + type="collect", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_perform_operation_overload_4(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.perform_operation( + key="key", + id_or_name="id_or_name", + type="collect", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_perform_operation_overload_4(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="key", @@ -2465,7 +2743,7 @@ async def test_path_params_perform_operation_overload_2(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_overload_3(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_overload_5(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2480,7 +2758,7 @@ async def test_method_perform_operation_overload_3(self, async_client: AsyncKern @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_with_all_params_overload_3(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_with_all_params_overload_5(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2496,7 +2774,7 @@ async def test_method_perform_operation_with_all_params_overload_3(self, async_c @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_perform_operation_overload_3(self, async_client: AsyncKernel) -> None: + async def test_raw_response_perform_operation_overload_5(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2515,7 +2793,7 @@ async def test_raw_response_perform_operation_overload_3(self, async_client: Asy @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_3(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_perform_operation_overload_5(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2536,7 +2814,7 @@ async def test_streaming_response_perform_operation_overload_3(self, async_clien @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_perform_operation_overload_3(self, async_client: AsyncKernel) -> None: + async def test_path_params_perform_operation_overload_5(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="key", @@ -2563,7 +2841,7 @@ async def test_path_params_perform_operation_overload_3(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_overload_4(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_overload_6(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2592,7 +2870,7 @@ async def test_method_perform_operation_overload_4(self, async_client: AsyncKern @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_with_all_params_overload_4(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_with_all_params_overload_6(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2627,7 +2905,7 @@ async def test_method_perform_operation_with_all_params_overload_4(self, async_c @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_perform_operation_overload_4(self, async_client: AsyncKernel) -> None: + async def test_raw_response_perform_operation_overload_6(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2660,7 +2938,7 @@ async def test_raw_response_perform_operation_overload_4(self, async_client: Asy @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_4(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_perform_operation_overload_6(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2695,7 +2973,7 @@ async def test_streaming_response_perform_operation_overload_4(self, async_clien @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_perform_operation_overload_4(self, async_client: AsyncKernel) -> None: + async def test_path_params_perform_operation_overload_6(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="key", @@ -2750,7 +3028,7 @@ async def test_path_params_perform_operation_overload_4(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_overload_5(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_overload_7(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2760,7 +3038,7 @@ async def test_method_perform_operation_overload_5(self, async_client: AsyncKern @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_with_all_params_overload_5(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_with_all_params_overload_7(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2773,7 +3051,7 @@ async def test_method_perform_operation_with_all_params_overload_5(self, async_c @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_perform_operation_overload_5(self, async_client: AsyncKernel) -> None: + async def test_raw_response_perform_operation_overload_7(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2787,7 +3065,7 @@ async def test_raw_response_perform_operation_overload_5(self, async_client: Asy @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_5(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_perform_operation_overload_7(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2803,7 +3081,7 @@ async def test_streaming_response_perform_operation_overload_5(self, async_clien @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_perform_operation_overload_5(self, async_client: AsyncKernel) -> None: + async def test_path_params_perform_operation_overload_7(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="key", @@ -2820,7 +3098,7 @@ async def test_path_params_perform_operation_overload_5(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_overload_6(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_overload_8(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2830,7 +3108,7 @@ async def test_method_perform_operation_overload_6(self, async_client: AsyncKern @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_with_all_params_overload_6(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_with_all_params_overload_8(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2841,7 +3119,7 @@ async def test_method_perform_operation_with_all_params_overload_6(self, async_c @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_perform_operation_overload_6(self, async_client: AsyncKernel) -> None: + async def test_raw_response_perform_operation_overload_8(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2855,7 +3133,7 @@ async def test_raw_response_perform_operation_overload_6(self, async_client: Asy @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_6(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_perform_operation_overload_8(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2871,7 +3149,7 @@ async def test_streaming_response_perform_operation_overload_6(self, async_clien @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_perform_operation_overload_6(self, async_client: AsyncKernel) -> None: + async def test_path_params_perform_operation_overload_8(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="key", @@ -2888,7 +3166,7 @@ async def test_path_params_perform_operation_overload_6(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_overload_7(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_overload_9(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2900,7 +3178,7 @@ async def test_method_perform_operation_overload_7(self, async_client: AsyncKern @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_with_all_params_overload_7(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_with_all_params_overload_9(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2914,7 +3192,7 @@ async def test_method_perform_operation_with_all_params_overload_7(self, async_c @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_perform_operation_overload_7(self, async_client: AsyncKernel) -> None: + async def test_raw_response_perform_operation_overload_9(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2930,7 +3208,7 @@ async def test_raw_response_perform_operation_overload_7(self, async_client: Asy @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_7(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_perform_operation_overload_9(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2948,7 +3226,7 @@ async def test_streaming_response_perform_operation_overload_7(self, async_clien @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_perform_operation_overload_7(self, async_client: AsyncKernel) -> None: + async def test_path_params_perform_operation_overload_9(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="key", @@ -2969,7 +3247,7 @@ async def test_path_params_perform_operation_overload_7(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_overload_8(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_overload_10(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -2979,7 +3257,7 @@ async def test_method_perform_operation_overload_8(self, async_client: AsyncKern @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_perform_operation_overload_8(self, async_client: AsyncKernel) -> None: + async def test_raw_response_perform_operation_overload_10(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -2993,7 +3271,7 @@ async def test_raw_response_perform_operation_overload_8(self, async_client: Asy @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_8(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_perform_operation_overload_10(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -3009,7 +3287,7 @@ async def test_streaming_response_perform_operation_overload_8(self, async_clien @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_perform_operation_overload_8(self, async_client: AsyncKernel) -> None: + async def test_path_params_perform_operation_overload_10(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="key", @@ -3026,7 +3304,7 @@ async def test_path_params_perform_operation_overload_8(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_overload_9(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_overload_11(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -3037,7 +3315,7 @@ async def test_method_perform_operation_overload_9(self, async_client: AsyncKern @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_with_all_params_overload_9(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_with_all_params_overload_11(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -3049,7 +3327,7 @@ async def test_method_perform_operation_with_all_params_overload_9(self, async_c @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_perform_operation_overload_9(self, async_client: AsyncKernel) -> None: + async def test_raw_response_perform_operation_overload_11(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -3064,7 +3342,7 @@ async def test_raw_response_perform_operation_overload_9(self, async_client: Asy @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_9(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_perform_operation_overload_11(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -3081,7 +3359,7 @@ async def test_streaming_response_perform_operation_overload_9(self, async_clien @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_perform_operation_overload_9(self, async_client: AsyncKernel) -> None: + async def test_path_params_perform_operation_overload_11(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="key", @@ -3100,7 +3378,7 @@ async def test_path_params_perform_operation_overload_9(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_overload_10(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_overload_12(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -3127,7 +3405,7 @@ async def test_method_perform_operation_overload_10(self, async_client: AsyncKer @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_with_all_params_overload_10(self, async_client: AsyncKernel) -> None: + async def test_method_perform_operation_with_all_params_overload_12(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", @@ -3157,7 +3435,7 @@ async def test_method_perform_operation_with_all_params_overload_10(self, async_ @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_perform_operation_overload_10(self, async_client: AsyncKernel) -> None: + async def test_raw_response_perform_operation_overload_12(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", @@ -3188,7 +3466,7 @@ async def test_raw_response_perform_operation_overload_10(self, async_client: As @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_10(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_perform_operation_overload_12(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", @@ -3221,7 +3499,7 @@ async def test_streaming_response_perform_operation_overload_10(self, async_clie @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_perform_operation_overload_10(self, async_client: AsyncKernel) -> None: + async def test_path_params_perform_operation_overload_12(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="key", diff --git a/tests/test_browser_pool_acquire_response.py b/tests/test_browser_pool_acquire_response.py new file mode 100644 index 00000000..269838a6 --- /dev/null +++ b/tests/test_browser_pool_acquire_response.py @@ -0,0 +1,70 @@ +import httpx +import pytest + +from kernel import Kernel, AsyncKernel, NotFoundError, APIResponseValidationError + + +def test_acquire_returns_browser() -> None: + browser = { + "cdp_ws_url": "wss://example.test/cdp", + "created_at": "2026-10-09T00:00:00Z", + "headless": True, + "memory": "1GiB", + "region": "us-east", + "session_id": "session-1", + "stealth": False, + "webdriver_ws_url": "wss://example.test/webdriver", + } + with Kernel( + api_key="test", + http_client=httpx.Client(transport=httpx.MockTransport(lambda _request: httpx.Response(200, json=browser))), + ) as client: + result = client.browser_pools.acquire("pool") + assert result is not None + assert result.session_id == "session-1" + + +def test_acquire_returns_none_on_poll_timeout() -> None: + calls = 0 + + def handle(_request: httpx.Request) -> httpx.Response: + nonlocal calls + calls += 1 + return httpx.Response(204) + + with Kernel(api_key="test", http_client=httpx.Client(transport=httpx.MockTransport(handle))) as client: + assert client.browser_pools.acquire("pool") is None + response = client.browser_pools.with_raw_response.acquire("pool") + assert response.status_code == 204 + assert response.parse() is None + assert response.parse(to=str) == "" + assert response.parse(to=bytes) == b"" + assert response.parse(to=httpx.Response) is response.http_response + assert calls == 2 + + +async def test_async_acquire_returns_none_on_poll_timeout() -> None: + async with AsyncKernel( + api_key="test", + http_client=httpx.AsyncClient(transport=httpx.MockTransport(lambda _request: httpx.Response(204))), + ) as client: + assert await client.browser_pools.acquire("pool") is None + + +def test_acquire_still_raises_not_found() -> None: + with Kernel( + api_key="test", + http_client=httpx.Client(transport=httpx.MockTransport(lambda _request: httpx.Response(404, json={}))), + ) as client: + with pytest.raises(NotFoundError): + client.browser_pools.acquire("missing") + + +def test_unexpected_204_still_fails_strict_validation() -> None: + with Kernel( + api_key="test", + _strict_response_validation=True, + http_client=httpx.Client(transport=httpx.MockTransport(lambda _request: httpx.Response(204))), + ) as client: + with pytest.raises(APIResponseValidationError): + client.browser_pools.retrieve("pool")