From 28fb2d3c8fd83090d83404a0b407557585bf93f6 Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Mon, 28 Sep 2026 14:20:00 +0000 Subject: [PATCH 1/7] feat: Accept telemetry.storage and settle it at browser create Stainless-Generated-From: 8f39036711533f5cf7d1dcae85d98c367dbf9d74 --- api.md | 1 + .../types/auth/connection_create_params.py | 14 ++++++++++++++ .../types/auth/connection_login_params.py | 14 ++++++++++++++ .../types/auth/connection_update_params.py | 14 ++++++++++++++ src/kernel/types/auth/managed_auth.py | 14 ++++++++++++++ .../types/auth/managed_auth_browser_config.py | 14 ++++++++++++++ .../auth/managed_auth_browser_config_param.py | 14 ++++++++++++++ src/kernel/types/browser_create_params.py | 14 ++++++++++++++ .../types/browser_pool_acquire_params.py | 14 ++++++++++++++ src/kernel/types/browser_pool_create_params.py | 14 ++++++++++++++ src/kernel/types/browser_pool_update_params.py | 14 ++++++++++++++ src/kernel/types/browser_update_params.py | 14 ++++++++++++++ src/kernel/types/browsers/__init__.py | 1 + .../types/browsers/browser_telemetry_config.py | 7 +++++++ .../browser_telemetry_storage_config.py | 18 ++++++++++++++++++ tests/api_resources/auth/test_connections.py | 12 ++++++++++++ tests/api_resources/test_browser_pools.py | 6 ++++++ tests/api_resources/test_browsers.py | 4 ++++ 18 files changed, 203 insertions(+) create mode 100644 src/kernel/types/browsers/browser_telemetry_storage_config.py diff --git a/api.md b/api.md index 1b130bb7..f8529996 100644 --- a/api.md +++ b/api.md @@ -207,6 +207,7 @@ from kernel.types.browsers import ( BrowserTelemetryEvent, BrowserTelemetryExportConfig, BrowserTelemetryOtlpExportConfig, + BrowserTelemetryStorageConfig, TelemetryEventsResponse, TelemetryStreamResponse, ) diff --git a/src/kernel/types/auth/connection_create_params.py b/src/kernel/types/auth/connection_create_params.py index 0ea02cbd..03dfc9c1 100644 --- a/src/kernel/types/auth/connection_create_params.py +++ b/src/kernel/types/auth/connection_create_params.py @@ -15,6 +15,7 @@ "BrowserTelemetryExport", "BrowserTelemetryExportOtlp", "BrowserTelemetryExportOtlpDestination", + "BrowserTelemetryStorage", "Credential", "Proxy", ] @@ -166,6 +167,16 @@ class BrowserTelemetryExport(TypedDict, total=False): """ +class BrowserTelemetryStorage(TypedDict, total=False): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: bool + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class BrowserTelemetry(TypedDict, total=False): """Deprecated. @@ -205,6 +216,9 @@ class BrowserTelemetry(TypedDict, total=False): Omit to capture without exporting. """ + storage: BrowserTelemetryStorage + """Whether to persist this session's captured telemetry to Kernel storage.""" + class Credential(TypedDict, total=False): """Reference to credentials for the auth connection. diff --git a/src/kernel/types/auth/connection_login_params.py b/src/kernel/types/auth/connection_login_params.py index 0d62506d..3c456c99 100644 --- a/src/kernel/types/auth/connection_login_params.py +++ b/src/kernel/types/auth/connection_login_params.py @@ -14,6 +14,7 @@ "BrowserTelemetryExport", "BrowserTelemetryExportOtlp", "BrowserTelemetryExportOtlpDestination", + "BrowserTelemetryStorage", "Proxy", ] @@ -92,6 +93,16 @@ class BrowserTelemetryExport(TypedDict, total=False): """ +class BrowserTelemetryStorage(TypedDict, total=False): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: bool + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class BrowserTelemetry(TypedDict, total=False): """Deprecated. @@ -131,6 +142,9 @@ class BrowserTelemetry(TypedDict, total=False): Omit to capture without exporting. """ + storage: BrowserTelemetryStorage + """Whether to persist this session's captured telemetry to Kernel storage.""" + class Proxy(TypedDict, total=False): """Deprecated. Use browser.proxy. Retained during migration for existing clients.""" diff --git a/src/kernel/types/auth/connection_update_params.py b/src/kernel/types/auth/connection_update_params.py index 21977396..db776ec9 100644 --- a/src/kernel/types/auth/connection_update_params.py +++ b/src/kernel/types/auth/connection_update_params.py @@ -15,6 +15,7 @@ "BrowserTelemetryExport", "BrowserTelemetryExportOtlp", "BrowserTelemetryExportOtlpDestination", + "BrowserTelemetryStorage", "Credential", "Proxy", ] @@ -129,6 +130,16 @@ class BrowserTelemetryExport(TypedDict, total=False): """ +class BrowserTelemetryStorage(TypedDict, total=False): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: bool + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class BrowserTelemetry(TypedDict, total=False): """Deprecated. @@ -168,6 +179,9 @@ class BrowserTelemetry(TypedDict, total=False): Omit to capture without exporting. """ + storage: BrowserTelemetryStorage + """Whether to persist this session's captured telemetry to Kernel storage.""" + class Credential(TypedDict, total=False): """Reference to credentials for the auth connection. diff --git a/src/kernel/types/auth/managed_auth.py b/src/kernel/types/auth/managed_auth.py index be202e61..aadb0718 100644 --- a/src/kernel/types/auth/managed_auth.py +++ b/src/kernel/types/auth/managed_auth.py @@ -14,6 +14,7 @@ "BrowserTelemetryExport", "BrowserTelemetryExportOtlp", "BrowserTelemetryExportOtlpDestination", + "BrowserTelemetryStorage", "Choice", "Credential", "DiscoveredField", @@ -68,6 +69,16 @@ class BrowserTelemetryExport(BaseModel): """ +class BrowserTelemetryStorage(BaseModel): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: Optional[bool] = None + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class BrowserTelemetry(BaseModel): """Deprecated. @@ -107,6 +118,9 @@ class BrowserTelemetry(BaseModel): Omit to capture without exporting. """ + storage: Optional[BrowserTelemetryStorage] = None + """Whether to persist this session's captured telemetry to Kernel storage.""" + class Choice(BaseModel): """Canonical auth-flow choice awaiting user selection.""" diff --git a/src/kernel/types/auth/managed_auth_browser_config.py b/src/kernel/types/auth/managed_auth_browser_config.py index 3309904e..363af851 100644 --- a/src/kernel/types/auth/managed_auth_browser_config.py +++ b/src/kernel/types/auth/managed_auth_browser_config.py @@ -13,6 +13,7 @@ "TelemetryExport", "TelemetryExportOtlp", "TelemetryExportOtlpDestination", + "TelemetryStorage", ] @@ -60,6 +61,16 @@ class TelemetryExport(BaseModel): """ +class TelemetryStorage(BaseModel): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: Optional[bool] = None + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class Telemetry(BaseModel): """Browser telemetry configuration using the same semantics as browser create.""" @@ -96,6 +107,9 @@ class Telemetry(BaseModel): Omit to capture without exporting. """ + storage: Optional[TelemetryStorage] = None + """Whether to persist this session's captured telemetry to Kernel storage.""" + class ManagedAuthBrowserConfig(BaseModel): """ diff --git a/src/kernel/types/auth/managed_auth_browser_config_param.py b/src/kernel/types/auth/managed_auth_browser_config_param.py index 6f8eab6d..ae9c171d 100644 --- a/src/kernel/types/auth/managed_auth_browser_config_param.py +++ b/src/kernel/types/auth/managed_auth_browser_config_param.py @@ -14,6 +14,7 @@ "TelemetryExport", "TelemetryExportOtlp", "TelemetryExportOtlpDestination", + "TelemetryStorage", ] @@ -61,6 +62,16 @@ class TelemetryExport(TypedDict, total=False): """ +class TelemetryStorage(TypedDict, total=False): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: bool + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class Telemetry(TypedDict, total=False): """Browser telemetry configuration using the same semantics as browser create.""" @@ -97,6 +108,9 @@ class Telemetry(TypedDict, total=False): Omit to capture without exporting. """ + storage: TelemetryStorage + """Whether to persist this session's captured telemetry to Kernel storage.""" + class ManagedAuthBrowserConfigParam(TypedDict, total=False): """ diff --git a/src/kernel/types/browser_create_params.py b/src/kernel/types/browser_create_params.py index ab486672..bcc71dc9 100644 --- a/src/kernel/types/browser_create_params.py +++ b/src/kernel/types/browser_create_params.py @@ -21,6 +21,7 @@ "TelemetryExport", "TelemetryExportOtlp", "TelemetryExportOtlpDestination", + "TelemetryStorage", ] @@ -217,6 +218,16 @@ class TelemetryExport(TypedDict, total=False): """ +class TelemetryStorage(TypedDict, total=False): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: bool + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class Telemetry(TypedDict, total=False): """Telemetry configuration for the browser session. @@ -255,3 +266,6 @@ class Telemetry(TypedDict, total=False): Omit to capture without exporting. """ + + storage: TelemetryStorage + """Whether to persist this session's captured telemetry to Kernel storage.""" diff --git a/src/kernel/types/browser_pool_acquire_params.py b/src/kernel/types/browser_pool_acquire_params.py index 823d05b9..30a355e2 100644 --- a/src/kernel/types/browser_pool_acquire_params.py +++ b/src/kernel/types/browser_pool_acquire_params.py @@ -15,6 +15,7 @@ "TelemetryExport", "TelemetryExportOtlp", "TelemetryExportOtlpDestination", + "TelemetryStorage", ] @@ -112,6 +113,16 @@ class TelemetryExport(TypedDict, total=False): """ +class TelemetryStorage(TypedDict, total=False): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: bool + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class Telemetry(TypedDict, total=False): """Telemetry override for the acquired browser, applied to this lease only. @@ -150,3 +161,6 @@ class Telemetry(TypedDict, total=False): Omit to capture without exporting. """ + + storage: TelemetryStorage + """Whether to persist this session's captured telemetry to Kernel storage.""" diff --git a/src/kernel/types/browser_pool_create_params.py b/src/kernel/types/browser_pool_create_params.py index 99fb61d2..ea734521 100644 --- a/src/kernel/types/browser_pool_create_params.py +++ b/src/kernel/types/browser_pool_create_params.py @@ -18,6 +18,7 @@ "TelemetryExport", "TelemetryExportOtlp", "TelemetryExportOtlpDestination", + "TelemetryStorage", ] @@ -209,6 +210,16 @@ class TelemetryExport(TypedDict, total=False): """ +class TelemetryStorage(TypedDict, total=False): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: bool + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class Telemetry(TypedDict, total=False): """Telemetry configuration applied to browsers warmed into this pool. @@ -247,3 +258,6 @@ class Telemetry(TypedDict, total=False): Omit to capture without exporting. """ + + storage: TelemetryStorage + """Whether to persist this session's captured telemetry to Kernel storage.""" diff --git a/src/kernel/types/browser_pool_update_params.py b/src/kernel/types/browser_pool_update_params.py index 2ccfa9b9..e2190dc6 100644 --- a/src/kernel/types/browser_pool_update_params.py +++ b/src/kernel/types/browser_pool_update_params.py @@ -17,6 +17,7 @@ "TelemetryExport", "TelemetryExportOtlp", "TelemetryExportOtlpDestination", + "TelemetryStorage", ] @@ -222,6 +223,16 @@ class TelemetryExport(TypedDict, total=False): """ +class TelemetryStorage(TypedDict, total=False): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: bool + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class Telemetry(TypedDict, total=False): """If provided, updates the pool's telemetry configuration. @@ -260,3 +271,6 @@ class Telemetry(TypedDict, total=False): Omit to capture without exporting. """ + + storage: TelemetryStorage + """Whether to persist this session's captured telemetry to Kernel storage.""" diff --git a/src/kernel/types/browser_update_params.py b/src/kernel/types/browser_update_params.py index c0592e28..19e7e592 100644 --- a/src/kernel/types/browser_update_params.py +++ b/src/kernel/types/browser_update_params.py @@ -17,6 +17,7 @@ "TelemetryExport", "TelemetryExportOtlp", "TelemetryExportOtlpDestination", + "TelemetryStorage", "Viewport", ] @@ -133,6 +134,16 @@ class TelemetryExport(TypedDict, total=False): """ +class TelemetryStorage(TypedDict, total=False): + """Whether to persist this session's captured telemetry to Kernel storage.""" + + enabled: bool + """Whether captured telemetry is persisted to Kernel storage. + + Defaults to true. Setting false is not supported yet and is rejected. + """ + + class Telemetry(TypedDict, total=False): """Telemetry configuration. @@ -172,6 +183,9 @@ class Telemetry(TypedDict, total=False): Omit to capture without exporting. """ + storage: TelemetryStorage + """Whether to persist this session's captured telemetry to Kernel storage.""" + class Viewport(BrowserViewport, total=False): """Viewport configuration to apply to the browser session.""" diff --git a/src/kernel/types/browsers/__init__.py b/src/kernel/types/browsers/__init__.py index 169e6ccf..2decde3a 100644 --- a/src/kernel/types/browsers/__init__.py +++ b/src/kernel/types/browsers/__init__.py @@ -88,6 +88,7 @@ from .computer_write_clipboard_params import ComputerWriteClipboardParams as ComputerWriteClipboardParams from .browser_monitor_screenshot_event import BrowserMonitorScreenshotEvent as BrowserMonitorScreenshotEvent from .browser_telemetry_control_config import BrowserTelemetryControlConfig as BrowserTelemetryControlConfig +from .browser_telemetry_storage_config import BrowserTelemetryStorageConfig as BrowserTelemetryStorageConfig from .computer_read_clipboard_response import ComputerReadClipboardResponse as ComputerReadClipboardResponse from .browser_monitor_init_failed_event import BrowserMonitorInitFailedEvent as BrowserMonitorInitFailedEvent from .browser_monitor_reconnected_event import BrowserMonitorReconnectedEvent as BrowserMonitorReconnectedEvent diff --git a/src/kernel/types/browsers/browser_telemetry_config.py b/src/kernel/types/browsers/browser_telemetry_config.py index 8d24e6bf..6eec504f 100644 --- a/src/kernel/types/browsers/browser_telemetry_config.py +++ b/src/kernel/types/browsers/browser_telemetry_config.py @@ -4,6 +4,7 @@ from ..._models import BaseModel from .browser_telemetry_export_config import BrowserTelemetryExportConfig +from .browser_telemetry_storage_config import BrowserTelemetryStorageConfig from .browser_telemetry_categories_config import BrowserTelemetryCategoriesConfig __all__ = ["BrowserTelemetryConfig"] @@ -20,3 +21,9 @@ class BrowserTelemetryConfig(BaseModel): Omitted when the export state is unknown. """ + + storage: Optional[BrowserTelemetryStorageConfig] = None + """Whether the session's captured telemetry is persisted to Kernel storage. + + Omitted for browsers created before this setting existed, which persist it. + """ diff --git a/src/kernel/types/browsers/browser_telemetry_storage_config.py b/src/kernel/types/browsers/browser_telemetry_storage_config.py new file mode 100644 index 00000000..f79f307e --- /dev/null +++ b/src/kernel/types/browsers/browser_telemetry_storage_config.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ..._models import BaseModel + +__all__ = ["BrowserTelemetryStorageConfig"] + + +class BrowserTelemetryStorageConfig(BaseModel): + """Kernel storage state for a session's captured telemetry.""" + + enabled: Optional[bool] = None + """Whether captured telemetry is persisted to Kernel storage. + + When off, the session's events are only available on the live stream and through + any configured export. + """ diff --git a/tests/api_resources/auth/test_connections.py b/tests/api_resources/auth/test_connections.py index 311b9971..f4bf875f 100644 --- a/tests/api_resources/auth/test_connections.py +++ b/tests/api_resources/auth/test_connections.py @@ -74,6 +74,7 @@ def test_method_create_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, }, browser_telemetry={ @@ -102,6 +103,7 @@ def test_method_create_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, credential={ "auto": True, @@ -240,6 +242,7 @@ def test_method_update_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, }, browser_telemetry={ @@ -268,6 +271,7 @@ def test_method_update_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, credential={ "auto": True, @@ -491,6 +495,7 @@ def test_method_login_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, }, browser_telemetry={ @@ -519,6 +524,7 @@ def test_method_login_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, proxy={ "id": "id", @@ -737,6 +743,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncKernel) -> "enabled": True, } }, + "storage": {"enabled": True}, }, }, browser_telemetry={ @@ -765,6 +772,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncKernel) -> "enabled": True, } }, + "storage": {"enabled": True}, }, credential={ "auto": True, @@ -903,6 +911,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncKernel) -> "enabled": True, } }, + "storage": {"enabled": True}, }, }, browser_telemetry={ @@ -931,6 +940,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncKernel) -> "enabled": True, } }, + "storage": {"enabled": True}, }, credential={ "auto": True, @@ -1154,6 +1164,7 @@ async def test_method_login_with_all_params(self, async_client: AsyncKernel) -> "enabled": True, } }, + "storage": {"enabled": True}, }, }, browser_telemetry={ @@ -1182,6 +1193,7 @@ async def test_method_login_with_all_params(self, async_client: AsyncKernel) -> "enabled": True, } }, + "storage": {"enabled": True}, }, proxy={ "id": "id", diff --git a/tests/api_resources/test_browser_pools.py b/tests/api_resources/test_browser_pools.py index d97b0704..cd0c1b98 100644 --- a/tests/api_resources/test_browser_pools.py +++ b/tests/api_resources/test_browser_pools.py @@ -93,6 +93,7 @@ def test_method_create_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, timeout_seconds=10, viewport={ @@ -244,6 +245,7 @@ def test_method_update_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, timeout_seconds=10, viewport={ @@ -430,6 +432,7 @@ def test_method_acquire_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, ) assert_matches_type(BrowserPoolAcquireResponse, browser_pool, path=["response"]) @@ -644,6 +647,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncKernel) -> "enabled": True, } }, + "storage": {"enabled": True}, }, timeout_seconds=10, viewport={ @@ -795,6 +799,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncKernel) -> "enabled": True, } }, + "storage": {"enabled": True}, }, timeout_seconds=10, viewport={ @@ -981,6 +986,7 @@ async def test_method_acquire_with_all_params(self, async_client: AsyncKernel) - "enabled": True, } }, + "storage": {"enabled": True}, }, ) assert_matches_type(BrowserPoolAcquireResponse, browser_pool, path=["response"]) diff --git a/tests/api_resources/test_browsers.py b/tests/api_resources/test_browsers.py index 5caa570e..a9f0c46b 100644 --- a/tests/api_resources/test_browsers.py +++ b/tests/api_resources/test_browsers.py @@ -104,6 +104,7 @@ def test_method_create_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, timeout_seconds=10, vaults=[ @@ -250,6 +251,7 @@ def test_method_update_with_all_params(self, client: Kernel) -> None: "enabled": True, } }, + "storage": {"enabled": True}, }, viewport={ "height": 800, @@ -646,6 +648,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncKernel) -> "enabled": True, } }, + "storage": {"enabled": True}, }, timeout_seconds=10, vaults=[ @@ -792,6 +795,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncKernel) -> "enabled": True, } }, + "storage": {"enabled": True}, }, viewport={ "height": 800, From 2ff8d4acacb1b8152b9c7d1b38067c1b02167f40 Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Mon, 28 Sep 2026 16:59:35 +0000 Subject: [PATCH 2/7] feat: Allow export-only network and console telemetry for BAA orgs Stainless-Generated-From: 1ea489e4871d8446f69ea3f39d82ec4856d6491b --- src/kernel/types/auth/connection_create_params.py | 3 ++- src/kernel/types/auth/connection_login_params.py | 3 ++- src/kernel/types/auth/connection_update_params.py | 3 ++- src/kernel/types/auth/managed_auth.py | 3 ++- src/kernel/types/auth/managed_auth_browser_config.py | 3 ++- src/kernel/types/auth/managed_auth_browser_config_param.py | 3 ++- src/kernel/types/browser_create_params.py | 3 ++- src/kernel/types/browser_pool_acquire_params.py | 3 ++- src/kernel/types/browser_pool_create_params.py | 3 ++- src/kernel/types/browser_pool_update_params.py | 3 ++- src/kernel/types/browser_update_params.py | 3 ++- 11 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/kernel/types/auth/connection_create_params.py b/src/kernel/types/auth/connection_create_params.py index 03dfc9c1..bf0ac55b 100644 --- a/src/kernel/types/auth/connection_create_params.py +++ b/src/kernel/types/auth/connection_create_params.py @@ -173,7 +173,8 @@ class BrowserTelemetryStorage(TypedDict, total=False): enabled: bool """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ diff --git a/src/kernel/types/auth/connection_login_params.py b/src/kernel/types/auth/connection_login_params.py index 3c456c99..19e452c9 100644 --- a/src/kernel/types/auth/connection_login_params.py +++ b/src/kernel/types/auth/connection_login_params.py @@ -99,7 +99,8 @@ class BrowserTelemetryStorage(TypedDict, total=False): enabled: bool """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ diff --git a/src/kernel/types/auth/connection_update_params.py b/src/kernel/types/auth/connection_update_params.py index db776ec9..36a9a9f8 100644 --- a/src/kernel/types/auth/connection_update_params.py +++ b/src/kernel/types/auth/connection_update_params.py @@ -136,7 +136,8 @@ class BrowserTelemetryStorage(TypedDict, total=False): enabled: bool """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ diff --git a/src/kernel/types/auth/managed_auth.py b/src/kernel/types/auth/managed_auth.py index aadb0718..eb5dda03 100644 --- a/src/kernel/types/auth/managed_auth.py +++ b/src/kernel/types/auth/managed_auth.py @@ -75,7 +75,8 @@ class BrowserTelemetryStorage(BaseModel): enabled: Optional[bool] = None """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ diff --git a/src/kernel/types/auth/managed_auth_browser_config.py b/src/kernel/types/auth/managed_auth_browser_config.py index 363af851..1cbab85a 100644 --- a/src/kernel/types/auth/managed_auth_browser_config.py +++ b/src/kernel/types/auth/managed_auth_browser_config.py @@ -67,7 +67,8 @@ class TelemetryStorage(BaseModel): enabled: Optional[bool] = None """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ diff --git a/src/kernel/types/auth/managed_auth_browser_config_param.py b/src/kernel/types/auth/managed_auth_browser_config_param.py index ae9c171d..47651227 100644 --- a/src/kernel/types/auth/managed_auth_browser_config_param.py +++ b/src/kernel/types/auth/managed_auth_browser_config_param.py @@ -68,7 +68,8 @@ class TelemetryStorage(TypedDict, total=False): enabled: bool """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ diff --git a/src/kernel/types/browser_create_params.py b/src/kernel/types/browser_create_params.py index bcc71dc9..fd33cee5 100644 --- a/src/kernel/types/browser_create_params.py +++ b/src/kernel/types/browser_create_params.py @@ -224,7 +224,8 @@ class TelemetryStorage(TypedDict, total=False): enabled: bool """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ diff --git a/src/kernel/types/browser_pool_acquire_params.py b/src/kernel/types/browser_pool_acquire_params.py index 30a355e2..0a74c176 100644 --- a/src/kernel/types/browser_pool_acquire_params.py +++ b/src/kernel/types/browser_pool_acquire_params.py @@ -119,7 +119,8 @@ class TelemetryStorage(TypedDict, total=False): enabled: bool """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ diff --git a/src/kernel/types/browser_pool_create_params.py b/src/kernel/types/browser_pool_create_params.py index ea734521..fa1f5f89 100644 --- a/src/kernel/types/browser_pool_create_params.py +++ b/src/kernel/types/browser_pool_create_params.py @@ -216,7 +216,8 @@ class TelemetryStorage(TypedDict, total=False): enabled: bool """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ diff --git a/src/kernel/types/browser_pool_update_params.py b/src/kernel/types/browser_pool_update_params.py index e2190dc6..ebf5cd35 100644 --- a/src/kernel/types/browser_pool_update_params.py +++ b/src/kernel/types/browser_pool_update_params.py @@ -229,7 +229,8 @@ class TelemetryStorage(TypedDict, total=False): enabled: bool """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ diff --git a/src/kernel/types/browser_update_params.py b/src/kernel/types/browser_update_params.py index 19e7e592..08cd43c2 100644 --- a/src/kernel/types/browser_update_params.py +++ b/src/kernel/types/browser_update_params.py @@ -140,7 +140,8 @@ class TelemetryStorage(TypedDict, total=False): enabled: bool """Whether captured telemetry is persisted to Kernel storage. - Defaults to true. Setting false is not supported yet and is rejected. + Defaults to true. Setting false requires an OTLP destination and cannot be + changed after the browser is created. """ From 74dbad8f0cdf5b414022ad907f6e20ee54893c59 Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Mon, 28 Sep 2026 17:19:53 +0000 Subject: [PATCH 3/7] feat: Expose missing managed auth check URL as verification unavailable Stainless-Generated-From: 1995c3fd399a0dc1dbc1a88983b6bb0d0673d0f8 --- src/kernel/types/auth/managed_auth.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/kernel/types/auth/managed_auth.py b/src/kernel/types/auth/managed_auth.py index eb5dda03..aab06668 100644 --- a/src/kernel/types/auth/managed_auth.py +++ b/src/kernel/types/auth/managed_auth.py @@ -324,7 +324,11 @@ class ManagedAuth(BaseModel): """ status: Literal["AUTHENTICATED", "NEEDS_AUTH"] - """Current authentication status of the managed profile""" + """Last known authentication status of the managed profile. + + An inconclusive health check preserves this status and does not verify the + current session. + """ allowed_domains: Optional[List[str]] = None """Additional hostname roots valid for this auth flow, besides the primary domain. @@ -519,6 +523,13 @@ class ManagedAuth(BaseModel): 3600 (1 hour), Free: 21600 (6 hours). """ + health_check_unavailable_reason: Optional[Literal["no_auth_check_url"]] = None + """Why health checks cannot verify this connection. + + Present when health checks are enabled but no auth check URL is available; a + recent last_auth_check_at is not evidence of a valid session. + """ + health_checks: Optional[bool] = None """Whether periodic health checks are enabled for this connection. From 2937b10cce135282b6badc7e5bf71d339500ffdb Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:17:01 +0000 Subject: [PATCH 4/7] feat: Let Vaults fill credentials from 1Password Stainless-Generated-From: 6d937aebb18d99636c515de11d6958083e7ca24c --- api.md | 15 + src/kernel/resources/vaults/items.py | 846 ++++++- src/kernel/types/vaults/__init__.py | 38 + .../vaults/credential_account_vault_item.py | 73 + ...ential_account_vault_item_request_param.py | 15 + .../types/vaults/credential_vault_item.py | 59 +- .../credential_vault_item_request_param.py | 25 +- .../vaults/credential_vault_item_spec.py | 24 +- .../credential_vault_item_spec_input_param.py | 31 +- .../vaults/credential_vault_item_state.py | 22 +- .../vaults/item_perform_operation_params.py | 80 +- src/kernel/types/vaults/item_upsert_params.py | 18 +- .../kernel_credential_vault_item_spec.py | 25 + ..._credential_vault_item_spec_input_param.py | 34 + .../kernel_credential_vault_item_state.py | 22 + .../one_password_credential_account_spec.py | 23 + ..._password_credential_account_spec_param.py | 23 + .../one_password_credential_account_state.py | 16 + ...one_password_credential_vault_item_spec.py | 57 + ..._credential_vault_item_spec_input_param.py | 84 + ...ne_password_credential_vault_item_state.py | 125 + ...fill_vault_item_operation_request_param.py | 33 + ...ssword_fill_vault_item_operation_result.py | 36 + .../types/vaults/one_password_oauth_action.py | 14 + ...over_vault_item_operation_request_param.py | 16 + ...cess_vault_item_operation_request_param.py | 26 + src/kernel/types/vaults/vault_item.py | 28 +- src/kernel/types/vaults/vault_item_action.py | 2 + .../vaults/vault_item_operation_response.py | 33 +- .../types/vaults/wallet_vault_item_spec.py | 4 +- tests/api_resources/vaults/test_items.py | 2081 ++++++++++++----- 31 files changed, 3164 insertions(+), 764 deletions(-) create mode 100644 src/kernel/types/vaults/credential_account_vault_item.py create mode 100644 src/kernel/types/vaults/credential_account_vault_item_request_param.py create mode 100644 src/kernel/types/vaults/kernel_credential_vault_item_spec.py create mode 100644 src/kernel/types/vaults/kernel_credential_vault_item_spec_input_param.py create mode 100644 src/kernel/types/vaults/kernel_credential_vault_item_state.py create mode 100644 src/kernel/types/vaults/one_password_credential_account_spec.py create mode 100644 src/kernel/types/vaults/one_password_credential_account_spec_param.py create mode 100644 src/kernel/types/vaults/one_password_credential_account_state.py create mode 100644 src/kernel/types/vaults/one_password_credential_vault_item_spec.py create mode 100644 src/kernel/types/vaults/one_password_credential_vault_item_spec_input_param.py create mode 100644 src/kernel/types/vaults/one_password_credential_vault_item_state.py create mode 100644 src/kernel/types/vaults/one_password_fill_vault_item_operation_request_param.py create mode 100644 src/kernel/types/vaults/one_password_fill_vault_item_operation_result.py create mode 100644 src/kernel/types/vaults/one_password_oauth_action.py create mode 100644 src/kernel/types/vaults/one_password_recover_vault_item_operation_request_param.py create mode 100644 src/kernel/types/vaults/one_password_request_access_vault_item_operation_request_param.py diff --git a/api.md b/api.md index f8529996..c15b15db 100644 --- a/api.md +++ b/api.md @@ -555,6 +555,8 @@ from kernel.types.vaults import ( CardVaultItemSpec, CardVaultItemState, CollectVaultItemOperationRequest, + CredentialAccountVaultItem, + CredentialAccountVaultItemRequest, CredentialCollectionAction, CredentialVaultFieldDefinition, CredentialVaultFieldInput, @@ -570,6 +572,19 @@ from kernel.types.vaults import ( CredentialVaultItemUpdateRequest, FillVaultItemOperationRequest, FillVaultItemOperationResult, + KernelCredentialVaultItemSpec, + KernelCredentialVaultItemSpecInput, + KernelCredentialVaultItemState, + OnePasswordCredentialAccountSpec, + OnePasswordCredentialAccountState, + OnePasswordCredentialVaultItemSpec, + OnePasswordCredentialVaultItemSpecInput, + OnePasswordCredentialVaultItemState, + OnePasswordFillVaultItemOperationRequest, + OnePasswordFillVaultItemOperationResult, + OnePasswordOAuthAction, + OnePasswordRecoverVaultItemOperationRequest, + OnePasswordRequestAccessVaultItemOperationRequest, PrepareCheckoutVaultItemOperationRequest, VaultCardAliases, VaultCardFillField, diff --git a/src/kernel/resources/vaults/items.py b/src/kernel/resources/vaults/items.py index acaf0315..31aefa82 100644 --- a/src/kernel/resources/vaults/items.py +++ b/src/kernel/resources/vaults/items.py @@ -2,12 +2,13 @@ from __future__ import annotations -from typing import Any, List, Iterable, cast +from typing import Any, List, Union, Iterable, cast +from datetime import datetime from typing_extensions import Literal, overload import httpx -from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given +from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given from ..._utils import path_template, required_args, maybe_transform, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource @@ -34,6 +35,7 @@ from ...types.vaults.vault_item_operation_response import VaultItemOperationResponse from ...types.vaults.credential_vault_item_spec_input_param import CredentialVaultItemSpecInputParam from ...types.vaults.credential_vault_item_spec_update_param import CredentialVaultItemSpecUpdateParam +from ...types.vaults.one_password_credential_account_spec_param import OnePasswordCredentialAccountSpecParam __all__ = ["ItemsResource", "AsyncItemsResource"] @@ -596,20 +598,299 @@ def perform_operation( """ ... + @overload + def perform_operation( + self, + key: str, + *, + id_or_name: str, + browser_id: str, + type: Literal["1pw_create_access_request"], + goal: str | Omit = omit, + keywords: SequenceNotStr[str] | Omit = omit, + reason: str | Omit = omit, + # 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`, not an automatic-retry signal. A transport error may + leave the outcome unknown; do not automatically retry. + + Args: + browser_id: Kernel browser session used to invoke the extension. + + 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, + browser_id: str, + type: Literal["1pw_access_request_status"], + timeout_seconds: int | Omit = omit, + # 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`, not an automatic-retry signal. A transport error may + leave the outcome unknown; do not automatically retry. + + 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, + browser_id: str, + page_url: str, + type: Literal["1pw_fill"], + entry_id: str | Omit = omit, + timeout_ms: int | Omit = omit, + # 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`, not an automatic-retry signal. A transport error may + leave the outcome unknown; do not automatically retry. + + Args: + browser_id: Browser session ID, not a reusable browser name. + + page_url: Exact current top-level page URL. Must match exactly one open page in the + browser. + + entry_id: ID of an approved request entry. Required when several approved entries have the + page's origin. + + 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, + type: Literal["1pw_recover"], + # 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`, not an automatic-retry signal. A transport error may + leave the outcome unknown; do not automatically retry. + + 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, + access_token: str, + type: Literal["1pw_update_access_token"], + access_token_expires_at: Union[str, datetime] | Omit = omit, + # 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`, not an automatic-retry signal. A transport error may + leave the outcome unknown; do not automatically retry. + + Args: + access_token_expires_at: Optional supplied expiry. Omit to clear the old expiry. + + 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 + """ + ... + @required_args( - ["id_or_name", "type"], ["id_or_name", "checkout", "type"], ["id_or_name", "browser_id", "fields", "type"] + ["id_or_name", "type"], + ["id_or_name", "checkout", "type"], + ["id_or_name", "browser_id", "fields", "type"], + ["id_or_name", "browser_id", "type"], + ["id_or_name", "browser_id", "page_url", "type"], + ["id_or_name", "access_token", "type"], ) def perform_operation( self, key: str, *, id_or_name: str, - type: Literal["authorize"] | Literal["collect"] | Literal["prepare_checkout"] | Literal["fill"], + type: Literal["authorize"] + | Literal["collect"] + | Literal["prepare_checkout"] + | Literal["fill"] + | Literal["1pw_create_access_request"] + | Literal["1pw_access_request_status"] + | Literal["1pw_fill"] + | Literal["1pw_recover"] + | Literal["1pw_update_access_token"], checkout: VaultCheckoutContextParam | Omit = omit, browser_id: str | Omit = omit, fields: Iterable[VaultFillFieldParam] | Omit = omit, page_url: str | Omit = omit, timeout_ms: int | Omit = omit, + goal: str | Omit = omit, + keywords: SequenceNotStr[str] | Omit = omit, + reason: str | Omit = omit, + timeout_seconds: int | Omit = omit, + entry_id: str | Omit = omit, + access_token: str | Omit = omit, + access_token_expires_at: Union[str, datetime] | Omit = omit, # 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, @@ -633,6 +914,13 @@ def perform_operation( "fields": fields, "page_url": page_url, "timeout_ms": timeout_ms, + "goal": goal, + "keywords": keywords, + "reason": reason, + "timeout_seconds": timeout_seconds, + "entry_id": entry_id, + "access_token": access_token, + "access_token_expires_at": access_token_expires_at, }, item_perform_operation_params.ItemPerformOperationParams, ), @@ -728,6 +1016,43 @@ def upsert( """ ... + @overload + def upsert( + self, + key: str, + *, + id_or_name: str, + spec: OnePasswordCredentialAccountSpecParam, + type: Literal["credential_account"], + # 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, + ) -> VaultItem: + """ + Create an item under a key unique within its vault, or retrieve the existing + item when its specification matches. An identical card PUT returns the existing + card in any lifecycle state without polling the provider, reauthorizing, + replacing aliases, or resetting recovery. Conflicting specifications return 409. + Provider-specific authorization requirements and retry behavior are described in + the item's request schema. Do not use credential items to store, collect, or + fill credit card data, including card numbers (PANs), security codes (CVV/CVC), + or expiration dates. Use wallet and card item types for credit cards and payment + checkout instead. + + 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 upsert( self, @@ -779,8 +1104,9 @@ def upsert( id_or_name: str, spec: item_upsert_params.WalletVaultItemRequestSpec | CardVaultItemSpecParam + | OnePasswordCredentialAccountSpecParam | CredentialVaultItemSpecInputParam, - type: Literal["wallet"] | Literal["card"] | Literal["credential"], + type: Literal["wallet"] | Literal["card"] | Literal["credential_account"] | Literal["credential"], # 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, @@ -1029,24 +1355,273 @@ async def update( ), ) - async def list( + async def list( + self, + id_or_name: str, + *, + # 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, + ) -> ItemListResponse: + """Credential entries include safe field metadata and non-sensitive values. + + Listing + never creates or renews collection sessions; only an existing unexpired active + session is included. Use single-item GET or collect to obtain a fresh link. + + 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 + """ + if not id_or_name: + raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}") + return await self._get( + path_template("/vaults/{id_or_name}/items", id_or_name=id_or_name), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ItemListResponse, + ) + + async def delete( + self, + key: str, + *, + id_or_name: str, + # 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, + ) -> None: + """ + Unresolved payment operations normally block deletion, including operations on + child cards of a wallet. An AgentCard card in recovery_required whose checkout + create response returned no authorization ID may be explicitly abandoned by + deleting that card directly; deleting its wallet or vault remains blocked. + Deleting or recreating an item is not proof that a payment did not occur. + + 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 + """ + if not id_or_name: + raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}") + if not key: + raise ValueError(f"Expected a non-empty value for `key` but received {key!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._delete( + path_template("/vaults/{id_or_name}/items/{key}", id_or_name=id_or_name, key=key), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def events( + self, + key: str, + *, + id_or_name: str, + after: str | Omit = omit, + wait: int | Omit = omit, + # 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, + ) -> ItemEventsResponse: + """ + List immutable audit events for a vault item + + Args: + after: Return events after this event ID. + + wait: Long-poll for new events for up to this many seconds. + + 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 id_or_name: + raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}") + if not key: + raise ValueError(f"Expected a non-empty value for `key` but received {key!r}") + return await self._get( + path_template("/vaults/{id_or_name}/items/{key}/events", id_or_name=id_or_name, key=key), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "after": after, + "wait": wait, + }, + item_events_params.ItemEventsParams, + ), + ), + cast_to=ItemEventsResponse, + ) + + @overload + async def perform_operation( + self, + key: str, + *, + id_or_name: str, + type: Literal["authorize"], + # 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`, not an automatic-retry signal. A transport error may + leave the outcome unknown; do not automatically retry. + + 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, + type: Literal["collect"], + # 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`, not an automatic-retry signal. A transport error may + leave the outcome unknown; do not automatically retry. + + 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, - id_or_name: str, + key: str, *, + id_or_name: str, + checkout: VaultCheckoutContextParam, + type: Literal["prepare_checkout"], # 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, - ) -> ItemListResponse: - """Credential entries include safe field metadata and non-sensitive values. + ) -> 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. - Listing - never creates or renews collection sessions; only an existing unexpired active - session is included. Use single-item GET or collect to obtain a fresh link. + 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`, not an automatic-retry signal. A transport error may + leave the outcome unknown; do not automatically retry. Args: + checkout: Required when preparing an unused AgentCard card for a supported checkout + processor. Consent is bound to this browser and declared merchant origin, not a + tab. Wait for the item's ready_to_submit status before native Pay and submit + within its readiness deadline. Unused preparations expire automatically; every + preparation is single-use, including after failure or expiry. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1055,36 +1630,61 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ - if not id_or_name: - raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}") - return await self._get( - path_template("/vaults/{id_or_name}/items", id_or_name=id_or_name), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ItemListResponse, - ) + ... - async def delete( + @overload + async def perform_operation( self, key: str, *, id_or_name: str, + browser_id: str, + fields: Iterable[VaultFillFieldParam], + type: Literal["fill"], + page_url: str | Omit = omit, + timeout_ms: int | Omit = omit, # 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, - ) -> None: + ) -> VaultItemOperationResponse: """ - Unresolved payment operations normally block deletion, including operations on - child cards of a wallet. An AgentCard card in recovery_required whose checkout - create response returned no authorization ID may be explicitly abandoned by - deleting that card directly; deleting its wallet or vault remains blocked. - Deleting or recreating an item is not proof that a payment did not occur. + 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`, not an automatic-retry signal. A transport error may + leave the outcome unknown; do not automatically retry. Args: + browser_id: Browser session ID, not a reusable browser name. + + fields: Field bindings for this step. No two bindings may resolve to the same element. + + page_url: Exact current top-level page URL, including path, query, and fragment. Must + match exactly one open page in the browser; zero or multiple matches fail. No + prefix or glob matching. Required for cards, which must use HTTPS without + embedded credentials. Optional for credentials, where omission requires exactly + one open page. + + timeout_ms: Total operation deadline in milliseconds, not a per-field timeout. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1093,40 +1693,50 @@ async def delete( timeout: Override the client-level default timeout for this request, in seconds """ - if not id_or_name: - raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}") - if not key: - raise ValueError(f"Expected a non-empty value for `key` but received {key!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - return await self._delete( - path_template("/vaults/{id_or_name}/items/{key}", id_or_name=id_or_name, key=key), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=NoneType, - ) + ... - async def events( + @overload + async def perform_operation( self, key: str, *, id_or_name: str, - after: str | Omit = omit, - wait: int | Omit = omit, + browser_id: str, + type: Literal["1pw_create_access_request"], + goal: str | Omit = omit, + keywords: SequenceNotStr[str] | Omit = omit, + reason: str | Omit = omit, # 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, - ) -> ItemEventsResponse: + ) -> VaultItemOperationResponse: """ - List immutable audit events for a vault item + 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. - Args: - after: Return events after this event ID. + 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`, not an automatic-retry signal. A transport error may + leave the outcome unknown; do not automatically retry. - wait: Long-poll for new events for up to this many seconds. + Args: + browser_id: Kernel browser session used to invoke the extension. extra_headers: Send extra headers @@ -1136,27 +1746,7 @@ async def events( timeout: Override the client-level default timeout for this request, in seconds """ - if not id_or_name: - raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}") - if not key: - raise ValueError(f"Expected a non-empty value for `key` but received {key!r}") - return await self._get( - path_template("/vaults/{id_or_name}/items/{key}/events", id_or_name=id_or_name, key=key), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - { - "after": after, - "wait": wait, - }, - item_events_params.ItemEventsParams, - ), - ), - cast_to=ItemEventsResponse, - ) + ... @overload async def perform_operation( @@ -1164,7 +1754,9 @@ async def perform_operation( key: str, *, id_or_name: str, - type: Literal["authorize"], + browser_id: str, + type: Literal["1pw_access_request_status"], + timeout_seconds: int | Omit = omit, # 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, @@ -1211,7 +1803,11 @@ async def perform_operation( key: str, *, id_or_name: str, - type: Literal["collect"], + browser_id: str, + page_url: str, + type: Literal["1pw_fill"], + entry_id: str | Omit = omit, + timeout_ms: int | Omit = omit, # 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, @@ -1242,6 +1838,14 @@ async def perform_operation( leave the outcome unknown; do not automatically retry. Args: + browser_id: Browser session ID, not a reusable browser name. + + page_url: Exact current top-level page URL. Must match exactly one open page in the + browser. + + entry_id: ID of an approved request entry. Required when several approved entries have the + page's origin. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1258,8 +1862,7 @@ async def perform_operation( key: str, *, id_or_name: str, - checkout: VaultCheckoutContextParam, - type: Literal["prepare_checkout"], + type: Literal["1pw_recover"], # 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, @@ -1290,12 +1893,6 @@ async def perform_operation( leave the outcome unknown; do not automatically retry. Args: - checkout: Required when preparing an unused AgentCard card for a supported checkout - processor. Consent is bound to this browser and declared merchant origin, not a - tab. Wait for the item's ready_to_submit status before native Pay and submit - within its readiness deadline. Unused preparations expire automatically; every - preparation is single-use, including after failure or expiry. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1312,11 +1909,9 @@ async def perform_operation( key: str, *, id_or_name: str, - browser_id: str, - fields: Iterable[VaultFillFieldParam], - type: Literal["fill"], - page_url: str | Omit = omit, - timeout_ms: int | Omit = omit, + access_token: str, + type: Literal["1pw_update_access_token"], + access_token_expires_at: Union[str, datetime] | Omit = omit, # 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, @@ -1347,17 +1942,7 @@ async def perform_operation( leave the outcome unknown; do not automatically retry. Args: - browser_id: Browser session ID, not a reusable browser name. - - fields: Field bindings for this step. No two bindings may resolve to the same element. - - page_url: Exact current top-level page URL, including path, query, and fragment. Must - match exactly one open page in the browser; zero or multiple matches fail. No - prefix or glob matching. Required for cards, which must use HTTPS without - embedded credentials. Optional for credentials, where omission requires exactly - one open page. - - timeout_ms: Total operation deadline in milliseconds, not a per-field timeout. + access_token_expires_at: Optional supplied expiry. Omit to clear the old expiry. extra_headers: Send extra headers @@ -1370,19 +1955,39 @@ async def perform_operation( ... @required_args( - ["id_or_name", "type"], ["id_or_name", "checkout", "type"], ["id_or_name", "browser_id", "fields", "type"] + ["id_or_name", "type"], + ["id_or_name", "checkout", "type"], + ["id_or_name", "browser_id", "fields", "type"], + ["id_or_name", "browser_id", "type"], + ["id_or_name", "browser_id", "page_url", "type"], + ["id_or_name", "access_token", "type"], ) async def perform_operation( self, key: str, *, id_or_name: str, - type: Literal["authorize"] | Literal["collect"] | Literal["prepare_checkout"] | Literal["fill"], + type: Literal["authorize"] + | Literal["collect"] + | Literal["prepare_checkout"] + | Literal["fill"] + | Literal["1pw_create_access_request"] + | Literal["1pw_access_request_status"] + | Literal["1pw_fill"] + | Literal["1pw_recover"] + | Literal["1pw_update_access_token"], checkout: VaultCheckoutContextParam | Omit = omit, browser_id: str | Omit = omit, fields: Iterable[VaultFillFieldParam] | Omit = omit, page_url: str | Omit = omit, timeout_ms: int | Omit = omit, + goal: str | Omit = omit, + keywords: SequenceNotStr[str] | Omit = omit, + reason: str | Omit = omit, + timeout_seconds: int | Omit = omit, + entry_id: str | Omit = omit, + access_token: str | Omit = omit, + access_token_expires_at: Union[str, datetime] | Omit = omit, # 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, @@ -1406,6 +2011,13 @@ async def perform_operation( "fields": fields, "page_url": page_url, "timeout_ms": timeout_ms, + "goal": goal, + "keywords": keywords, + "reason": reason, + "timeout_seconds": timeout_seconds, + "entry_id": entry_id, + "access_token": access_token, + "access_token_expires_at": access_token_expires_at, }, item_perform_operation_params.ItemPerformOperationParams, ), @@ -1501,6 +2113,43 @@ async def upsert( """ ... + @overload + async def upsert( + self, + key: str, + *, + id_or_name: str, + spec: OnePasswordCredentialAccountSpecParam, + type: Literal["credential_account"], + # 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, + ) -> VaultItem: + """ + Create an item under a key unique within its vault, or retrieve the existing + item when its specification matches. An identical card PUT returns the existing + card in any lifecycle state without polling the provider, reauthorizing, + replacing aliases, or resetting recovery. Conflicting specifications return 409. + Provider-specific authorization requirements and retry behavior are described in + the item's request schema. Do not use credential items to store, collect, or + fill credit card data, including card numbers (PANs), security codes (CVV/CVC), + or expiration dates. Use wallet and card item types for credit cards and payment + checkout instead. + + 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 upsert( self, @@ -1552,8 +2201,9 @@ async def upsert( id_or_name: str, spec: item_upsert_params.WalletVaultItemRequestSpec | CardVaultItemSpecParam + | OnePasswordCredentialAccountSpecParam | CredentialVaultItemSpecInputParam, - type: Literal["wallet"] | Literal["card"] | Literal["credential"], + type: Literal["wallet"] | Literal["card"] | Literal["credential_account"] | Literal["credential"], # 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, diff --git a/src/kernel/types/vaults/__init__.py b/src/kernel/types/vaults/__init__.py index e2dd28eb..220eafc2 100644 --- a/src/kernel/types/vaults/__init__.py +++ b/src/kernel/types/vaults/__init__.py @@ -20,6 +20,7 @@ from .wallet_vault_item_spec import WalletVaultItemSpec as WalletVaultItemSpec from .vault_fill_field_result import VaultFillFieldResult as VaultFillFieldResult from .wallet_vault_item_state import WalletVaultItemState as WalletVaultItemState +from .one_password_oauth_action import OnePasswordOAuthAction as OnePasswordOAuthAction from .card_vault_item_spec_param import CardVaultItemSpecParam as CardVaultItemSpecParam from .credential_vault_item_spec import CredentialVaultItemSpec as CredentialVaultItemSpec from .credential_vault_field_type import CredentialVaultFieldType as CredentialVaultFieldType @@ -28,15 +29,22 @@ from .credential_collection_action import CredentialCollectionAction as CredentialCollectionAction from .credential_vault_field_state import CredentialVaultFieldState as CredentialVaultFieldState from .vault_checkout_context_param import VaultCheckoutContextParam as VaultCheckoutContextParam +from .credential_account_vault_item import CredentialAccountVaultItem as CredentialAccountVaultItem from .item_perform_operation_params import ItemPerformOperationParams as ItemPerformOperationParams from .vault_item_operation_response import VaultItemOperationResponse as VaultItemOperationResponse from .agentcard_checkout_preparation import AgentcardCheckoutPreparation as AgentcardCheckoutPreparation from .agentcard_checkout_authorization import AgentcardCheckoutAuthorization as AgentcardCheckoutAuthorization from .fill_vault_item_operation_result import FillVaultItemOperationResult as FillVaultItemOperationResult from .credential_vault_field_definition import CredentialVaultFieldDefinition as CredentialVaultFieldDefinition +from .kernel_credential_vault_item_spec import KernelCredentialVaultItemSpec as KernelCredentialVaultItemSpec from .credential_vault_field_input_param import CredentialVaultFieldInputParam as CredentialVaultFieldInputParam +from .kernel_credential_vault_item_state import KernelCredentialVaultItemState as KernelCredentialVaultItemState from .credential_vault_field_update_param import CredentialVaultFieldUpdateParam as CredentialVaultFieldUpdateParam from .credential_vault_item_request_param import CredentialVaultItemRequestParam as CredentialVaultItemRequestParam +from .one_password_credential_account_spec import OnePasswordCredentialAccountSpec as OnePasswordCredentialAccountSpec +from .one_password_credential_account_state import ( + OnePasswordCredentialAccountState as OnePasswordCredentialAccountState, +) from .credential_vault_item_spec_input_param import ( CredentialVaultItemSpecInputParam as CredentialVaultItemSpecInputParam, ) @@ -46,15 +54,45 @@ from .fill_vault_item_operation_request_param import ( FillVaultItemOperationRequestParam as FillVaultItemOperationRequestParam, ) +from .one_password_credential_vault_item_spec import ( + OnePasswordCredentialVaultItemSpec as OnePasswordCredentialVaultItemSpec, +) +from .one_password_credential_vault_item_state import ( + OnePasswordCredentialVaultItemState as OnePasswordCredentialVaultItemState, +) from .collect_vault_item_operation_request_param import ( CollectVaultItemOperationRequestParam as CollectVaultItemOperationRequestParam, ) from .credential_vault_item_update_request_param import ( CredentialVaultItemUpdateRequestParam as CredentialVaultItemUpdateRequestParam, ) +from .one_password_credential_account_spec_param import ( + OnePasswordCredentialAccountSpecParam as OnePasswordCredentialAccountSpecParam, +) +from .credential_account_vault_item_request_param import ( + CredentialAccountVaultItemRequestParam as CredentialAccountVaultItemRequestParam, +) from .authorize_vault_item_operation_request_param import ( AuthorizeVaultItemOperationRequestParam as AuthorizeVaultItemOperationRequestParam, ) +from .kernel_credential_vault_item_spec_input_param import ( + KernelCredentialVaultItemSpecInputParam as KernelCredentialVaultItemSpecInputParam, +) +from .one_password_fill_vault_item_operation_result import ( + OnePasswordFillVaultItemOperationResult as OnePasswordFillVaultItemOperationResult, +) +from .one_password_credential_vault_item_spec_input_param import ( + OnePasswordCredentialVaultItemSpecInputParam as OnePasswordCredentialVaultItemSpecInputParam, +) from .prepare_checkout_vault_item_operation_request_param import ( PrepareCheckoutVaultItemOperationRequestParam as PrepareCheckoutVaultItemOperationRequestParam, ) +from .one_password_fill_vault_item_operation_request_param import ( + OnePasswordFillVaultItemOperationRequestParam as OnePasswordFillVaultItemOperationRequestParam, +) +from .one_password_recover_vault_item_operation_request_param import ( + OnePasswordRecoverVaultItemOperationRequestParam as OnePasswordRecoverVaultItemOperationRequestParam, +) +from .one_password_request_access_vault_item_operation_request_param import ( + OnePasswordRequestAccessVaultItemOperationRequestParam as OnePasswordRequestAccessVaultItemOperationRequestParam, +) diff --git a/src/kernel/types/vaults/credential_account_vault_item.py b/src/kernel/types/vaults/credential_account_vault_item.py new file mode 100644 index 00000000..ef7555cb --- /dev/null +++ b/src/kernel/types/vaults/credential_account_vault_item.py @@ -0,0 +1,73 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel +from .one_password_oauth_action import OnePasswordOAuthAction +from .one_password_credential_account_spec import OnePasswordCredentialAccountSpec +from .one_password_credential_account_state import OnePasswordCredentialAccountState + +__all__ = ["CredentialAccountVaultItem", "AvailableExpansion", "AvailableOperation"] + + +class AvailableExpansion(BaseModel): + """ + Live data that can currently be requested by passing its type to the item GET expand parameter. + """ + + description: str + + type: Literal["payment_methods"] + + +class AvailableOperation(BaseModel): + """An operation that is currently valid for this item. + + Read the description before invoking it through the item operations endpoint. + """ + + description: str + + type: Literal[ + "authorize", + "collect", + "prepare_checkout", + "fill", + "1pw_create_access_request", + "1pw_access_request_status", + "1pw_fill", + "1pw_recover", + "1pw_update_access_token", + ] + + +class CredentialAccountVaultItem(BaseModel): + id: str + + available_expansions: List[AvailableExpansion] + + available_operations: List[AvailableOperation] + """Advertises 1pw_recover when Kernel can recover a failed account link. + + Recovery is unavailable while authorization is pending or after the connection + has already been reset. + """ + + created_at: datetime + + key: str + """Immutable item key assigned when the item is created.""" + + spec: OnePasswordCredentialAccountSpec + + state: OnePasswordCredentialAccountState + + type: Literal["credential_account"] + + updated_at: datetime + + action: Optional[OnePasswordOAuthAction] = None + + expires_at: Optional[datetime] = None diff --git a/src/kernel/types/vaults/credential_account_vault_item_request_param.py b/src/kernel/types/vaults/credential_account_vault_item_request_param.py new file mode 100644 index 00000000..187b25f2 --- /dev/null +++ b/src/kernel/types/vaults/credential_account_vault_item_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 + +from .one_password_credential_account_spec_param import OnePasswordCredentialAccountSpecParam + +__all__ = ["CredentialAccountVaultItemRequestParam"] + + +class CredentialAccountVaultItemRequestParam(TypedDict, total=False): + spec: Required[OnePasswordCredentialAccountSpecParam] + + type: Required[Literal["credential_account"]] diff --git a/src/kernel/types/vaults/credential_vault_item.py b/src/kernel/types/vaults/credential_vault_item.py index 79c12abc..3cee5030 100644 --- a/src/kernel/types/vaults/credential_vault_item.py +++ b/src/kernel/types/vaults/credential_vault_item.py @@ -1,15 +1,22 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List, Union, Optional from datetime import datetime -from typing_extensions import Literal +from typing_extensions import Literal, Annotated, TypeAlias +from ..._utils import PropertyInfo from ..._models import BaseModel from .credential_vault_item_spec import CredentialVaultItemSpec from .credential_vault_item_state import CredentialVaultItemState from .credential_collection_action import CredentialCollectionAction -__all__ = ["CredentialVaultItem", "AvailableExpansion", "AvailableOperation"] +__all__ = [ + "CredentialVaultItem", + "AvailableExpansion", + "AvailableOperation", + "Action", + "ActionOnePasswordAccessApprovalAction", +] class AvailableExpansion(BaseModel): @@ -30,7 +37,39 @@ class AvailableOperation(BaseModel): description: str - type: Literal["authorize", "collect", "prepare_checkout", "fill"] + type: Literal[ + "authorize", + "collect", + "prepare_checkout", + "fill", + "1pw_create_access_request", + "1pw_access_request_status", + "1pw_fill", + "1pw_recover", + "1pw_update_access_token", + ] + + +class ActionOnePasswordAccessApprovalAction(BaseModel): + instructions: str + """ + Steps for the agent to hand approval to the human and poll the resulting + decision. + """ + + name: Literal["1password_access_approval"] + + url: str + """Native 1Password approval link. + + Present it to the account owner without modifying it; it does not grant access + until they approve in their app. + """ + + +Action: TypeAlias = Annotated[ + Union[CredentialCollectionAction, ActionOnePasswordAccessApprovalAction], PropertyInfo(discriminator="name") +] class CredentialVaultItem(BaseModel): @@ -39,9 +78,11 @@ class CredentialVaultItem(BaseModel): available_expansions: List[AvailableExpansion] available_operations: List[AvailableOperation] - """Advertises collect for ready and pending_collection items. + """Kernel credentials advertise collect and fill when eligible. - Browser fill is advertised only when separately implemented and eligible. + 1Password credentials advertise 1pw_create_access_request until a request is + made, 1pw_access_request_status while its approval is pending, and 1pw_fill + after access is granted. """ created_at: datetime @@ -50,6 +91,10 @@ class CredentialVaultItem(BaseModel): """Immutable item key assigned when the item is created.""" spec: CredentialVaultItemSpec + """ + Stored-token credentials omit account and never return access_token or + integration_key. + """ state: CredentialVaultItemState @@ -63,7 +108,7 @@ class CredentialVaultItem(BaseModel): collection-link renewal. """ - action: Optional[CredentialCollectionAction] = None + action: Optional[Action] = None """ One schema-derived form for the item, available in ready or pending_collection state. Render every form-supported field as editable; omit totp fields and diff --git a/src/kernel/types/vaults/credential_vault_item_request_param.py b/src/kernel/types/vaults/credential_vault_item_request_param.py index 169af036..84d03bf5 100644 --- a/src/kernel/types/vaults/credential_vault_item_request_param.py +++ b/src/kernel/types/vaults/credential_vault_item_request_param.py @@ -11,19 +11,18 @@ class CredentialVaultItemRequestParam(TypedDict, total=False): """ - Create a credential item without a wallet or external provider. - Do not use credential items to store, collect, or fill credit card data, - including card numbers (PANs), security codes (CVV/CVC), or expiration dates. - Use wallet and card item types for credit cards and payment checkout instead. - If all required fields have values, return ready without a collection action; - collect can still open its form. Otherwise return pending_collection with - a time-scoped Kernel-hosted collection action. Missing - optional fields alone do not trigger collection. Repeating the original - creation request returns the current item without overwriting later edits; - a different request at the same key returns 409. Use PATCH for updates. - Required totp fields must include a valid seed on creation; otherwise return - 400 rather than opening a form that cannot collect it. Optional totp fields - may be unset and populated later through PATCH. + Ask the end-user whether to link their site credential through 1Password. + If they choose 1Password, connect their account and request access to a login + in their own non-shared vault; passkeys are not supported. If they decline + or that path fails, collect a Kernel-hosted credential item instead. Never + automatically retry an uncertain 1Password request or fill. + Do not use credential items for credit card data. Use wallet and card item types instead. + Kernel credentials declare fields and may enter pending_collection. + 1Password credentials either reference a connected credential_account or + store a supplied access token and integration key encrypted on the item. + They store no login values or selectors. Repeating the original creation + request returns the current item without overwriting later state. A + different request at the same key returns 409. """ spec: Required[CredentialVaultItemSpecInputParam] diff --git a/src/kernel/types/vaults/credential_vault_item_spec.py b/src/kernel/types/vaults/credential_vault_item_spec.py index 307d2b25..fe452071 100644 --- a/src/kernel/types/vaults/credential_vault_item_spec.py +++ b/src/kernel/types/vaults/credential_vault_item_spec.py @@ -1,22 +1,14 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Union +from typing_extensions import Annotated, TypeAlias -from ..._models import BaseModel -from .credential_vault_field_definition import CredentialVaultFieldDefinition +from ..._utils import PropertyInfo +from .kernel_credential_vault_item_spec import KernelCredentialVaultItemSpec +from .one_password_credential_vault_item_spec import OnePasswordCredentialVaultItemSpec __all__ = ["CredentialVaultItemSpec"] - -class CredentialVaultItemSpec(BaseModel): - fields: List[CredentialVaultFieldDefinition] - """ - Ordered field definitions rendered in this order by credential collection forms. - """ - - description: Optional[str] = None - """ - Recognizable site or service name displayed verbatim as the form title, without - suffixes such as sign-in credentials. Display text only, not an enforced - destination policy. - """ +CredentialVaultItemSpec: TypeAlias = Annotated[ + Union[KernelCredentialVaultItemSpec, OnePasswordCredentialVaultItemSpec], PropertyInfo(discriminator="provider") +] diff --git a/src/kernel/types/vaults/credential_vault_item_spec_input_param.py b/src/kernel/types/vaults/credential_vault_item_spec_input_param.py index ab4eaee8..3b36cbeb 100644 --- a/src/kernel/types/vaults/credential_vault_item_spec_input_param.py +++ b/src/kernel/types/vaults/credential_vault_item_spec_input_param.py @@ -2,31 +2,14 @@ from __future__ import annotations -from typing import Iterable -from typing_extensions import Required, TypedDict +from typing import Union +from typing_extensions import TypeAlias -from .credential_vault_field_input_param import CredentialVaultFieldInputParam +from .kernel_credential_vault_item_spec_input_param import KernelCredentialVaultItemSpecInputParam +from .one_password_credential_vault_item_spec_input_param import OnePasswordCredentialVaultItemSpecInputParam __all__ = ["CredentialVaultItemSpecInputParam"] - -class CredentialVaultItemSpecInputParam(TypedDict, total=False): - """Credential fields are for login and other non-payment credentials. - - Do not store, collect, or fill credit card data in credential items. Use wallet and card item types for credit cards and payment checkout instead. Field order is preserved in the user-facing collection form, so list fields in the same top-to-bottom order as the website. - """ - - fields: Required[Iterable[CredentialVaultFieldInputParam]] - """Ordered field definitions. - - Use the website's top-to-bottom field order; the collection form renders this - order unchanged. - """ - - description: str - """ - The site's recognizable display name, used verbatim as the user-facing form - title (for example, Hacker News). Use only the site or service name; do not - append sign-in, login, credentials, or task instructions. This is display text, - not an enforced destination policy. At most 16 KiB in UTF-8 bytes. - """ +CredentialVaultItemSpecInputParam: TypeAlias = Union[ + KernelCredentialVaultItemSpecInputParam, OnePasswordCredentialVaultItemSpecInputParam +] diff --git a/src/kernel/types/vaults/credential_vault_item_state.py b/src/kernel/types/vaults/credential_vault_item_state.py index 7d64ad95..8c0077e0 100644 --- a/src/kernel/types/vaults/credential_vault_item_state.py +++ b/src/kernel/types/vaults/credential_vault_item_state.py @@ -1,20 +1,14 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict -from typing_extensions import Literal +from typing import Union +from typing_extensions import Annotated, TypeAlias -from ..._models import BaseModel -from .credential_vault_field_state import CredentialVaultFieldState +from ..._utils import PropertyInfo +from .kernel_credential_vault_item_state import KernelCredentialVaultItemState +from .one_password_credential_vault_item_state import OnePasswordCredentialVaultItemState __all__ = ["CredentialVaultItemState"] - -class CredentialVaultItemState(BaseModel): - fields: Dict[str, CredentialVaultFieldState] - """Exactly one entry for each declared field.""" - - status: Literal["pending_collection", "ready"] - """Ready means all required fields have values, not that a login succeeded. - - Optional fields may remain unset. - """ +CredentialVaultItemState: TypeAlias = Annotated[ + Union[KernelCredentialVaultItemState, OnePasswordCredentialVaultItemState], PropertyInfo(discriminator="provider") +] diff --git a/src/kernel/types/vaults/item_perform_operation_params.py b/src/kernel/types/vaults/item_perform_operation_params.py index 7e866ff3..8d1490b5 100644 --- a/src/kernel/types/vaults/item_perform_operation_params.py +++ b/src/kernel/types/vaults/item_perform_operation_params.py @@ -3,8 +3,11 @@ from __future__ import annotations from typing import Union, Iterable -from typing_extensions import Literal, Required, TypeAlias, TypedDict +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict +from ..._types import SequenceNotStr +from ..._utils import PropertyInfo from .vault_fill_field_param import VaultFillFieldParam from .vault_checkout_context_param import VaultCheckoutContextParam @@ -14,6 +17,11 @@ "CollectVaultItemOperationRequest", "PrepareCheckoutVaultItemOperationRequest", "FillVaultItemOperationRequest", + "OnePasswordRequestAccessVaultItemOperationRequest", + "OnePasswordPollAccessVaultItemOperationRequest", + "OnePasswordFillVaultItemOperationRequest", + "OnePasswordRecoverVaultItemOperationRequest", + "OnePasswordUpdateAccessTokenVaultItemOperationRequest", ] @@ -68,9 +76,79 @@ class FillVaultItemOperationRequest(TypedDict, total=False): """Total operation deadline in milliseconds, not a per-field timeout.""" +class OnePasswordRequestAccessVaultItemOperationRequest(TypedDict, total=False): + id_or_name: Required[str] + + browser_id: Required[str] + """Kernel browser session used to invoke the extension.""" + + type: Required[Literal["1pw_create_access_request"]] + + goal: str + + keywords: SequenceNotStr[str] + + reason: str + + +class OnePasswordPollAccessVaultItemOperationRequest(TypedDict, total=False): + id_or_name: Required[str] + + browser_id: Required[str] + + type: Required[Literal["1pw_access_request_status"]] + + timeout_seconds: int + + +class OnePasswordFillVaultItemOperationRequest(TypedDict, total=False): + id_or_name: Required[str] + + browser_id: Required[str] + """Browser session ID, not a reusable browser name.""" + + page_url: Required[str] + """Exact current top-level page URL. + + Must match exactly one open page in the browser. + """ + + type: Required[Literal["1pw_fill"]] + + entry_id: str + """ID of an approved request entry. + + Required when several approved entries have the page's origin. + """ + + timeout_ms: int + + +class OnePasswordRecoverVaultItemOperationRequest(TypedDict, total=False): + id_or_name: Required[str] + + type: Required[Literal["1pw_recover"]] + + +class OnePasswordUpdateAccessTokenVaultItemOperationRequest(TypedDict, total=False): + id_or_name: Required[str] + + access_token: Required[str] + + type: Required[Literal["1pw_update_access_token"]] + + access_token_expires_at: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """Optional supplied expiry. Omit to clear the old expiry.""" + + ItemPerformOperationParams: TypeAlias = Union[ AuthorizeVaultItemOperationRequest, CollectVaultItemOperationRequest, PrepareCheckoutVaultItemOperationRequest, FillVaultItemOperationRequest, + OnePasswordRequestAccessVaultItemOperationRequest, + OnePasswordPollAccessVaultItemOperationRequest, + OnePasswordFillVaultItemOperationRequest, + OnePasswordRecoverVaultItemOperationRequest, + OnePasswordUpdateAccessTokenVaultItemOperationRequest, ] diff --git a/src/kernel/types/vaults/item_upsert_params.py b/src/kernel/types/vaults/item_upsert_params.py index 4e4799dd..fc9acbdf 100644 --- a/src/kernel/types/vaults/item_upsert_params.py +++ b/src/kernel/types/vaults/item_upsert_params.py @@ -7,6 +7,7 @@ from .card_vault_item_spec_param import CardVaultItemSpecParam from .credential_vault_item_spec_input_param import CredentialVaultItemSpecInputParam +from .one_password_credential_account_spec_param import OnePasswordCredentialAccountSpecParam __all__ = [ "ItemUpsertParams", @@ -23,6 +24,7 @@ "WalletVaultItemRequestSpecAgentCardWalletVaultItemSpec", "WalletVaultItemRequestSpecAgentCardWalletVaultItemSpecProviderConfig", "CardVaultItemRequest", + "CredentialAccountVaultItemRequest", "CredentialVaultItemRequest", ] @@ -67,7 +69,7 @@ class WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImpor ): """Select a provider config by ID or name. - Responses return the ID. Renaming a config does not change existing wallet bindings; a wallet cannot switch to a different config after creation. + Responses return the ID. Renaming a config does not change existing wallet bindings; an item cannot switch to a different config after creation. """ id: str @@ -84,7 +86,7 @@ class WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImpor """Select a provider config by ID or name. Responses return the ID. Renaming a config does not change existing wallet - bindings; a wallet cannot switch to a different config after creation. + bindings; an item cannot switch to a different config after creation. """ type: Required[Literal["customer_managed"]] @@ -187,6 +189,14 @@ class CardVaultItemRequest(TypedDict, total=False): type: Required[Literal["card"]] +class CredentialAccountVaultItemRequest(TypedDict, total=False): + id_or_name: Required[str] + + spec: Required[OnePasswordCredentialAccountSpecParam] + + type: Required[Literal["credential_account"]] + + class CredentialVaultItemRequest(TypedDict, total=False): id_or_name: Required[str] @@ -202,4 +212,6 @@ class CredentialVaultItemRequest(TypedDict, total=False): type: Required[Literal["credential"]] -ItemUpsertParams: TypeAlias = Union[WalletVaultItemRequest, CardVaultItemRequest, CredentialVaultItemRequest] +ItemUpsertParams: TypeAlias = Union[ + WalletVaultItemRequest, CardVaultItemRequest, CredentialAccountVaultItemRequest, CredentialVaultItemRequest +] diff --git a/src/kernel/types/vaults/kernel_credential_vault_item_spec.py b/src/kernel/types/vaults/kernel_credential_vault_item_spec.py new file mode 100644 index 00000000..a58a11d6 --- /dev/null +++ b/src/kernel/types/vaults/kernel_credential_vault_item_spec.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from ..._models import BaseModel +from .credential_vault_field_definition import CredentialVaultFieldDefinition + +__all__ = ["KernelCredentialVaultItemSpec"] + + +class KernelCredentialVaultItemSpec(BaseModel): + fields: List[CredentialVaultFieldDefinition] + """ + Ordered field definitions rendered in this order by credential collection forms. + """ + + provider: Literal["kernel"] + + description: Optional[str] = None + """ + Recognizable site or service name displayed verbatim as the form title, without + suffixes such as sign-in credentials. Display text only, not an enforced + destination policy. + """ diff --git a/src/kernel/types/vaults/kernel_credential_vault_item_spec_input_param.py b/src/kernel/types/vaults/kernel_credential_vault_item_spec_input_param.py new file mode 100644 index 00000000..d8ae9257 --- /dev/null +++ b/src/kernel/types/vaults/kernel_credential_vault_item_spec_input_param.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal, Required, TypedDict + +from .credential_vault_field_input_param import CredentialVaultFieldInputParam + +__all__ = ["KernelCredentialVaultItemSpecInputParam"] + + +class KernelCredentialVaultItemSpecInputParam(TypedDict, total=False): + """Credential fields are for login and other non-payment credentials. + + Do not store, collect, or fill credit card data in credential items. Use wallet and card item types for credit cards and payment checkout instead. Field order is preserved in the user-facing collection form, so list fields in the same top-to-bottom order as the website. + """ + + fields: Required[Iterable[CredentialVaultFieldInputParam]] + """Ordered field definitions. + + Use the website's top-to-bottom field order; the collection form renders this + order unchanged. + """ + + provider: Required[Literal["kernel"]] + + description: str + """ + The site's recognizable display name, used verbatim as the user-facing form + title (for example, Hacker News). Use only the site or service name; do not + append sign-in, login, credentials, or task instructions. This is display text, + not an enforced destination policy. At most 16 KiB in UTF-8 bytes. + """ diff --git a/src/kernel/types/vaults/kernel_credential_vault_item_state.py b/src/kernel/types/vaults/kernel_credential_vault_item_state.py new file mode 100644 index 00000000..48a85af0 --- /dev/null +++ b/src/kernel/types/vaults/kernel_credential_vault_item_state.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict +from typing_extensions import Literal + +from ..._models import BaseModel +from .credential_vault_field_state import CredentialVaultFieldState + +__all__ = ["KernelCredentialVaultItemState"] + + +class KernelCredentialVaultItemState(BaseModel): + fields: Dict[str, CredentialVaultFieldState] + """Exactly one entry for each declared field.""" + + provider: Literal["kernel"] + + status: Literal["pending_collection", "ready"] + """Ready means all required fields have values, not that a login succeeded. + + Optional fields may remain unset. + """ diff --git a/src/kernel/types/vaults/one_password_credential_account_spec.py b/src/kernel/types/vaults/one_password_credential_account_spec.py new file mode 100644 index 00000000..cea6ee4d --- /dev/null +++ b/src/kernel/types/vaults/one_password_credential_account_spec.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["OnePasswordCredentialAccountSpec", "Authorization", "AuthorizationClient"] + + +class AuthorizationClient(BaseModel): + type: Literal["kernel_managed"] + + +class Authorization(BaseModel): + client: AuthorizationClient + + method: Literal["oauth"] + + +class OnePasswordCredentialAccountSpec(BaseModel): + authorization: Authorization + + provider: Literal["1password"] diff --git a/src/kernel/types/vaults/one_password_credential_account_spec_param.py b/src/kernel/types/vaults/one_password_credential_account_spec_param.py new file mode 100644 index 00000000..12bf6023 --- /dev/null +++ b/src/kernel/types/vaults/one_password_credential_account_spec_param.py @@ -0,0 +1,23 @@ +# 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__ = ["OnePasswordCredentialAccountSpecParam", "Authorization", "AuthorizationClient"] + + +class AuthorizationClient(TypedDict, total=False): + type: Required[Literal["kernel_managed"]] + + +class Authorization(TypedDict, total=False): + client: Required[AuthorizationClient] + + method: Required[Literal["oauth"]] + + +class OnePasswordCredentialAccountSpecParam(TypedDict, total=False): + authorization: Required[Authorization] + + provider: Required[Literal["1password"]] diff --git a/src/kernel/types/vaults/one_password_credential_account_state.py b/src/kernel/types/vaults/one_password_credential_account_state.py new file mode 100644 index 00000000..07eab56b --- /dev/null +++ b/src/kernel/types/vaults/one_password_credential_account_state.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["OnePasswordCredentialAccountState"] + + +class OnePasswordCredentialAccountState(BaseModel): + provider: Literal["1password"] + + status: Literal["pending_authorization", "connected", "reconnect_required", "declined"] + + status_reason: Optional[str] = None diff --git a/src/kernel/types/vaults/one_password_credential_vault_item_spec.py b/src/kernel/types/vaults/one_password_credential_vault_item_spec.py new file mode 100644 index 00000000..84811174 --- /dev/null +++ b/src/kernel/types/vaults/one_password_credential_vault_item_spec.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["OnePasswordCredentialVaultItemSpec", "Requests", "RequestsEntry", "RequestsEntryParameters"] + + +class RequestsEntryParameters(BaseModel): + website: str + + +class RequestsEntry(BaseModel): + parameters: RequestsEntryParameters + + type: str + """Must be login.""" + + keywords: Optional[List[str]] = None + + reason: Optional[str] = None + + +class Requests(BaseModel): + """Credential Request v2 input sent to the extension. + + A credential item may request up to five login entries. + """ + + entries: List[RequestsEntry] + + version: int + """Must be 2.""" + + goal: Optional[str] = None + + +class OnePasswordCredentialVaultItemSpec(BaseModel): + """ + Stored-token credentials omit account and never return access_token or integration_key. + """ + + provider: Literal["1password"] + + requests: Requests + """Credential Request v2 input sent to the extension. + + A credential item may request up to five login entries. + """ + + access_token_expires_at: Optional[datetime] = None + """Customer-supplied expiry metadata, if provided.""" + + account: Optional[str] = None diff --git a/src/kernel/types/vaults/one_password_credential_vault_item_spec_input_param.py b/src/kernel/types/vaults/one_password_credential_vault_item_spec_input_param.py new file mode 100644 index 00000000..3a2b4c19 --- /dev/null +++ b/src/kernel/types/vaults/one_password_credential_vault_item_spec_input_param.py @@ -0,0 +1,84 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union, Iterable +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._types import SequenceNotStr +from ..._utils import PropertyInfo + +__all__ = ["OnePasswordCredentialVaultItemSpecInputParam", "Requests", "RequestsEntry", "RequestsEntryParameters"] + + +class RequestsEntryParameters(TypedDict, total=False): + website: Required[str] + + +class RequestsEntry(TypedDict, total=False): + parameters: Required[RequestsEntryParameters] + + type: Required[str] + """Must be login.""" + + keywords: SequenceNotStr[str] + + reason: str + + +class Requests(TypedDict, total=False): + """Credential Request v2 input sent to the extension. + + A credential item may request up to five login entries. + """ + + entries: Required[Iterable[RequestsEntry]] + + version: Required[int] + """Must be 2.""" + + goal: str + + +class OnePasswordCredentialVaultItemSpecInputParam(TypedDict, total=False): + """ + A login request backed by a connected 1Password account or by a customer-supplied access token and matching integration key. Supply either account or both secrets, never both. Supplied secrets are write-only and never returned. Supply requests for new items; website remains supported for existing account-backed callers. + """ + + provider: Required[Literal["1password"]] + + access_token: str + """Customer-supplied 1Password broker token. + + Requires integration_key; stored encrypted on this item. Omit if providing a + connected credential_account item via the account field. + """ + + access_token_expires_at: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """Optional supplied token expiry metadata for stored-token credentials. + + Omit if providing a connected credential_account item via the account field. + """ + + account: str + """Key of a connected credential_account item in the same vault. + + Omit for stored-token credentials. + """ + + integration_key: str + """Matching customer-supplied integration key. + + Requires access_token; stored encrypted on this item. Omit if providing a + connected credential_account item via the account field. + """ + + requests: Requests + """Credential Request v2 input sent to the extension. + + A credential item may request up to five login entries. + """ + + website: str + """Legacy single-login shorthand. Supply requests instead.""" diff --git a/src/kernel/types/vaults/one_password_credential_vault_item_state.py b/src/kernel/types/vaults/one_password_credential_vault_item_state.py new file mode 100644 index 00000000..5cf9b390 --- /dev/null +++ b/src/kernel/types/vaults/one_password_credential_vault_item_state.py @@ -0,0 +1,125 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = [ + "OnePasswordCredentialVaultItemState", + "AccessRequest", + "AccessRequestEntry", + "AccessRequestEntryParameters", + "AccessRequestRequest", + "AccessRequestRequestEntry", + "AccessRequestRequestEntryParameters", +] + + +class AccessRequestEntryParameters(BaseModel): + website: Optional[str] = None + + +class AccessRequestEntry(BaseModel): + id: Optional[str] = None + + keywords: Optional[List[str]] = None + + parameters: Optional[AccessRequestEntryParameters] = None + + reason: Optional[str] = None + + type: Optional[str] = None + + +class AccessRequestRequestEntryParameters(BaseModel): + website: Optional[str] = None + + +class AccessRequestRequestEntry(BaseModel): + id: Optional[str] = None + + keywords: Optional[List[str]] = None + + parameters: Optional[AccessRequestRequestEntryParameters] = None + + reason: Optional[str] = None + + type: Optional[str] = None + + +class AccessRequestRequest(BaseModel): + """The request object if returned by the extension. + + The observed create response may omit entries; no entry IDs are invented. + """ + + entries: Optional[List[AccessRequestRequestEntry]] = None + + goal: Optional[str] = None + + version: Optional[int] = None + + +class AccessRequest(BaseModel): + """Non-secret broker state. + + Granted credential references stay encrypted server-side and can only be used by the fill operation. + """ + + id: str + + has_autofill_token: bool + + state: str + """One of pending, resolved, denied, or failed.""" + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + """Provider-created timestamp as returned by the broker.""" + + entries: Optional[List[AccessRequestEntry]] = None + """Login entries returned directly on accessRequest by the observed extension + build. + + Omitted when the provider does not supply them. + """ + + goal: Optional[str] = None + """Goal echoed by the observed createAccessRequest response when present.""" + + granted_count: Optional[int] = None + + identity: Optional[str] = None + """Opaque provider identity returned by the broker.""" + + path: Optional[str] = None + """Provider path if supplied in the broker response.""" + + request: Optional[AccessRequestRequest] = None + """The request object if returned by the extension. + + The observed create response may omit entries; no entry IDs are invented. + """ + + +class OnePasswordCredentialVaultItemState(BaseModel): + provider: Literal["1password"] + + status: Literal["pending_authorization", "ready", "declined", "failed"] + + access_request: Optional[AccessRequest] = None + """Non-secret broker state. + + Granted credential references stay encrypted server-side and can only be used by + the fill operation. + """ + + access_request_id: Optional[str] = None + """ + Opaque request ID returned by the 1Password broker after a successful + createAccessRequest call. + """ + + status_reason: Optional[str] = None diff --git a/src/kernel/types/vaults/one_password_fill_vault_item_operation_request_param.py b/src/kernel/types/vaults/one_password_fill_vault_item_operation_request_param.py new file mode 100644 index 00000000..f36a456c --- /dev/null +++ b/src/kernel/types/vaults/one_password_fill_vault_item_operation_request_param.py @@ -0,0 +1,33 @@ +# 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__ = ["OnePasswordFillVaultItemOperationRequestParam"] + + +class OnePasswordFillVaultItemOperationRequestParam(TypedDict, total=False): + """Fill and submit an approved 1Password login in the selected browser page. + + The page must share the selected entry's login origin. Supply entry_id when more than one approved entry matches the page origin. The extension selects fields; callers cannot supply selectors or secret values. Submission does not confirm website authentication. + """ + + browser_id: Required[str] + """Browser session ID, not a reusable browser name.""" + + page_url: Required[str] + """Exact current top-level page URL. + + Must match exactly one open page in the browser. + """ + + type: Required[Literal["1pw_fill"]] + + entry_id: str + """ID of an approved request entry. + + Required when several approved entries have the page's origin. + """ + + timeout_ms: int diff --git a/src/kernel/types/vaults/one_password_fill_vault_item_operation_result.py b/src/kernel/types/vaults/one_password_fill_vault_item_operation_result.py new file mode 100644 index 00000000..b1586f5b --- /dev/null +++ b/src/kernel/types/vaults/one_password_fill_vault_item_operation_result.py @@ -0,0 +1,36 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["OnePasswordFillVaultItemOperationResult"] + + +class OnePasswordFillVaultItemOperationResult(BaseModel): + """The submission result reported by the 1Password extension when available. + + Kernel returns fill_unknown if the extension call has no conclusive result. Inspect the page to determine successful authentication on the website. + """ + + status: Literal["fill_submitted", "fill_failed", "fill_unknown"] + """Kernel's outcome of the extension call. + + fill_submitted means the extension reported submission, not website + authentication. fill_failed means the extension returned a known failure and may + include error_code. fill_unknown means submission may have happened without a + conclusive response; it has no error_code and must not be retried in the same + browser. + """ + + type: Literal["1pw_fill"] + + error_code: Optional[Literal["fillFailed", "autosubmitFailed", "noExistingCredentials", "authenticationFailed"]] = ( + None + ) + """Present only for a conclusive fill_failed response. + + These are allowlisted 1Password extension codes, never raw errors, secrets, or + page content. + """ diff --git a/src/kernel/types/vaults/one_password_oauth_action.py b/src/kernel/types/vaults/one_password_oauth_action.py new file mode 100644 index 00000000..b2e4d377 --- /dev/null +++ b/src/kernel/types/vaults/one_password_oauth_action.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["OnePasswordOAuthAction"] + + +class OnePasswordOAuthAction(BaseModel): + name: Literal["1password_oauth"] + + url: str + """1Password-hosted OAuth authorization URL for the human to open.""" diff --git a/src/kernel/types/vaults/one_password_recover_vault_item_operation_request_param.py b/src/kernel/types/vaults/one_password_recover_vault_item_operation_request_param.py new file mode 100644 index 00000000..5913ab40 --- /dev/null +++ b/src/kernel/types/vaults/one_password_recover_vault_item_operation_request_param.py @@ -0,0 +1,16 @@ +# 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__ = ["OnePasswordRecoverVaultItemOperationRequestParam"] + + +class OnePasswordRecoverVaultItemOperationRequestParam(TypedDict, total=False): + """Kernel encountered a recoverable error while linking this 1Password account. + + Use this action to get a new link to recover the connection. After recovery completes, start a new authorization on the same item. + """ + + type: Required[Literal["1pw_recover"]] diff --git a/src/kernel/types/vaults/one_password_request_access_vault_item_operation_request_param.py b/src/kernel/types/vaults/one_password_request_access_vault_item_operation_request_param.py new file mode 100644 index 00000000..259a31b4 --- /dev/null +++ b/src/kernel/types/vaults/one_password_request_access_vault_item_operation_request_param.py @@ -0,0 +1,26 @@ +# 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 ..._types import SequenceNotStr + +__all__ = ["OnePasswordRequestAccessVaultItemOperationRequestParam"] + + +class OnePasswordRequestAccessVaultItemOperationRequestParam(TypedDict, total=False): + """ + Request access to login entries in the end-user's own, non-shared 1Password vault through the browser extension, auto-loaded into the browser. The end-user approves access in the 1Password app. Shared-vault items and passkeys are not supported. Per-entry reason and keywords overrides are only supported for a single login entry. + """ + + browser_id: Required[str] + """Kernel browser session used to invoke the extension.""" + + type: Required[Literal["1pw_create_access_request"]] + + goal: str + + keywords: SequenceNotStr[str] + + reason: str diff --git a/src/kernel/types/vaults/vault_item.py b/src/kernel/types/vaults/vault_item.py index b9723f4a..7fcdfc5d 100644 --- a/src/kernel/types/vaults/vault_item.py +++ b/src/kernel/types/vaults/vault_item.py @@ -13,6 +13,7 @@ from .credential_vault_item import CredentialVaultItem from .wallet_vault_item_spec import WalletVaultItemSpec from .wallet_vault_item_state import WalletVaultItemState +from .credential_account_vault_item import CredentialAccountVaultItem __all__ = [ "VaultItem", @@ -44,7 +45,17 @@ class WalletVaultItemAvailableOperation(BaseModel): description: str - type: Literal["authorize", "collect", "prepare_checkout", "fill"] + type: Literal[ + "authorize", + "collect", + "prepare_checkout", + "fill", + "1pw_create_access_request", + "1pw_access_request_status", + "1pw_fill", + "1pw_recover", + "1pw_update_access_token", + ] class WalletVaultItemExpanded(BaseModel): @@ -108,7 +119,17 @@ class CardVaultItemAvailableOperation(BaseModel): description: str - type: Literal["authorize", "collect", "prepare_checkout", "fill"] + type: Literal[ + "authorize", + "collect", + "prepare_checkout", + "fill", + "1pw_create_access_request", + "1pw_access_request_status", + "1pw_fill", + "1pw_recover", + "1pw_update_access_token", + ] class CardVaultItem(BaseModel): @@ -142,5 +163,6 @@ class CardVaultItem(BaseModel): VaultItem: TypeAlias = Annotated[ - Union[WalletVaultItem, CardVaultItem, CredentialVaultItem], PropertyInfo(discriminator="type") + Union[WalletVaultItem, CardVaultItem, CredentialAccountVaultItem, CredentialVaultItem], + PropertyInfo(discriminator="type"), ] diff --git a/src/kernel/types/vaults/vault_item_action.py b/src/kernel/types/vaults/vault_item_action.py index 9054447e..e3816895 100644 --- a/src/kernel/types/vaults/vault_item_action.py +++ b/src/kernel/types/vaults/vault_item_action.py @@ -5,6 +5,7 @@ from ..._utils import PropertyInfo from ..._models import BaseModel +from .one_password_oauth_action import OnePasswordOAuthAction __all__ = [ "VaultItemAction", @@ -55,6 +56,7 @@ class CardEnrollmentAction(BaseModel): VaultItemAction: TypeAlias = Annotated[ Union[ LinkOAuthAction, + OnePasswordOAuthAction, SpendApprovalAction, PushApprovalAction, CollectAction, diff --git a/src/kernel/types/vaults/vault_item_operation_response.py b/src/kernel/types/vaults/vault_item_operation_response.py index 33dcd8b3..fd858295 100644 --- a/src/kernel/types/vaults/vault_item_operation_response.py +++ b/src/kernel/types/vaults/vault_item_operation_response.py @@ -12,7 +12,9 @@ from .credential_vault_item import CredentialVaultItem from .wallet_vault_item_spec import WalletVaultItemSpec from .wallet_vault_item_state import WalletVaultItemState +from .credential_account_vault_item import CredentialAccountVaultItem from .fill_vault_item_operation_result import FillVaultItemOperationResult +from .one_password_fill_vault_item_operation_result import OnePasswordFillVaultItemOperationResult __all__ = [ "VaultItemOperationResponse", @@ -44,7 +46,17 @@ class WalletVaultItemAvailableOperation(BaseModel): description: str - type: Literal["authorize", "collect", "prepare_checkout", "fill"] + type: Literal[ + "authorize", + "collect", + "prepare_checkout", + "fill", + "1pw_create_access_request", + "1pw_access_request_status", + "1pw_fill", + "1pw_recover", + "1pw_update_access_token", + ] class WalletVaultItemExpanded(BaseModel): @@ -108,7 +120,17 @@ class CardVaultItemAvailableOperation(BaseModel): description: str - type: Literal["authorize", "collect", "prepare_checkout", "fill"] + type: Literal[ + "authorize", + "collect", + "prepare_checkout", + "fill", + "1pw_create_access_request", + "1pw_access_request_status", + "1pw_fill", + "1pw_recover", + "1pw_update_access_token", + ] class CardVaultItem(BaseModel): @@ -142,5 +164,10 @@ class CardVaultItem(BaseModel): VaultItemOperationResponse: TypeAlias = Union[ - WalletVaultItem, CardVaultItem, CredentialVaultItem, FillVaultItemOperationResult + WalletVaultItem, + CardVaultItem, + CredentialAccountVaultItem, + CredentialVaultItem, + FillVaultItemOperationResult, + OnePasswordFillVaultItemOperationResult, ] diff --git a/src/kernel/types/vaults/wallet_vault_item_spec.py b/src/kernel/types/vaults/wallet_vault_item_spec.py index 2c17933d..a09456a0 100644 --- a/src/kernel/types/vaults/wallet_vault_item_spec.py +++ b/src/kernel/types/vaults/wallet_vault_item_spec.py @@ -26,7 +26,7 @@ class LinkWalletVaultItemSpecAuthorizationClientKernelManagedOAuthClient(BaseMod class LinkWalletVaultItemSpecAuthorizationClientCustomerManagedOAuthClientProviderConfig(BaseModel): """Select a provider config by ID or name. - Responses return the ID. Renaming a config does not change existing wallet bindings; a wallet cannot switch to a different config after creation. + Responses return the ID. Renaming a config does not change existing wallet bindings; an item cannot switch to a different config after creation. """ id: Optional[str] = None @@ -39,7 +39,7 @@ class LinkWalletVaultItemSpecAuthorizationClientCustomerManagedOAuthClient(BaseM """Select a provider config by ID or name. Responses return the ID. Renaming a config does not change existing wallet - bindings; a wallet cannot switch to a different config after creation. + bindings; an item cannot switch to a different config after creation. """ type: Literal["customer_managed"] diff --git a/tests/api_resources/vaults/test_items.py b/tests/api_resources/vaults/test_items.py index 61f350e4..bbe7a151 100644 --- a/tests/api_resources/vaults/test_items.py +++ b/tests/api_resources/vaults/test_items.py @@ -9,6 +9,7 @@ from kernel import Kernel, AsyncKernel from tests.utils import assert_matches_type +from kernel._utils import parse_datetime from kernel.types.vaults import ( VaultItem, ItemListResponse, @@ -876,461 +877,479 @@ 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_upsert_overload_1(self, client: Kernel) -> None: - item = client.vaults.items.upsert( - key="x", + 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", - spec={ - "authorization": { - "client": {"type": "kernel_managed"}, - "method": "oauth", - }, - "provider": "link", - }, - type="wallet", + browser_id="x", + type="1pw_create_access_request", ) - assert_matches_type(VaultItem, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_upsert_with_all_params_overload_1(self, client: Kernel) -> None: - item = client.vaults.items.upsert( - key="x", + 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", - spec={ - "authorization": { - "client": {"type": "kernel_managed"}, - "method": "oauth", - }, - "provider": "link", - }, - type="wallet", + browser_id="x", + type="1pw_create_access_request", + goal="goal", + keywords=["x"], + reason="reason", ) - assert_matches_type(VaultItem, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_upsert_overload_1(self, client: Kernel) -> None: - response = client.vaults.items.with_raw_response.upsert( - key="x", + 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", - spec={ - "authorization": { - "client": {"type": "kernel_managed"}, - "method": "oauth", - }, - "provider": "link", - }, - type="wallet", + browser_id="x", + type="1pw_create_access_request", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = response.parse() - assert_matches_type(VaultItem, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_upsert_overload_1(self, client: Kernel) -> None: - with client.vaults.items.with_streaming_response.upsert( - key="x", + 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", - spec={ - "authorization": { - "client": {"type": "kernel_managed"}, - "method": "oauth", - }, - "provider": "link", - }, - type="wallet", + browser_id="x", + type="1pw_create_access_request", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = response.parse() - assert_matches_type(VaultItem, item, path=["response"]) + 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_upsert_overload_1(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.upsert( - key="x", + client.vaults.items.with_raw_response.perform_operation( + key="key", id_or_name="", - spec={ - "authorization": { - "client": {"type": "kernel_managed"}, - "method": "oauth", - }, - "provider": "link", - }, - type="wallet", + browser_id="x", + type="1pw_create_access_request", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): - client.vaults.items.with_raw_response.upsert( + client.vaults.items.with_raw_response.perform_operation( key="", id_or_name="id_or_name", - spec={ - "authorization": { - "client": {"type": "kernel_managed"}, - "method": "oauth", - }, - "provider": "link", - }, - type="wallet", + browser_id="x", + type="1pw_create_access_request", ) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_upsert_overload_2(self, client: Kernel) -> None: - item = client.vaults.items.upsert( - key="x", + 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", - spec={ - "amount": 1, - "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "currency": "bFx", - "merchant_name": "x", - "merchant_url": "https://example.com", - "payment_method_id": "x", - "provider": "link", - "wallet": "wallet", - }, - type="card", + browser_id="x", + type="1pw_access_request_status", ) - assert_matches_type(VaultItem, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_upsert_with_all_params_overload_2(self, client: Kernel) -> None: - item = client.vaults.items.upsert( - key="x", + 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", - spec={ - "amount": 1, - "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "currency": "bFx", - "merchant_name": "x", - "merchant_url": "https://example.com", - "payment_method_id": "x", - "provider": "link", - "wallet": "wallet", - "expires_at": 0, - "line_items": [ - { - "name": "name", - "description": "description", - "image_url": "image_url", - "product_url": "product_url", - "quantity": 1, - "sku": "sku", - "totals": [ - { - "amount": 0, - "display_text": "display_text", - "type": "type", - } - ], - "unit_amount": 0, - "url": "url", - } - ], - "metadata": {"foo": "string"}, - "totals": [ - { - "amount": 0, - "display_text": "display_text", - "type": "type", - } - ], - }, - type="card", + browser_id="x", + type="1pw_access_request_status", + timeout_seconds=0, ) - assert_matches_type(VaultItem, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_upsert_overload_2(self, client: Kernel) -> None: - response = client.vaults.items.with_raw_response.upsert( - key="x", + 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", - spec={ - "amount": 1, - "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "currency": "bFx", - "merchant_name": "x", - "merchant_url": "https://example.com", - "payment_method_id": "x", - "provider": "link", - "wallet": "wallet", - }, - type="card", + browser_id="x", + type="1pw_access_request_status", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = response.parse() - assert_matches_type(VaultItem, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_upsert_overload_2(self, client: Kernel) -> None: - with client.vaults.items.with_streaming_response.upsert( - key="x", + 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", - spec={ - "amount": 1, - "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "currency": "bFx", - "merchant_name": "x", - "merchant_url": "https://example.com", - "payment_method_id": "x", - "provider": "link", - "wallet": "wallet", - }, - type="card", + browser_id="x", + type="1pw_access_request_status", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = response.parse() - assert_matches_type(VaultItem, item, path=["response"]) + 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_upsert_overload_2(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.upsert( - key="x", + client.vaults.items.with_raw_response.perform_operation( + key="key", id_or_name="", - spec={ - "amount": 1, - "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "currency": "bFx", - "merchant_name": "x", - "merchant_url": "https://example.com", - "payment_method_id": "x", - "provider": "link", - "wallet": "wallet", - }, - type="card", + browser_id="x", + type="1pw_access_request_status", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): - client.vaults.items.with_raw_response.upsert( + client.vaults.items.with_raw_response.perform_operation( key="", id_or_name="id_or_name", - spec={ - "amount": 1, - "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "currency": "bFx", - "merchant_name": "x", - "merchant_url": "https://example.com", - "payment_method_id": "x", - "provider": "link", - "wallet": "wallet", - }, - type="card", + browser_id="x", + type="1pw_access_request_status", ) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_upsert_overload_3(self, client: Kernel) -> None: - item = client.vaults.items.upsert( - key="x", + 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", - spec={ - "fields": [ - { - "name": "name", - "type": "text", - } - ] - }, - type="credential", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", ) - assert_matches_type(VaultItem, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_upsert_with_all_params_overload_3(self, client: Kernel) -> None: - item = client.vaults.items.upsert( - key="x", + 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", - spec={ - "fields": [ - { - "name": "name", - "type": "text", - "label": "label", - "required": True, - "sensitive": True, - "value": "x", - } - ], - "description": "description", - }, - type="credential", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", + entry_id="x", + timeout_ms=1, ) - assert_matches_type(VaultItem, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_upsert_overload_3(self, client: Kernel) -> None: - response = client.vaults.items.with_raw_response.upsert( - key="x", + 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", - spec={ - "fields": [ - { - "name": "name", - "type": "text", - } - ] - }, - type="credential", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = response.parse() - assert_matches_type(VaultItem, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_upsert_overload_3(self, client: Kernel) -> None: - with client.vaults.items.with_streaming_response.upsert( - key="x", + 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", - spec={ - "fields": [ - { - "name": "name", - "type": "text", - } - ] - }, - type="credential", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = response.parse() - assert_matches_type(VaultItem, item, path=["response"]) + 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_upsert_overload_3(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.upsert( - key="x", + client.vaults.items.with_raw_response.perform_operation( + key="key", id_or_name="", - spec={ - "fields": [ - { - "name": "name", - "type": "text", - } - ] - }, - type="credential", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): - client.vaults.items.with_raw_response.upsert( + client.vaults.items.with_raw_response.perform_operation( key="", id_or_name="id_or_name", - spec={ - "fields": [ - { - "name": "name", - "type": "text", - } - ] - }, - type="credential", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", ) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + 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", + type="1pw_recover", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + 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", + type="1pw_recover", + ) -class TestAsyncItems: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) + 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 - async def test_method_retrieve(self, async_client: AsyncKernel) -> None: - item = await async_client.vaults.items.retrieve( + 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", + type="1pw_recover", + ) 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_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", + id_or_name="", + type="1pw_recover", + ) + + 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="1pw_recover", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + 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", + access_token="x", + type="1pw_update_access_token", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + 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", + access_token="x", + type="1pw_update_access_token", + access_token_expires_at=parse_datetime("2019-12-27T18:11:19.117Z"), + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + 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", + access_token="x", + type="1pw_update_access_token", + ) + + 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_9(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.perform_operation( + key="key", + id_or_name="id_or_name", + access_token="x", + type="1pw_update_access_token", + ) 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_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", + id_or_name="", + access_token="x", + type="1pw_update_access_token", + ) + + 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", + access_token="x", + type="1pw_update_access_token", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_upsert_overload_1(self, client: Kernel) -> None: + item = client.vaults.items.upsert( key="x", id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "link", + }, + type="wallet", ) assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_retrieve_with_all_params(self, async_client: AsyncKernel) -> None: - item = await async_client.vaults.items.retrieve( + def test_method_upsert_with_all_params_overload_1(self, client: Kernel) -> None: + item = client.vaults.items.upsert( key="x", id_or_name="id_or_name", - expand=["payment_methods"], - wait=0, + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "link", + }, + type="wallet", ) assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_retrieve(self, async_client: AsyncKernel) -> None: - response = await async_client.vaults.items.with_raw_response.retrieve( + def test_raw_response_upsert_overload_1(self, client: Kernel) -> None: + response = client.vaults.items.with_raw_response.upsert( key="x", id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "link", + }, + type="wallet", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" - item = await response.parse() + item = response.parse() assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_retrieve(self, async_client: AsyncKernel) -> None: - async with async_client.vaults.items.with_streaming_response.retrieve( + def test_streaming_response_upsert_overload_1(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.upsert( key="x", id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "link", + }, + type="wallet", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" - item = await response.parse() + item = response.parse() assert_matches_type(VaultItem, 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_retrieve(self, async_client: AsyncKernel) -> None: + def test_path_params_upsert_overload_1(self, client: Kernel) -> 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.retrieve( + client.vaults.items.with_raw_response.upsert( key="x", id_or_name="", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "link", + }, + type="wallet", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): - await async_client.vaults.items.with_raw_response.retrieve( + client.vaults.items.with_raw_response.upsert( key="", id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "link", + }, + type="wallet", ) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_update_overload_1(self, async_client: AsyncKernel) -> None: - item = await async_client.vaults.items.update( + def test_method_upsert_overload_2(self, client: Kernel) -> None: + item = client.vaults.items.upsert( key="x", id_or_name="id_or_name", spec={ @@ -1343,13 +1362,14 @@ async def test_method_update_overload_1(self, async_client: AsyncKernel) -> None "provider": "link", "wallet": "wallet", }, + type="card", ) assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_update_with_all_params_overload_1(self, async_client: AsyncKernel) -> None: - item = await async_client.vaults.items.update( + def test_method_upsert_with_all_params_overload_2(self, client: Kernel) -> None: + item = client.vaults.items.upsert( key="x", id_or_name="id_or_name", spec={ @@ -1396,8 +1416,8 @@ async def test_method_update_with_all_params_overload_1(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_update_overload_1(self, async_client: AsyncKernel) -> None: - response = await async_client.vaults.items.with_raw_response.update( + def test_raw_response_upsert_overload_2(self, client: Kernel) -> None: + response = client.vaults.items.with_raw_response.upsert( key="x", id_or_name="id_or_name", spec={ @@ -1410,17 +1430,18 @@ async def test_raw_response_update_overload_1(self, async_client: AsyncKernel) - "provider": "link", "wallet": "wallet", }, + type="card", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" - item = await response.parse() + item = response.parse() assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_update_overload_1(self, async_client: AsyncKernel) -> None: - async with async_client.vaults.items.with_streaming_response.update( + def test_streaming_response_upsert_overload_2(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.upsert( key="x", id_or_name="id_or_name", spec={ @@ -1433,20 +1454,21 @@ async def test_streaming_response_update_overload_1(self, async_client: AsyncKer "provider": "link", "wallet": "wallet", }, + type="card", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" - item = await response.parse() + item = response.parse() assert_matches_type(VaultItem, 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_update_overload_1(self, async_client: AsyncKernel) -> None: + def test_path_params_upsert_overload_2(self, client: Kernel) -> 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.update( + client.vaults.items.with_raw_response.upsert( key="x", id_or_name="", spec={ @@ -1459,10 +1481,11 @@ async def test_path_params_update_overload_1(self, async_client: AsyncKernel) -> "provider": "link", "wallet": "wallet", }, + type="card", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): - await async_client.vaults.items.with_raw_response.update( + client.vaults.items.with_raw_response.upsert( key="", id_or_name="id_or_name", spec={ @@ -1475,265 +1498,1192 @@ async def test_path_params_update_overload_1(self, async_client: AsyncKernel) -> "provider": "link", "wallet": "wallet", }, + type="card", ) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_update_overload_2(self, async_client: AsyncKernel) -> None: - item = await async_client.vaults.items.update( + def test_method_upsert_overload_3(self, client: Kernel) -> None: + item = client.vaults.items.upsert( key="x", id_or_name="id_or_name", - spec={}, + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_upsert_overload_3(self, client: Kernel) -> None: + response = client.vaults.items.with_raw_response.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_upsert_overload_3(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = response.parse() + assert_matches_type(VaultItem, 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_upsert_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.upsert( + key="x", + id_or_name="", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + client.vaults.items.with_raw_response.upsert( + key="", + id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_upsert_overload_4(self, client: Kernel) -> None: + item = client.vaults.items.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "fields": [ + { + "name": "name", + "type": "text", + } + ], + "provider": "kernel", + }, type="credential", - version=1, ) assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_update_with_all_params_overload_2(self, async_client: AsyncKernel) -> None: - item = await async_client.vaults.items.update( + def test_method_upsert_with_all_params_overload_4(self, client: Kernel) -> None: + item = client.vaults.items.upsert( key="x", id_or_name="id_or_name", spec={ + "fields": [ + { + "name": "name", + "type": "text", + "label": "label", + "required": True, + "sensitive": True, + "value": "x", + } + ], + "provider": "kernel", "description": "description", - "fields": {"foo": {"value": "value"}}, }, type="credential", - version=1, - expected_item_id="x", ) assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_update_overload_2(self, async_client: AsyncKernel) -> None: - response = await async_client.vaults.items.with_raw_response.update( + def test_raw_response_upsert_overload_4(self, client: Kernel) -> None: + response = client.vaults.items.with_raw_response.upsert( key="x", id_or_name="id_or_name", - spec={}, + spec={ + "fields": [ + { + "name": "name", + "type": "text", + } + ], + "provider": "kernel", + }, type="credential", - version=1, ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" - item = await response.parse() + item = response.parse() assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_update_overload_2(self, async_client: AsyncKernel) -> None: - async with async_client.vaults.items.with_streaming_response.update( + def test_streaming_response_upsert_overload_4(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.upsert( key="x", id_or_name="id_or_name", - spec={}, + spec={ + "fields": [ + { + "name": "name", + "type": "text", + } + ], + "provider": "kernel", + }, type="credential", - version=1, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" - item = await response.parse() + item = response.parse() assert_matches_type(VaultItem, 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_update_overload_2(self, async_client: AsyncKernel) -> None: + def test_path_params_upsert_overload_4(self, client: Kernel) -> 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.update( + client.vaults.items.with_raw_response.upsert( key="x", id_or_name="", - spec={}, + spec={ + "fields": [ + { + "name": "name", + "type": "text", + } + ], + "provider": "kernel", + }, type="credential", - version=1, ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): - await async_client.vaults.items.with_raw_response.update( + client.vaults.items.with_raw_response.upsert( key="", id_or_name="id_or_name", - spec={}, + spec={ + "fields": [ + { + "name": "name", + "type": "text", + } + ], + "provider": "kernel", + }, type="credential", - version=1, ) + +class TestAsyncItems: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_list(self, async_client: AsyncKernel) -> None: - item = await async_client.vaults.items.list( - "id_or_name", + async def test_method_retrieve(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.retrieve( + key="x", + id_or_name="id_or_name", ) - assert_matches_type(ItemListResponse, item, path=["response"]) + assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_list(self, async_client: AsyncKernel) -> None: - response = await async_client.vaults.items.with_raw_response.list( - "id_or_name", + async def test_method_retrieve_with_all_params(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.retrieve( + key="x", + id_or_name="id_or_name", + expand=["payment_methods"], + wait=0, + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.retrieve( + key="x", + id_or_name="id_or_name", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = await response.parse() - assert_matches_type(ItemListResponse, item, path=["response"]) + assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_list(self, async_client: AsyncKernel) -> None: - async with async_client.vaults.items.with_streaming_response.list( - "id_or_name", + async def test_streaming_response_retrieve(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.retrieve( + key="x", + id_or_name="id_or_name", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = await response.parse() - assert_matches_type(ItemListResponse, item, path=["response"]) + assert_matches_type(VaultItem, 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_list(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.list( - "", - ) + async def test_path_params_retrieve(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.retrieve( + key="x", + id_or_name="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.retrieve( + key="", + id_or_name="id_or_name", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_overload_1(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_with_all_params_overload_1(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + "expires_at": 0, + "line_items": [ + { + "name": "name", + "description": "description", + "image_url": "image_url", + "product_url": "product_url", + "quantity": 1, + "sku": "sku", + "totals": [ + { + "amount": 0, + "display_text": "display_text", + "type": "type", + } + ], + "unit_amount": 0, + "url": "url", + } + ], + "metadata": {"foo": "string"}, + "totals": [ + { + "amount": 0, + "display_text": "display_text", + "type": "type", + } + ], + }, + type="card", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update_overload_1(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update_overload_1(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(VaultItem, 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_update_overload_1(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.update( + key="x", + id_or_name="", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.update( + key="", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_overload_2(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.update( + key="x", + id_or_name="id_or_name", + spec={}, + type="credential", + version=1, + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_with_all_params_overload_2(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.update( + key="x", + id_or_name="id_or_name", + spec={ + "description": "description", + "fields": {"foo": {"value": "value"}}, + }, + type="credential", + version=1, + expected_item_id="x", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update_overload_2(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.update( + key="x", + id_or_name="id_or_name", + spec={}, + type="credential", + version=1, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update_overload_2(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.update( + key="x", + id_or_name="id_or_name", + spec={}, + type="credential", + version=1, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(VaultItem, 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_update_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.update( + key="x", + id_or_name="", + spec={}, + type="credential", + version=1, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.update( + key="", + id_or_name="id_or_name", + spec={}, + type="credential", + version=1, + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.list( + "id_or_name", + ) + assert_matches_type(ItemListResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.list( + "id_or_name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(ItemListResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.list( + "id_or_name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(ItemListResponse, 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_list(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.list( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.delete( + key="x", + id_or_name="id_or_name", + ) + assert item is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.delete( + key="x", + id_or_name="id_or_name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert item is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.delete( + key="x", + id_or_name="id_or_name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert item is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(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.delete( + key="x", + id_or_name="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.delete( + key="", + id_or_name="id_or_name", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_events(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.events( + key="key", + id_or_name="id_or_name", + ) + assert_matches_type(ItemEventsResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_events_with_all_params(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.events( + key="key", + id_or_name="id_or_name", + after="after", + wait=0, + ) + assert_matches_type(ItemEventsResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_events(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.events( + key="key", + id_or_name="id_or_name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(ItemEventsResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_events(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.events( + key="key", + id_or_name="id_or_name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(ItemEventsResponse, 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_events(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.events( + key="key", + id_or_name="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.events( + key="", + id_or_name="id_or_name", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_perform_operation_overload_1(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.perform_operation( + key="key", + id_or_name="id_or_name", + type="authorize", + ) + 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_1(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="authorize", + ) + + 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_1(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="authorize", + ) 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_1(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="authorize", + ) + + 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="authorize", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_perform_operation_overload_2(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_2(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_2(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_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="collect", + ) + + 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="collect", + ) + + @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", + checkout={ + "browser_id": "browser_id", + "environment": "production", + "merchant_origin": "merchant_origin", + }, + type="prepare_checkout", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @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: + item = await async_client.vaults.items.perform_operation( + key="key", + id_or_name="id_or_name", + checkout={ + "browser_id": "browser_id", + "environment": "production", + "merchant_origin": "merchant_origin", + "psp": "square", + }, + type="prepare_checkout", + ) + 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", + checkout={ + "browser_id": "browser_id", + "environment": "production", + "merchant_origin": "merchant_origin", + }, + type="prepare_checkout", + ) + + 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", + checkout={ + "browser_id": "browser_id", + "environment": "production", + "merchant_origin": "merchant_origin", + }, + type="prepare_checkout", + ) 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="", + checkout={ + "browser_id": "browser_id", + "environment": "production", + "merchant_origin": "merchant_origin", + }, + type="prepare_checkout", + ) + + 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", + checkout={ + "browser_id": "browser_id", + "environment": "production", + "merchant_origin": "merchant_origin", + }, + type="prepare_checkout", + ) + + @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", + browser_id="browser-session-id", + fields=[ + { + "field": "number", + "selector": "#card-number", + }, + { + "field": "exp_month", + "selector": "#expiry-month", + }, + { + "field": "exp_year", + "selector": "#expiry-year", + }, + { + "field": "cvc", + "selector": "#security-code", + }, + ], + type="fill", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_delete(self, async_client: AsyncKernel) -> None: - item = await async_client.vaults.items.delete( - key="x", + async def test_method_perform_operation_with_all_params_overload_4(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.perform_operation( + key="key", id_or_name="id_or_name", + browser_id="browser-session-id", + fields=[ + { + "field": "number", + "selector": "#card-number", + "format": "MM/YY", + }, + { + "field": "exp_month", + "selector": "#expiry-month", + "format": "MM/YY", + }, + { + "field": "exp_year", + "selector": "#expiry-year", + "format": "MM/YY", + }, + { + "field": "cvc", + "selector": "#security-code", + "format": "MM/YY", + }, + ], + type="fill", + page_url="https://shop.example/checkout", + timeout_ms=1, ) - assert item is None + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_delete(self, async_client: AsyncKernel) -> None: - response = await async_client.vaults.items.with_raw_response.delete( - key="x", + 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", + browser_id="browser-session-id", + fields=[ + { + "field": "number", + "selector": "#card-number", + }, + { + "field": "exp_month", + "selector": "#expiry-month", + }, + { + "field": "exp_year", + "selector": "#expiry-year", + }, + { + "field": "cvc", + "selector": "#security-code", + }, + ], + type="fill", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = await response.parse() - assert item is None + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_delete(self, async_client: AsyncKernel) -> None: - async with async_client.vaults.items.with_streaming_response.delete( - key="x", + 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", + browser_id="browser-session-id", + fields=[ + { + "field": "number", + "selector": "#card-number", + }, + { + "field": "exp_month", + "selector": "#expiry-month", + }, + { + "field": "exp_year", + "selector": "#expiry-year", + }, + { + "field": "cvc", + "selector": "#security-code", + }, + ], + type="fill", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = await response.parse() - assert item is None + 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_delete(self, async_client: AsyncKernel) -> None: + 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.delete( - key="x", + await async_client.vaults.items.with_raw_response.perform_operation( + key="key", id_or_name="", + browser_id="browser-session-id", + fields=[ + { + "field": "number", + "selector": "#card-number", + }, + { + "field": "exp_month", + "selector": "#expiry-month", + }, + { + "field": "exp_year", + "selector": "#expiry-year", + }, + { + "field": "cvc", + "selector": "#security-code", + }, + ], + type="fill", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): - await async_client.vaults.items.with_raw_response.delete( + await async_client.vaults.items.with_raw_response.perform_operation( key="", id_or_name="id_or_name", + browser_id="browser-session-id", + fields=[ + { + "field": "number", + "selector": "#card-number", + }, + { + "field": "exp_month", + "selector": "#expiry-month", + }, + { + "field": "exp_year", + "selector": "#expiry-year", + }, + { + "field": "cvc", + "selector": "#security-code", + }, + ], + type="fill", ) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_events(self, async_client: AsyncKernel) -> None: - item = await async_client.vaults.items.events( + 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", + browser_id="x", + type="1pw_create_access_request", ) - assert_matches_type(ItemEventsResponse, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_events_with_all_params(self, async_client: AsyncKernel) -> None: - item = await async_client.vaults.items.events( + 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", - after="after", - wait=0, + browser_id="x", + type="1pw_create_access_request", + goal="goal", + keywords=["x"], + reason="reason", ) - assert_matches_type(ItemEventsResponse, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_events(self, async_client: AsyncKernel) -> None: - response = await async_client.vaults.items.with_raw_response.events( + 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", + browser_id="x", + type="1pw_create_access_request", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = await response.parse() - assert_matches_type(ItemEventsResponse, item, path=["response"]) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_events(self, async_client: AsyncKernel) -> None: - async with async_client.vaults.items.with_streaming_response.events( + 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", + browser_id="x", + type="1pw_create_access_request", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" item = await response.parse() - assert_matches_type(ItemEventsResponse, item, path=["response"]) + 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_events(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.events( + await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="", + browser_id="x", + type="1pw_create_access_request", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): - await async_client.vaults.items.with_raw_response.events( + await async_client.vaults.items.with_raw_response.perform_operation( key="", id_or_name="id_or_name", + browser_id="x", + type="1pw_create_access_request", ) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_overload_1(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", - type="authorize", + browser_id="x", + type="1pw_access_request_status", ) 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_1(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", + browser_id="x", + type="1pw_access_request_status", + timeout_seconds=0, + ) + 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_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", - type="authorize", + browser_id="x", + type="1pw_access_request_status", ) assert response.is_closed is True @@ -1743,11 +2693,12 @@ async def test_raw_response_perform_operation_overload_1(self, async_client: Asy @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_1(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", - type="authorize", + browser_id="x", + type="1pw_access_request_status", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1759,38 +2710,58 @@ async def test_streaming_response_perform_operation_overload_1(self, async_clien @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_perform_operation_overload_1(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", id_or_name="", - type="authorize", + browser_id="x", + type="1pw_access_request_status", ) 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="authorize", + browser_id="x", + type="1pw_access_request_status", ) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_perform_operation_overload_2(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", - type="collect", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", ) 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_2(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", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", + entry_id="x", + timeout_ms=1, + ) + 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_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", - type="collect", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", ) assert response.is_closed is True @@ -1800,11 +2771,13 @@ async def test_raw_response_perform_operation_overload_2(self, async_client: Asy @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_2(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", - type="collect", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1816,64 +2789,42 @@ 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: + 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", id_or_name="", - type="collect", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", ) 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="collect", - ) - - @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", - checkout={ - "browser_id": "browser_id", - "environment": "production", - "merchant_origin": "merchant_origin", - }, - type="prepare_checkout", - ) - assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + key="", + id_or_name="id_or_name", + browser_id="x", + page_url="https://example.com", + type="1pw_fill", + ) @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_overload_8(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", - checkout={ - "browser_id": "browser_id", - "environment": "production", - "merchant_origin": "merchant_origin", - "psp": "square", - }, - type="prepare_checkout", + type="1pw_recover", ) 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: + 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", - checkout={ - "browser_id": "browser_id", - "environment": "production", - "merchant_origin": "merchant_origin", - }, - type="prepare_checkout", + type="1pw_recover", ) assert response.is_closed is True @@ -1883,16 +2834,11 @@ 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_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", - checkout={ - "browser_id": "browser_id", - "environment": "production", - "merchant_origin": "merchant_origin", - }, - type="prepare_checkout", + type="1pw_recover", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1904,121 +2850,52 @@ 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_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", id_or_name="", - checkout={ - "browser_id": "browser_id", - "environment": "production", - "merchant_origin": "merchant_origin", - }, - type="prepare_checkout", + type="1pw_recover", ) 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", - checkout={ - "browser_id": "browser_id", - "environment": "production", - "merchant_origin": "merchant_origin", - }, - type="prepare_checkout", + type="1pw_recover", ) @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_9(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", - browser_id="browser-session-id", - fields=[ - { - "field": "number", - "selector": "#card-number", - }, - { - "field": "exp_month", - "selector": "#expiry-month", - }, - { - "field": "exp_year", - "selector": "#expiry-year", - }, - { - "field": "cvc", - "selector": "#security-code", - }, - ], - type="fill", + access_token="x", + type="1pw_update_access_token", ) assert_matches_type(VaultItemOperationResponse, item, path=["response"]) @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_9(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.perform_operation( key="key", id_or_name="id_or_name", - browser_id="browser-session-id", - fields=[ - { - "field": "number", - "selector": "#card-number", - "format": "MM/YY", - }, - { - "field": "exp_month", - "selector": "#expiry-month", - "format": "MM/YY", - }, - { - "field": "exp_year", - "selector": "#expiry-year", - "format": "MM/YY", - }, - { - "field": "cvc", - "selector": "#security-code", - "format": "MM/YY", - }, - ], - type="fill", - page_url="https://shop.example/checkout", - timeout_ms=1, + access_token="x", + type="1pw_update_access_token", + access_token_expires_at=parse_datetime("2019-12-27T18:11:19.117Z"), ) 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: + 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", - browser_id="browser-session-id", - fields=[ - { - "field": "number", - "selector": "#card-number", - }, - { - "field": "exp_month", - "selector": "#expiry-month", - }, - { - "field": "exp_year", - "selector": "#expiry-year", - }, - { - "field": "cvc", - "selector": "#security-code", - }, - ], - type="fill", + access_token="x", + type="1pw_update_access_token", ) assert response.is_closed is True @@ -2028,30 +2905,12 @@ 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_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", - browser_id="browser-session-id", - fields=[ - { - "field": "number", - "selector": "#card-number", - }, - { - "field": "exp_month", - "selector": "#expiry-month", - }, - { - "field": "exp_year", - "selector": "#expiry-year", - }, - { - "field": "cvc", - "selector": "#security-code", - }, - ], - type="fill", + access_token="x", + type="1pw_update_access_token", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -2063,57 +2922,21 @@ 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_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", id_or_name="", - browser_id="browser-session-id", - fields=[ - { - "field": "number", - "selector": "#card-number", - }, - { - "field": "exp_month", - "selector": "#expiry-month", - }, - { - "field": "exp_year", - "selector": "#expiry-year", - }, - { - "field": "cvc", - "selector": "#security-code", - }, - ], - type="fill", + access_token="x", + type="1pw_update_access_token", ) 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", - browser_id="browser-session-id", - fields=[ - { - "field": "number", - "selector": "#card-number", - }, - { - "field": "exp_month", - "selector": "#expiry-month", - }, - { - "field": "exp_year", - "selector": "#expiry-year", - }, - { - "field": "cvc", - "selector": "#security-code", - }, - ], - type="fill", + access_token="x", + type="1pw_update_access_token", ) @pytest.mark.skip(reason="Mock server tests are disabled") @@ -2383,6 +3206,98 @@ async def test_path_params_upsert_overload_2(self, async_client: AsyncKernel) -> @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_upsert_overload_3(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_upsert_overload_3(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_upsert_overload_3(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(VaultItem, 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_upsert_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.upsert( + key="x", + id_or_name="", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.upsert( + key="", + id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_upsert_overload_4(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.upsert( key="x", id_or_name="id_or_name", @@ -2392,7 +3307,8 @@ async def test_method_upsert_overload_3(self, async_client: AsyncKernel) -> None "name": "name", "type": "text", } - ] + ], + "provider": "kernel", }, type="credential", ) @@ -2400,7 +3316,7 @@ async def test_method_upsert_overload_3(self, async_client: AsyncKernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_upsert_with_all_params_overload_3(self, async_client: AsyncKernel) -> None: + async def test_method_upsert_with_all_params_overload_4(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.upsert( key="x", id_or_name="id_or_name", @@ -2415,6 +3331,7 @@ async def test_method_upsert_with_all_params_overload_3(self, async_client: Asyn "value": "x", } ], + "provider": "kernel", "description": "description", }, type="credential", @@ -2423,7 +3340,7 @@ async def test_method_upsert_with_all_params_overload_3(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_upsert_overload_3(self, async_client: AsyncKernel) -> None: + async def test_raw_response_upsert_overload_4(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.upsert( key="x", id_or_name="id_or_name", @@ -2433,7 +3350,8 @@ async def test_raw_response_upsert_overload_3(self, async_client: AsyncKernel) - "name": "name", "type": "text", } - ] + ], + "provider": "kernel", }, type="credential", ) @@ -2445,7 +3363,7 @@ async def test_raw_response_upsert_overload_3(self, async_client: AsyncKernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_upsert_overload_3(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_upsert_overload_4(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.upsert( key="x", id_or_name="id_or_name", @@ -2455,7 +3373,8 @@ async def test_streaming_response_upsert_overload_3(self, async_client: AsyncKer "name": "name", "type": "text", } - ] + ], + "provider": "kernel", }, type="credential", ) as response: @@ -2469,7 +3388,7 @@ async def test_streaming_response_upsert_overload_3(self, async_client: AsyncKer @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_upsert_overload_3(self, async_client: AsyncKernel) -> None: + async def test_path_params_upsert_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.upsert( key="x", @@ -2480,7 +3399,8 @@ async def test_path_params_upsert_overload_3(self, async_client: AsyncKernel) -> "name": "name", "type": "text", } - ] + ], + "provider": "kernel", }, type="credential", ) @@ -2495,7 +3415,8 @@ async def test_path_params_upsert_overload_3(self, async_client: AsyncKernel) -> "name": "name", "type": "text", } - ] + ], + "provider": "kernel", }, type="credential", ) From 5c1bed353eb421bff589bcc86b2940ca750e3999 Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 13:29:13 +0000 Subject: [PATCH 5/7] feat: chore(stlc): seal custom-code tracking files Stainless-Generated-From: 8ac1635568224ca17c04e5c6f15ac6e66e31b932 --- src/kernel/types/vault_provider_config.py | 8 +++- .../vault_provider_config_create_params.py | 8 ++++ .../vault_provider_config_update_params.py | 6 +++ .../test_vault_provider_configs.py | 38 ++++++++++++++++++- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/kernel/types/vault_provider_config.py b/src/kernel/types/vault_provider_config.py index 7ab9a049..03b0a427 100644 --- a/src/kernel/types/vault_provider_config.py +++ b/src/kernel/types/vault_provider_config.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Union +from typing import Union, Optional from datetime import datetime from typing_extensions import Literal, Annotated, TypeAlias @@ -30,6 +30,12 @@ class VaultLinkProviderConfig(BaseModel): updated_at: datetime + publishable_key: Optional[str] = None + """Stripe publishable key sent to Link when refreshing and revoking wallet grants. + + Omitted when not configured. + """ + class VaultAgentCardProviderConfig(BaseModel): """Response schema for an AgentCard configuration, without secret credentials. diff --git a/src/kernel/types/vault_provider_config_create_params.py b/src/kernel/types/vault_provider_config_create_params.py index 185f06a6..bbef1ed7 100644 --- a/src/kernel/types/vault_provider_config_create_params.py +++ b/src/kernel/types/vault_provider_config_create_params.py @@ -28,6 +28,14 @@ class VaultLinkProviderConfigRequestCredentials(TypedDict, total=False): client_secret: Required[str] + publishable_key: str + """Stripe publishable key for the account that owns the Link OAuth client. + + Link requires it as the bearer credential when Kernel refreshes or revokes + imported wallet grants; without it, those wallets stop working when the imported + access token expires. + """ + class VaultAgentCardProviderConfigRequest(TypedDict, total=False): credentials: Required[VaultAgentCardProviderConfigRequestCredentials] diff --git a/src/kernel/types/vault_provider_config_update_params.py b/src/kernel/types/vault_provider_config_update_params.py index 49d1be8a..b4c18d20 100644 --- a/src/kernel/types/vault_provider_config_update_params.py +++ b/src/kernel/types/vault_provider_config_update_params.py @@ -26,3 +26,9 @@ class Credentials(TypedDict, total=False): """ client_secret: str + + publishable_key: str + """Link configurations only. + + Stripe publishable key sent to Link when refreshing and revoking wallet grants. + """ diff --git a/tests/api_resources/test_vault_provider_configs.py b/tests/api_resources/test_vault_provider_configs.py index 7ab21cd5..7fe512e3 100644 --- a/tests/api_resources/test_vault_provider_configs.py +++ b/tests/api_resources/test_vault_provider_configs.py @@ -33,6 +33,20 @@ def test_method_create_overload_1(self, client: Kernel) -> None: ) assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"]) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params_overload_1(self, client: Kernel) -> None: + vault_provider_config = client.vault_provider_configs.create( + credentials={ + "client_id": "x", + "client_secret": "x", + "publishable_key": "pk_test_lK9w2kI5J1", + }, + name="name", + provider="link", + ) + assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"]) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_raw_response_create_overload_1(self, client: Kernel) -> None: @@ -173,7 +187,10 @@ def test_method_update(self, client: Kernel) -> None: def test_method_update_with_all_params(self, client: Kernel) -> None: vault_provider_config = client.vault_provider_configs.update( id_or_name="id_or_name", - credentials={"client_secret": "x"}, + credentials={ + "client_secret": "x", + "publishable_key": "pk_test_lK9w2kI5J1", + }, name="renamed-link-client", ) assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"]) @@ -310,6 +327,20 @@ async def test_method_create_overload_1(self, async_client: AsyncKernel) -> None ) assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"]) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_with_all_params_overload_1(self, async_client: AsyncKernel) -> None: + vault_provider_config = await async_client.vault_provider_configs.create( + credentials={ + "client_id": "x", + "client_secret": "x", + "publishable_key": "pk_test_lK9w2kI5J1", + }, + name="name", + provider="link", + ) + assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"]) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_raw_response_create_overload_1(self, async_client: AsyncKernel) -> None: @@ -450,7 +481,10 @@ async def test_method_update(self, async_client: AsyncKernel) -> None: async def test_method_update_with_all_params(self, async_client: AsyncKernel) -> None: vault_provider_config = await async_client.vault_provider_configs.update( id_or_name="id_or_name", - credentials={"client_secret": "x"}, + credentials={ + "client_secret": "x", + "publishable_key": "pk_test_lK9w2kI5J1", + }, name="renamed-link-client", ) assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"]) From f6e1c01ac7e1cd1a06142292a59228603b78379c Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 13:34:38 +0000 Subject: [PATCH 6/7] release: 0.114.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 11 +++++++++++ pyproject.toml | 2 +- src/kernel/_version.py | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 939bb175..d61779f3 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.113.0" + ".": "0.114.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 347647b8..c1ad420f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## [0.114.0](https://github.com/kernel/kernel-python-sdk/compare/v0.113.0...v0.114.0) (2026-09-30) + + +### Features + +* Accept telemetry.storage and settle it at browser create ([28fb2d3](https://github.com/kernel/kernel-python-sdk/commit/28fb2d3c8fd83090d83404a0b407557585bf93f6)) +* Allow export-only network and console telemetry for BAA orgs ([2ff8d4a](https://github.com/kernel/kernel-python-sdk/commit/2ff8d4acacb1b8152b9c7d1b38067c1b02167f40)) +* chore(stlc): seal custom-code tracking files ([5c1bed3](https://github.com/kernel/kernel-python-sdk/commit/5c1bed353eb421bff589bcc86b2940ca750e3999)) +* Expose missing managed auth check URL as verification unavailable ([74dbad8](https://github.com/kernel/kernel-python-sdk/commit/74dbad8f0cdf5b414022ad907f6e20ee54893c59)) +* Let Vaults fill credentials from 1Password ([2937b10](https://github.com/kernel/kernel-python-sdk/commit/2937b10cce135282b6badc7e5bf71d339500ffdb)) + ## [0.113.0](https://github.com/kernel/kernel-python-sdk/compare/v0.112.0...v0.113.0) (2026-09-27) diff --git a/pyproject.toml b/pyproject.toml index 82dfdf81..7c2a12fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kernel" -version = "0.113.0" +version = "0.114.0" description = "The official Python library for the kernel API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/kernel/_version.py b/src/kernel/_version.py index 3350781a..f1d9dca2 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.113.0" # x-release-please-version +__version__ = "0.114.0" # x-release-please-version From 1f0aabc15ab7f7d943074978d8ba6839560f2ebe Mon Sep 17 00:00:00 2001 From: rgarcia <72655+rgarcia@users.noreply.github.com> Date: Wed, 30 Sep 2026 13:38:57 +0000 Subject: [PATCH 7/7] docs: correct 0.114.0 changelog entry for Link publishable key --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1ad420f..762517f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,9 @@ * Accept telemetry.storage and settle it at browser create ([28fb2d3](https://github.com/kernel/kernel-python-sdk/commit/28fb2d3c8fd83090d83404a0b407557585bf93f6)) * Allow export-only network and console telemetry for BAA orgs ([2ff8d4a](https://github.com/kernel/kernel-python-sdk/commit/2ff8d4acacb1b8152b9c7d1b38067c1b02167f40)) -* chore(stlc): seal custom-code tracking files ([5c1bed3](https://github.com/kernel/kernel-python-sdk/commit/5c1bed353eb421bff589bcc86b2940ca750e3999)) * Expose missing managed auth check URL as verification unavailable ([74dbad8](https://github.com/kernel/kernel-python-sdk/commit/74dbad8f0cdf5b414022ad907f6e20ee54893c59)) * Let Vaults fill credentials from 1Password ([2937b10](https://github.com/kernel/kernel-python-sdk/commit/2937b10cce135282b6badc7e5bf71d339500ffdb)) +* Send Stripe publishable key when refreshing customer-owned Link grants ([5c1bed3](https://github.com/kernel/kernel-python-sdk/commit/5c1bed353eb421bff589bcc86b2940ca750e3999)) ## [0.113.0](https://github.com/kernel/kernel-python-sdk/compare/v0.112.0...v0.113.0) (2026-09-27)