From 663efc3587cef938a1a1504458eb37a964d48c9d Mon Sep 17 00:00:00 2001 From: Shuchang Zheng Date: Sat, 17 May 2025 11:15:47 -0700 Subject: [PATCH] update code samples part1 (#2375) --- skyvern/client/__init__.py | 6 +- skyvern/client/agent/client.py | 100 ++++---- skyvern/client/browser_session/client.py | 63 ++++-- skyvern/client/client.py | 8 +- skyvern/client/core/client_wrapper.py | 2 +- skyvern/client/credentials/client.py | 214 +++++++++++++++++- skyvern/client/errors/__init__.py | 4 +- ...authorized_error.py => forbidden_error.py} | 4 +- skyvern/client/types/__init__.py | 2 + skyvern/client/types/action_block.py | 1 + .../client/types/browser_session_response.py | 17 +- skyvern/client/types/extraction_block.py | 1 + skyvern/client/types/file_download_block.py | 1 + .../types/for_loop_block_loop_blocks_item.py | 8 + skyvern/client/types/login_block.py | 1 + skyvern/client/types/navigation_block.py | 1 + skyvern/client/types/task_block.py | 1 + skyvern/client/types/task_run_request.py | 19 +- skyvern/client/types/task_run_response.py | 6 +- skyvern/client/types/totp_code.py | 78 +++++++ skyvern/client/types/url_block.py | 1 + skyvern/client/types/validation_block.py | 1 + .../types/workflow_definition_blocks_item.py | 8 + skyvern/client/types/workflow_run_request.py | 20 +- skyvern/client/types/workflow_run_response.py | 6 +- 25 files changed, 474 insertions(+), 99 deletions(-) rename skyvern/client/errors/{unauthorized_error.py => forbidden_error.py} (66%) create mode 100644 skyvern/client/types/totp_code.py diff --git a/skyvern/client/__init__.py b/skyvern/client/__init__.py index 974397e8..07638544 100644 --- a/skyvern/client/__init__.py +++ b/skyvern/client/__init__.py @@ -159,6 +159,7 @@ from .types import ( TextPromptBlockParametersItem_Credential, TextPromptBlockParametersItem_Output, TextPromptBlockParametersItem_Workflow, + TotpCode, UploadToS3Block, UrlBlock, UrlBlockDataSchema, @@ -233,7 +234,7 @@ from .types import ( WorkflowRunResponseOutput, WorkflowStatus, ) -from .errors import BadRequestError, NotFoundError, UnauthorizedError, UnprocessableEntityError +from .errors import BadRequestError, ForbiddenError, NotFoundError, UnprocessableEntityError from . import agent, browser_session, credentials from .agent import ( AgentGetRunResponse, @@ -358,6 +359,7 @@ __all__ = [ "ForLoopBlockLoopOver_Credential", "ForLoopBlockLoopOver_Output", "ForLoopBlockLoopOver_Workflow", + "ForbiddenError", "HttpValidationError", "LoginBlock", "LoginBlockDataSchema", @@ -419,7 +421,7 @@ __all__ = [ "TextPromptBlockParametersItem_Credential", "TextPromptBlockParametersItem_Output", "TextPromptBlockParametersItem_Workflow", - "UnauthorizedError", + "TotpCode", "UnprocessableEntityError", "UploadToS3Block", "UrlBlock", diff --git a/skyvern/client/agent/client.py b/skyvern/client/agent/client.py index 45c7a316..a6c660c1 100644 --- a/skyvern/client/agent/client.py +++ b/skyvern/client/agent/client.py @@ -54,7 +54,7 @@ class AgentClient: authorization="YOUR_AUTHORIZATION", ) client.agent.get_run( - run_id="run_id", + run_id="tsk_123", ) """ _response = self._client_wrapper.httpx_client.request( @@ -156,6 +156,7 @@ class AgentClient: Parameters ---------- workflow_id : str + The ID of the workflow to update. Workflow ID starts with `wpid_`. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -174,7 +175,7 @@ class AgentClient: authorization="YOUR_AUTHORIZATION", ) client.agent.update_workflow( - workflow_id="workflow_id", + workflow_id="wpid_123", ) """ _response = self._client_wrapper.httpx_client.request( @@ -215,6 +216,7 @@ class AgentClient: Parameters ---------- workflow_id : str + The ID of the workflow to delete. Workflow ID starts with `wpid_`. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -233,7 +235,7 @@ class AgentClient: authorization="YOUR_AUTHORIZATION", ) client.agent.delete_workflow( - workflow_id="workflow_id", + workflow_id="wpid_123", ) """ _response = self._client_wrapper.httpx_client.request( @@ -271,8 +273,8 @@ class AgentClient: prompt: str, user_agent: typing.Optional[str] = None, url: typing.Optional[str] = OMIT, - title: typing.Optional[str] = OMIT, engine: typing.Optional[RunEngine] = OMIT, + title: typing.Optional[str] = OMIT, proxy_location: typing.Optional[ProxyLocation] = OMIT, data_extraction_schema: typing.Optional[TaskRunRequestDataExtractionSchema] = OMIT, error_code_mapping: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT, @@ -282,6 +284,7 @@ class AgentClient: totp_url: typing.Optional[str] = OMIT, browser_session_id: typing.Optional[str] = OMIT, publish_workflow: typing.Optional[bool] = OMIT, + include_action_history_in_verification: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> TaskRunResponse: """ @@ -297,11 +300,11 @@ class AgentClient: url : typing.Optional[str] The starting URL for the task. If not provided, Skyvern will attempt to determine an appropriate URL - title : typing.Optional[str] - Optional title for the task - engine : typing.Optional[RunEngine] - The Skyvern engine version to use for this task + The Skyvern engine version to use for this task. The default value is skyvern-2.0. + + title : typing.Optional[str] + The title for the task proxy_location : typing.Optional[ProxyLocation] Geographic Proxy location to route the browser traffic through @@ -328,7 +331,10 @@ class AgentClient: ID of an existing browser session to reuse, having it continue from the current screen state publish_workflow : typing.Optional[bool] - Whether to publish this task as a reusable workflow. + Whether to publish this task as a reusable workflow. Only available for skyvern-2.0. + + include_action_history_in_verification : typing.Optional[bool] + Whether to include action history when verifying that the task is complete request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -346,7 +352,7 @@ class AgentClient: api_key="YOUR_API_KEY", authorization="YOUR_AUTHORIZATION", ) - await client.agent.run_task( + client.agent.run_task( prompt="prompt", ) """ @@ -356,8 +362,8 @@ class AgentClient: json={ "prompt": prompt, "url": url, - "title": title, "engine": engine, + "title": title, "proxy_location": proxy_location, "data_extraction_schema": convert_and_respect_annotation_metadata( object_=data_extraction_schema, annotation=TaskRunRequestDataExtractionSchema, direction="write" @@ -369,6 +375,7 @@ class AgentClient: "totp_url": totp_url, "browser_session_id": browser_session_id, "publish_workflow": publish_workflow, + "include_action_history_in_verification": include_action_history_in_verification, }, headers={ "x-user-agent": str(user_agent) if user_agent is not None else None, @@ -417,8 +424,8 @@ class AgentClient: template: typing.Optional[bool] = None, max_steps_override: typing.Optional[int] = None, user_agent: typing.Optional[str] = None, - title: typing.Optional[str] = OMIT, parameters: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + title: typing.Optional[str] = OMIT, proxy_location: typing.Optional[ProxyLocation] = OMIT, webhook_url: typing.Optional[str] = OMIT, totp_url: typing.Optional[str] = OMIT, @@ -432,7 +439,7 @@ class AgentClient: Parameters ---------- workflow_id : str - ID of the workflow to run + ID of the workflow to run. Workflow ID starts with `wpid_`. template : typing.Optional[bool] @@ -440,26 +447,26 @@ class AgentClient: user_agent : typing.Optional[str] - title : typing.Optional[str] - Optional title for this workflow run - parameters : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] Parameters to pass to the workflow + title : typing.Optional[str] + The title for this workflow run + proxy_location : typing.Optional[ProxyLocation] Location of proxy to use for this workflow run webhook_url : typing.Optional[str] - URL to send workflow status updates to after a run is finished + URL to send workflow status updates to after a run is finished. Refer to https://docs.skyvern.com/running-tasks/webhooks-faq for webhook questions. totp_url : typing.Optional[str] - URL for TOTP authentication setup if Skyvern should be polling endpoint for 2FA codes + URL that serves TOTP/2FA/MFA codes for Skyvern to use during the workflow run. Refer to https://docs.skyvern.com/running-tasks/advanced-features#get-code-from-your-endpoint totp_identifier : typing.Optional[str] - Identifier for TOTP (Time-based One-Time Password) authentication if codes are being pushed to Skyvern + Identifier for the TOTP/2FA/MFA code when the code is pushed to Skyvern. Refer to https://docs.skyvern.com/running-tasks/advanced-features#time-based-one-time-password-totp browser_session_id : typing.Optional[str] - ID of an existing browser session to reuse, having it continue from the current screen state + ID of a Skyvern browser session to reuse, having it continue from the current screen state request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -478,7 +485,7 @@ class AgentClient: authorization="YOUR_AUTHORIZATION", ) client.agent.run_workflow( - workflow_id="workflow_id", + workflow_id="wpid_123", ) """ _response = self._client_wrapper.httpx_client.request( @@ -489,8 +496,8 @@ class AgentClient: }, json={ "workflow_id": workflow_id, - "title": title, "parameters": parameters, + "title": title, "proxy_location": proxy_location, "webhook_url": webhook_url, "totp_url": totp_url, @@ -636,7 +643,7 @@ class AsyncAgentClient: async def main() -> None: await client.agent.get_run( - run_id="run_id", + run_id="tsk_123", ) @@ -751,6 +758,7 @@ class AsyncAgentClient: Parameters ---------- workflow_id : str + The ID of the workflow to update. Workflow ID starts with `wpid_`. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -774,7 +782,7 @@ class AsyncAgentClient: async def main() -> None: await client.agent.update_workflow( - workflow_id="workflow_id", + workflow_id="wpid_123", ) @@ -818,6 +826,7 @@ class AsyncAgentClient: Parameters ---------- workflow_id : str + The ID of the workflow to delete. Workflow ID starts with `wpid_`. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -841,7 +850,7 @@ class AsyncAgentClient: async def main() -> None: await client.agent.delete_workflow( - workflow_id="workflow_id", + workflow_id="wpid_123", ) @@ -882,8 +891,8 @@ class AsyncAgentClient: prompt: str, user_agent: typing.Optional[str] = None, url: typing.Optional[str] = OMIT, - title: typing.Optional[str] = OMIT, engine: typing.Optional[RunEngine] = OMIT, + title: typing.Optional[str] = OMIT, proxy_location: typing.Optional[ProxyLocation] = OMIT, data_extraction_schema: typing.Optional[TaskRunRequestDataExtractionSchema] = OMIT, error_code_mapping: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT, @@ -893,6 +902,7 @@ class AsyncAgentClient: totp_url: typing.Optional[str] = OMIT, browser_session_id: typing.Optional[str] = OMIT, publish_workflow: typing.Optional[bool] = OMIT, + include_action_history_in_verification: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> TaskRunResponse: """ @@ -908,11 +918,11 @@ class AsyncAgentClient: url : typing.Optional[str] The starting URL for the task. If not provided, Skyvern will attempt to determine an appropriate URL - title : typing.Optional[str] - Optional title for the task - engine : typing.Optional[RunEngine] - The Skyvern engine version to use for this task + The Skyvern engine version to use for this task. The default value is skyvern-2.0. + + title : typing.Optional[str] + The title for the task proxy_location : typing.Optional[ProxyLocation] Geographic Proxy location to route the browser traffic through @@ -939,7 +949,10 @@ class AsyncAgentClient: ID of an existing browser session to reuse, having it continue from the current screen state publish_workflow : typing.Optional[bool] - Whether to publish this task as a reusable workflow. + Whether to publish this task as a reusable workflow. Only available for skyvern-2.0. + + include_action_history_in_verification : typing.Optional[bool] + Whether to include action history when verifying that the task is complete request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -975,8 +988,8 @@ class AsyncAgentClient: json={ "prompt": prompt, "url": url, - "title": title, "engine": engine, + "title": title, "proxy_location": proxy_location, "data_extraction_schema": convert_and_respect_annotation_metadata( object_=data_extraction_schema, annotation=TaskRunRequestDataExtractionSchema, direction="write" @@ -988,6 +1001,7 @@ class AsyncAgentClient: "totp_url": totp_url, "browser_session_id": browser_session_id, "publish_workflow": publish_workflow, + "include_action_history_in_verification": include_action_history_in_verification, }, headers={ "x-user-agent": str(user_agent) if user_agent is not None else None, @@ -1036,8 +1050,8 @@ class AsyncAgentClient: template: typing.Optional[bool] = None, max_steps_override: typing.Optional[int] = None, user_agent: typing.Optional[str] = None, - title: typing.Optional[str] = OMIT, parameters: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + title: typing.Optional[str] = OMIT, proxy_location: typing.Optional[ProxyLocation] = OMIT, webhook_url: typing.Optional[str] = OMIT, totp_url: typing.Optional[str] = OMIT, @@ -1051,7 +1065,7 @@ class AsyncAgentClient: Parameters ---------- workflow_id : str - ID of the workflow to run + ID of the workflow to run. Workflow ID starts with `wpid_`. template : typing.Optional[bool] @@ -1059,26 +1073,26 @@ class AsyncAgentClient: user_agent : typing.Optional[str] - title : typing.Optional[str] - Optional title for this workflow run - parameters : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] Parameters to pass to the workflow + title : typing.Optional[str] + The title for this workflow run + proxy_location : typing.Optional[ProxyLocation] Location of proxy to use for this workflow run webhook_url : typing.Optional[str] - URL to send workflow status updates to after a run is finished + URL to send workflow status updates to after a run is finished. Refer to https://docs.skyvern.com/running-tasks/webhooks-faq for webhook questions. totp_url : typing.Optional[str] - URL for TOTP authentication setup if Skyvern should be polling endpoint for 2FA codes + URL that serves TOTP/2FA/MFA codes for Skyvern to use during the workflow run. Refer to https://docs.skyvern.com/running-tasks/advanced-features#get-code-from-your-endpoint totp_identifier : typing.Optional[str] - Identifier for TOTP (Time-based One-Time Password) authentication if codes are being pushed to Skyvern + Identifier for the TOTP/2FA/MFA code when the code is pushed to Skyvern. Refer to https://docs.skyvern.com/running-tasks/advanced-features#time-based-one-time-password-totp browser_session_id : typing.Optional[str] - ID of an existing browser session to reuse, having it continue from the current screen state + ID of a Skyvern browser session to reuse, having it continue from the current screen state request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1102,7 +1116,7 @@ class AsyncAgentClient: async def main() -> None: await client.agent.run_workflow( - workflow_id="workflow_id", + workflow_id="wpid_123", ) @@ -1116,8 +1130,8 @@ class AsyncAgentClient: }, json={ "workflow_id": workflow_id, - "title": title, "parameters": parameters, + "title": title, "proxy_location": proxy_location, "webhook_url": webhook_url, "totp_url": totp_url, diff --git a/skyvern/client/browser_session/client.py b/skyvern/client/browser_session/client.py index b81a7b09..a52544d4 100644 --- a/skyvern/client/browser_session/client.py +++ b/skyvern/client/browser_session/client.py @@ -1,18 +1,21 @@ # This file was auto-generated by Fern from our API Definition. -from ..core.client_wrapper import SyncClientWrapper import typing +from ..core.client_wrapper import SyncClientWrapper from ..core.request_options import RequestOptions from ..types.browser_session_response import BrowserSessionResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pydantic_utilities import parse_obj_as -from ..errors.unauthorized_error import UnauthorizedError +from ..errors.forbidden_error import ForbiddenError from ..errors.not_found_error import NotFoundError from ..errors.unprocessable_entity_error import UnprocessableEntityError from json.decoder import JSONDecodeError from ..core.api_error import ApiError from ..core.client_wrapper import AsyncClientWrapper +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + class BrowserSessionClient: def __init__(self, *, client_wrapper: SyncClientWrapper): @@ -62,8 +65,8 @@ class BrowserSessionClient: object_=_response.json(), ), ) - if _response.status_code == 401: - raise UnauthorizedError( + if _response.status_code == 403: + raise ForbiddenError( typing.cast( typing.Optional[typing.Any], parse_obj_as( @@ -137,8 +140,8 @@ class BrowserSessionClient: object_=_response.json(), ), ) - if _response.status_code == 401: - raise UnauthorizedError( + if _response.status_code == 403: + raise ForbiddenError( typing.cast( typing.Optional[typing.Any], parse_obj_as( @@ -163,13 +166,16 @@ class BrowserSessionClient: raise ApiError(status_code=_response.status_code, body=_response_json) def create_browser_session( - self, *, request_options: typing.Optional[RequestOptions] = None + self, *, timeout: typing.Optional[int] = OMIT, request_options: typing.Optional[RequestOptions] = None ) -> BrowserSessionResponse: """ Create a new browser session Parameters ---------- + timeout : typing.Optional[int] + Timeout in minutes for the session. Timeout is applied after the session is started. Must be between 5 and 10080. Defaults to 60. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -191,7 +197,14 @@ class BrowserSessionClient: _response = self._client_wrapper.httpx_client.request( "v1/browser_sessions", method="POST", + json={ + "timeout": timeout, + }, + headers={ + "content-type": "application/json", + }, request_options=request_options, + omit=OMIT, ) try: if 200 <= _response.status_code < 300: @@ -202,8 +215,8 @@ class BrowserSessionClient: object_=_response.json(), ), ) - if _response.status_code == 401: - raise UnauthorizedError( + if _response.status_code == 403: + raise ForbiddenError( typing.cast( typing.Optional[typing.Any], parse_obj_as( @@ -271,8 +284,8 @@ class BrowserSessionClient: object_=_response.json(), ), ) - if _response.status_code == 401: - raise UnauthorizedError( + if _response.status_code == 403: + raise ForbiddenError( typing.cast( typing.Optional[typing.Any], parse_obj_as( @@ -353,8 +366,8 @@ class AsyncBrowserSessionClient: object_=_response.json(), ), ) - if _response.status_code == 401: - raise UnauthorizedError( + if _response.status_code == 403: + raise ForbiddenError( typing.cast( typing.Optional[typing.Any], parse_obj_as( @@ -436,8 +449,8 @@ class AsyncBrowserSessionClient: object_=_response.json(), ), ) - if _response.status_code == 401: - raise UnauthorizedError( + if _response.status_code == 403: + raise ForbiddenError( typing.cast( typing.Optional[typing.Any], parse_obj_as( @@ -462,13 +475,16 @@ class AsyncBrowserSessionClient: raise ApiError(status_code=_response.status_code, body=_response_json) async def create_browser_session( - self, *, request_options: typing.Optional[RequestOptions] = None + self, *, timeout: typing.Optional[int] = OMIT, request_options: typing.Optional[RequestOptions] = None ) -> BrowserSessionResponse: """ Create a new browser session Parameters ---------- + timeout : typing.Optional[int] + Timeout in minutes for the session. Timeout is applied after the session is started. Must be between 5 and 10080. Defaults to 60. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -498,7 +514,14 @@ class AsyncBrowserSessionClient: _response = await self._client_wrapper.httpx_client.request( "v1/browser_sessions", method="POST", + json={ + "timeout": timeout, + }, + headers={ + "content-type": "application/json", + }, request_options=request_options, + omit=OMIT, ) try: if 200 <= _response.status_code < 300: @@ -509,8 +532,8 @@ class AsyncBrowserSessionClient: object_=_response.json(), ), ) - if _response.status_code == 401: - raise UnauthorizedError( + if _response.status_code == 403: + raise ForbiddenError( typing.cast( typing.Optional[typing.Any], parse_obj_as( @@ -586,8 +609,8 @@ class AsyncBrowserSessionClient: object_=_response.json(), ), ) - if _response.status_code == 401: - raise UnauthorizedError( + if _response.status_code == 403: + raise ForbiddenError( typing.cast( typing.Optional[typing.Any], parse_obj_as( diff --git a/skyvern/client/client.py b/skyvern/client/client.py index 68656e6f..469f8239 100644 --- a/skyvern/client/client.py +++ b/skyvern/client/client.py @@ -5,12 +5,12 @@ from .environment import SkyvernEnvironment import httpx from .core.client_wrapper import SyncClientWrapper from .agent.client import AgentClient -from .credentials.client import CredentialsClient from .browser_session.client import BrowserSessionClient +from .credentials.client import CredentialsClient from .core.client_wrapper import AsyncClientWrapper from .agent.client import AsyncAgentClient -from .credentials.client import AsyncCredentialsClient from .browser_session.client import AsyncBrowserSessionClient +from .credentials.client import AsyncCredentialsClient class Skyvern: @@ -76,8 +76,8 @@ class Skyvern: timeout=_defaulted_timeout, ) self.agent = AgentClient(client_wrapper=self._client_wrapper) - self.credentials = CredentialsClient(client_wrapper=self._client_wrapper) self.browser_session = BrowserSessionClient(client_wrapper=self._client_wrapper) + self.credentials = CredentialsClient(client_wrapper=self._client_wrapper) class AsyncSkyvern: @@ -143,8 +143,8 @@ class AsyncSkyvern: timeout=_defaulted_timeout, ) self.agent = AsyncAgentClient(client_wrapper=self._client_wrapper) - self.credentials = AsyncCredentialsClient(client_wrapper=self._client_wrapper) self.browser_session = AsyncBrowserSessionClient(client_wrapper=self._client_wrapper) + self.credentials = AsyncCredentialsClient(client_wrapper=self._client_wrapper) def _get_base_url(*, base_url: typing.Optional[str] = None, environment: SkyvernEnvironment) -> str: diff --git a/skyvern/client/core/client_wrapper.py b/skyvern/client/core/client_wrapper.py index 8efb8790..8471a644 100644 --- a/skyvern/client/core/client_wrapper.py +++ b/skyvern/client/core/client_wrapper.py @@ -24,7 +24,7 @@ class BaseClientWrapper: headers: typing.Dict[str, str] = { "X-Fern-Language": "Python", "X-Fern-SDK-Name": "skyvern", - "X-Fern-SDK-Version": "0.1.82", + "X-Fern-SDK-Version": "0.1.83", } if self._api_key is not None: headers["x-api-key"] = self._api_key diff --git a/skyvern/client/credentials/client.py b/skyvern/client/credentials/client.py index 1357caaf..0747482b 100644 --- a/skyvern/client/credentials/client.py +++ b/skyvern/client/credentials/client.py @@ -2,12 +2,14 @@ import typing from ..core.client_wrapper import SyncClientWrapper +import datetime as dt from ..core.request_options import RequestOptions -from ..types.credential_response import CredentialResponse +from ..types.totp_code import TotpCode from ..core.pydantic_utilities import parse_obj_as from ..errors.unprocessable_entity_error import UnprocessableEntityError from json.decoder import JSONDecodeError from ..core.api_error import ApiError +from ..types.credential_response import CredentialResponse from ..types.credential_type import CredentialType from .types.create_credential_request_credential import CreateCredentialRequestCredential from ..core.serialization import convert_and_respect_annotation_metadata @@ -22,6 +24,107 @@ class CredentialsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper + def send_totp_code( + self, + *, + totp_identifier: str, + content: str, + task_id: typing.Optional[str] = OMIT, + workflow_id: typing.Optional[str] = OMIT, + workflow_run_id: typing.Optional[str] = OMIT, + source: typing.Optional[str] = OMIT, + expired_at: typing.Optional[dt.datetime] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> TotpCode: + """ + Forward a TOTP (2FA, MFA) code to Skyvern + + Parameters + ---------- + totp_identifier : str + The identifier of the TOTP code. It can be the email address, phone number, or the identifier of the user. + + content : str + The content of the TOTP code. It can be the email content that contains the TOTP code, or the sms message that contains the TOTP code. Skyvern will automatically extract the TOTP code from the content. + + task_id : typing.Optional[str] + The task_id the totp code is for. It can be the task_id of the task that the TOTP code is for. + + workflow_id : typing.Optional[str] + The workflow ID the TOTP code is for. It can be the workflow ID of the workflow that the TOTP code is for. + + workflow_run_id : typing.Optional[str] + The workflow run id that the TOTP code is for. It can be the workflow run id of the workflow run that the TOTP code is for. + + source : typing.Optional[str] + An optional field. The source of the TOTP code. e.g. email, sms, etc. + + expired_at : typing.Optional[dt.datetime] + The timestamp when the TOTP code expires + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TotpCode + Successful Response + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + authorization="YOUR_AUTHORIZATION", + ) + client.credentials.send_totp_code( + totp_identifier="john.doe@example.com", + content="Hello, your verification code is 123456", + ) + """ + _response = self._client_wrapper.httpx_client.request( + "v1/credentials/totp", + method="POST", + json={ + "totp_identifier": totp_identifier, + "task_id": task_id, + "workflow_id": workflow_id, + "workflow_run_id": workflow_run_id, + "source": source, + "content": content, + "expired_at": expired_at, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + TotpCode, + parse_obj_as( + type_=TotpCode, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + def get_credentials( self, *, @@ -295,6 +398,115 @@ class AsyncCredentialsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper + async def send_totp_code( + self, + *, + totp_identifier: str, + content: str, + task_id: typing.Optional[str] = OMIT, + workflow_id: typing.Optional[str] = OMIT, + workflow_run_id: typing.Optional[str] = OMIT, + source: typing.Optional[str] = OMIT, + expired_at: typing.Optional[dt.datetime] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> TotpCode: + """ + Forward a TOTP (2FA, MFA) code to Skyvern + + Parameters + ---------- + totp_identifier : str + The identifier of the TOTP code. It can be the email address, phone number, or the identifier of the user. + + content : str + The content of the TOTP code. It can be the email content that contains the TOTP code, or the sms message that contains the TOTP code. Skyvern will automatically extract the TOTP code from the content. + + task_id : typing.Optional[str] + The task_id the totp code is for. It can be the task_id of the task that the TOTP code is for. + + workflow_id : typing.Optional[str] + The workflow ID the TOTP code is for. It can be the workflow ID of the workflow that the TOTP code is for. + + workflow_run_id : typing.Optional[str] + The workflow run id that the TOTP code is for. It can be the workflow run id of the workflow run that the TOTP code is for. + + source : typing.Optional[str] + An optional field. The source of the TOTP code. e.g. email, sms, etc. + + expired_at : typing.Optional[dt.datetime] + The timestamp when the TOTP code expires + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TotpCode + Successful Response + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + authorization="YOUR_AUTHORIZATION", + ) + + + async def main() -> None: + await client.credentials.send_totp_code( + totp_identifier="john.doe@example.com", + content="Hello, your verification code is 123456", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/credentials/totp", + method="POST", + json={ + "totp_identifier": totp_identifier, + "task_id": task_id, + "workflow_id": workflow_id, + "workflow_run_id": workflow_run_id, + "source": source, + "content": content, + "expired_at": expired_at, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + TotpCode, + parse_obj_as( + type_=TotpCode, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + async def get_credentials( self, *, diff --git a/skyvern/client/errors/__init__.py b/skyvern/client/errors/__init__.py index abc026cc..2511a0e6 100644 --- a/skyvern/client/errors/__init__.py +++ b/skyvern/client/errors/__init__.py @@ -1,8 +1,8 @@ # This file was auto-generated by Fern from our API Definition. from .bad_request_error import BadRequestError +from .forbidden_error import ForbiddenError from .not_found_error import NotFoundError -from .unauthorized_error import UnauthorizedError from .unprocessable_entity_error import UnprocessableEntityError -__all__ = ["BadRequestError", "NotFoundError", "UnauthorizedError", "UnprocessableEntityError"] +__all__ = ["BadRequestError", "ForbiddenError", "NotFoundError", "UnprocessableEntityError"] diff --git a/skyvern/client/errors/unauthorized_error.py b/skyvern/client/errors/forbidden_error.py similarity index 66% rename from skyvern/client/errors/unauthorized_error.py rename to skyvern/client/errors/forbidden_error.py index 1c00f98a..d17eb4b9 100644 --- a/skyvern/client/errors/unauthorized_error.py +++ b/skyvern/client/errors/forbidden_error.py @@ -4,6 +4,6 @@ from ..core.api_error import ApiError import typing -class UnauthorizedError(ApiError): +class ForbiddenError(ApiError): def __init__(self, body: typing.Optional[typing.Any]): - super().__init__(status_code=401, body=body) + super().__init__(status_code=403, body=body) diff --git a/skyvern/client/types/__init__.py b/skyvern/client/types/__init__.py index 73daa766..3239bf68 100644 --- a/skyvern/client/types/__init__.py +++ b/skyvern/client/types/__init__.py @@ -180,6 +180,7 @@ from .text_prompt_block_parameters_item import ( TextPromptBlockParametersItem_Output, TextPromptBlockParametersItem_Workflow, ) +from .totp_code import TotpCode from .upload_to_s3block import UploadToS3Block from .url_block import UrlBlock from .url_block_data_schema import UrlBlockDataSchema @@ -423,6 +424,7 @@ __all__ = [ "TextPromptBlockParametersItem_Credential", "TextPromptBlockParametersItem_Output", "TextPromptBlockParametersItem_Workflow", + "TotpCode", "UploadToS3Block", "UrlBlock", "UrlBlockDataSchema", diff --git a/skyvern/client/types/action_block.py b/skyvern/client/types/action_block.py index 12dcabc0..9eff2723 100644 --- a/skyvern/client/types/action_block.py +++ b/skyvern/client/types/action_block.py @@ -34,6 +34,7 @@ class ActionBlock(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/browser_session_response.py b/skyvern/client/types/browser_session_response.py index 710459ea..36e6fccc 100644 --- a/skyvern/client/types/browser_session_response.py +++ b/skyvern/client/types/browser_session_response.py @@ -32,9 +32,24 @@ class BrowserSessionResponse(UniversalBaseModel): ID of the associated runnable """ + timeout: typing.Optional[int] = pydantic.Field(default=None) + """ + Timeout in minutes for the session. Timeout is applied after the session is started. + """ + + started_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the session was started + """ + + completed_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the session was completed + """ + created_at: dt.datetime = pydantic.Field() """ - Timestamp when the session was created + Timestamp when the session was created (the timestamp for the initial request) """ modified_at: dt.datetime = pydantic.Field() diff --git a/skyvern/client/types/extraction_block.py b/skyvern/client/types/extraction_block.py index be41d975..2de9d8bb 100644 --- a/skyvern/client/types/extraction_block.py +++ b/skyvern/client/types/extraction_block.py @@ -34,6 +34,7 @@ class ExtractionBlock(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/file_download_block.py b/skyvern/client/types/file_download_block.py index e17de0cc..d67fece6 100644 --- a/skyvern/client/types/file_download_block.py +++ b/skyvern/client/types/file_download_block.py @@ -34,6 +34,7 @@ class FileDownloadBlock(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/for_loop_block_loop_blocks_item.py b/skyvern/client/types/for_loop_block_loop_blocks_item.py index 106c624d..b4599a81 100644 --- a/skyvern/client/types/for_loop_block_loop_blocks_item.py +++ b/skyvern/client/types/for_loop_block_loop_blocks_item.py @@ -60,6 +60,7 @@ class ForLoopBlockLoopBlocksItem_Action(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -130,6 +131,7 @@ class ForLoopBlockLoopBlocksItem_Extraction(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -165,6 +167,7 @@ class ForLoopBlockLoopBlocksItem_FileDownload(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -263,6 +266,7 @@ class ForLoopBlockLoopBlocksItem_GotoUrl(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -298,6 +302,7 @@ class ForLoopBlockLoopBlocksItem_Login(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -333,6 +338,7 @@ class ForLoopBlockLoopBlocksItem_Navigation(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -411,6 +417,7 @@ class ForLoopBlockLoopBlocksItem_Task(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -505,6 +512,7 @@ class ForLoopBlockLoopBlocksItem_Validation(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/login_block.py b/skyvern/client/types/login_block.py index b281fc4f..0c043e2a 100644 --- a/skyvern/client/types/login_block.py +++ b/skyvern/client/types/login_block.py @@ -34,6 +34,7 @@ class LoginBlock(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/navigation_block.py b/skyvern/client/types/navigation_block.py index bec5d1cf..0bcc96a3 100644 --- a/skyvern/client/types/navigation_block.py +++ b/skyvern/client/types/navigation_block.py @@ -34,6 +34,7 @@ class NavigationBlock(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/task_block.py b/skyvern/client/types/task_block.py index 3c7050b4..c914e2ce 100644 --- a/skyvern/client/types/task_block.py +++ b/skyvern/client/types/task_block.py @@ -34,6 +34,7 @@ class TaskBlock(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/task_run_request.py b/skyvern/client/types/task_run_request.py index fade92ff..74b89c80 100644 --- a/skyvern/client/types/task_run_request.py +++ b/skyvern/client/types/task_run_request.py @@ -20,14 +20,14 @@ class TaskRunRequest(UniversalBaseModel): The starting URL for the task. If not provided, Skyvern will attempt to determine an appropriate URL """ - title: typing.Optional[str] = pydantic.Field(default=None) - """ - Optional title for the task - """ - engine: typing.Optional[RunEngine] = pydantic.Field(default=None) """ - The Skyvern engine version to use for this task + The Skyvern engine version to use for this task. The default value is skyvern-2.0. + """ + + title: typing.Optional[str] = pydantic.Field(default=None) + """ + The title for the task """ proxy_location: typing.Optional[ProxyLocation] = pydantic.Field(default=None) @@ -72,7 +72,12 @@ class TaskRunRequest(UniversalBaseModel): publish_workflow: typing.Optional[bool] = pydantic.Field(default=None) """ - Whether to publish this task as a reusable workflow. + Whether to publish this task as a reusable workflow. Only available for skyvern-2.0. + """ + + include_action_history_in_verification: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether to include action history when verifying that the task is complete """ if IS_PYDANTIC_V2: diff --git a/skyvern/client/types/task_run_response.py b/skyvern/client/types/task_run_response.py index c05c07f3..684a041b 100644 --- a/skyvern/client/types/task_run_response.py +++ b/skyvern/client/types/task_run_response.py @@ -14,7 +14,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2 class TaskRunResponse(UniversalBaseModel): run_id: str = pydantic.Field() """ - Unique identifier for this run + Unique identifier for this run. Run ID starts with `tsk_` for task runs and `wr_` for workflow runs. """ status: RunStatus = pydantic.Field() @@ -24,7 +24,7 @@ class TaskRunResponse(UniversalBaseModel): output: typing.Optional[TaskRunResponseOutput] = pydantic.Field(default=None) """ - Output data from the run, if any. Format depends on the schema in the input + Output data from the run, if any. Format/schema depends on the data extracted by the run. """ downloaded_files: typing.Optional[typing.List[FileInfo]] = pydantic.Field(default=None) @@ -39,7 +39,7 @@ class TaskRunResponse(UniversalBaseModel): failure_reason: typing.Optional[str] = pydantic.Field(default=None) """ - Reason for failure if the run failed + Reason for failure if the run failed or terminated """ created_at: dt.datetime = pydantic.Field() diff --git a/skyvern/client/types/totp_code.py b/skyvern/client/types/totp_code.py new file mode 100644 index 00000000..b09d2dda --- /dev/null +++ b/skyvern/client/types/totp_code.py @@ -0,0 +1,78 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing +import datetime as dt +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class TotpCode(UniversalBaseModel): + totp_identifier: str = pydantic.Field() + """ + The identifier of the TOTP code. It can be the email address, phone number, or the identifier of the user. + """ + + task_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The task_id the totp code is for. It can be the task_id of the task that the TOTP code is for. + """ + + workflow_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The workflow ID the TOTP code is for. It can be the workflow ID of the workflow that the TOTP code is for. + """ + + workflow_run_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The workflow run id that the TOTP code is for. It can be the workflow run id of the workflow run that the TOTP code is for. + """ + + source: typing.Optional[str] = pydantic.Field(default=None) + """ + An optional field. The source of the TOTP code. e.g. email, sms, etc. + """ + + content: str = pydantic.Field() + """ + The content of the TOTP code. It can be the email content that contains the TOTP code, or the sms message that contains the TOTP code. Skyvern will automatically extract the TOTP code from the content. + """ + + expired_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + The timestamp when the TOTP code expires + """ + + totp_code_id: str = pydantic.Field() + """ + The skyvern ID of the TOTP code. + """ + + code: str = pydantic.Field() + """ + The TOTP code extracted from the content. + """ + + organization_id: str = pydantic.Field() + """ + The ID of the organization that the TOTP code is for. + """ + + created_at: dt.datetime = pydantic.Field() + """ + The timestamp when the TOTP code was created. + """ + + modified_at: dt.datetime = pydantic.Field() + """ + The timestamp when the TOTP code was modified. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/types/url_block.py b/skyvern/client/types/url_block.py index 3fe55c77..e13f8bae 100644 --- a/skyvern/client/types/url_block.py +++ b/skyvern/client/types/url_block.py @@ -34,6 +34,7 @@ class UrlBlock(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/validation_block.py b/skyvern/client/types/validation_block.py index b3a097f8..4b53e379 100644 --- a/skyvern/client/types/validation_block.py +++ b/skyvern/client/types/validation_block.py @@ -34,6 +34,7 @@ class ValidationBlock(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/workflow_definition_blocks_item.py b/skyvern/client/types/workflow_definition_blocks_item.py index a31b2347..6ee19e0a 100644 --- a/skyvern/client/types/workflow_definition_blocks_item.py +++ b/skyvern/client/types/workflow_definition_blocks_item.py @@ -60,6 +60,7 @@ class WorkflowDefinitionBlocksItem_Action(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -130,6 +131,7 @@ class WorkflowDefinitionBlocksItem_Extraction(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -165,6 +167,7 @@ class WorkflowDefinitionBlocksItem_FileDownload(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -264,6 +267,7 @@ class WorkflowDefinitionBlocksItem_GotoUrl(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -299,6 +303,7 @@ class WorkflowDefinitionBlocksItem_Login(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -334,6 +339,7 @@ class WorkflowDefinitionBlocksItem_Navigation(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -412,6 +418,7 @@ class WorkflowDefinitionBlocksItem_Task(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -506,6 +513,7 @@ class WorkflowDefinitionBlocksItem_Validation(UniversalBaseModel): totp_identifier: typing.Optional[str] = None cache_actions: typing.Optional[bool] = None complete_verification: typing.Optional[bool] = None + include_action_history_in_verification: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/workflow_run_request.py b/skyvern/client/types/workflow_run_request.py index 09be2c8e..7f9833ac 100644 --- a/skyvern/client/types/workflow_run_request.py +++ b/skyvern/client/types/workflow_run_request.py @@ -10,12 +10,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2 class WorkflowRunRequest(UniversalBaseModel): workflow_id: str = pydantic.Field() """ - ID of the workflow to run - """ - - title: typing.Optional[str] = pydantic.Field(default=None) - """ - Optional title for this workflow run + ID of the workflow to run. Workflow ID starts with `wpid_`. """ parameters: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None) @@ -23,6 +18,11 @@ class WorkflowRunRequest(UniversalBaseModel): Parameters to pass to the workflow """ + title: typing.Optional[str] = pydantic.Field(default=None) + """ + The title for this workflow run + """ + proxy_location: typing.Optional[ProxyLocation] = pydantic.Field(default=None) """ Location of proxy to use for this workflow run @@ -30,22 +30,22 @@ class WorkflowRunRequest(UniversalBaseModel): webhook_url: typing.Optional[str] = pydantic.Field(default=None) """ - URL to send workflow status updates to after a run is finished + URL to send workflow status updates to after a run is finished. Refer to https://docs.skyvern.com/running-tasks/webhooks-faq for webhook questions. """ totp_url: typing.Optional[str] = pydantic.Field(default=None) """ - URL for TOTP authentication setup if Skyvern should be polling endpoint for 2FA codes + URL that serves TOTP/2FA/MFA codes for Skyvern to use during the workflow run. Refer to https://docs.skyvern.com/running-tasks/advanced-features#get-code-from-your-endpoint """ totp_identifier: typing.Optional[str] = pydantic.Field(default=None) """ - Identifier for TOTP (Time-based One-Time Password) authentication if codes are being pushed to Skyvern + Identifier for the TOTP/2FA/MFA code when the code is pushed to Skyvern. Refer to https://docs.skyvern.com/running-tasks/advanced-features#time-based-one-time-password-totp """ browser_session_id: typing.Optional[str] = pydantic.Field(default=None) """ - ID of an existing browser session to reuse, having it continue from the current screen state + ID of a Skyvern browser session to reuse, having it continue from the current screen state """ if IS_PYDANTIC_V2: diff --git a/skyvern/client/types/workflow_run_response.py b/skyvern/client/types/workflow_run_response.py index ee46501e..0024e121 100644 --- a/skyvern/client/types/workflow_run_response.py +++ b/skyvern/client/types/workflow_run_response.py @@ -14,7 +14,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2 class WorkflowRunResponse(UniversalBaseModel): run_id: str = pydantic.Field() """ - Unique identifier for this run + Unique identifier for this run. Run ID starts with `tsk_` for task runs and `wr_` for workflow runs. """ status: RunStatus = pydantic.Field() @@ -24,7 +24,7 @@ class WorkflowRunResponse(UniversalBaseModel): output: typing.Optional[WorkflowRunResponseOutput] = pydantic.Field(default=None) """ - Output data from the run, if any. Format depends on the schema in the input + Output data from the run, if any. Format/schema depends on the data extracted by the run. """ downloaded_files: typing.Optional[typing.List[FileInfo]] = pydantic.Field(default=None) @@ -39,7 +39,7 @@ class WorkflowRunResponse(UniversalBaseModel): failure_reason: typing.Optional[str] = pydantic.Field(default=None) """ - Reason for failure if the run failed + Reason for failure if the run failed or terminated """ created_at: dt.datetime = pydantic.Field()