diff --git a/skyvern/forge/sdk/routes/code_samples.py b/skyvern/forge/sdk/routes/code_samples.py index 7f628a90..f8c5fdbd 100644 --- a/skyvern/forge/sdk/routes/code_samples.py +++ b/skyvern/forge/sdk/routes/code_samples.py @@ -25,10 +25,27 @@ RETRY_RUN_WEBHOOK_CODE_SAMPLE = """from skyvern import Skyvern skyvern = Skyvern(api_key="YOUR_API_KEY") await skyvern.retry_run_webhook(run_id="tsk_v2_123") """ -LOGIN_CODE_SAMPLE = """from skyvern import Skyvern +LOGIN_CODE_SAMPLE_SKYVERN = """# Login with password saved in Skyvern +from skyvern import Skyvern skyvern = Skyvern(api_key="YOUR_API_KEY") -await skyvern.login(workflow_id="wpid_123", parameters={"parameter1": "value1", "parameter2": "value2"}) +await skyvern.login(credential_id="cred_123") +""" +LOGIN_CODE_SAMPLE_BITWARDEN = """# Login with password saved in Bitwarden +from skyvern import Skyvern + +skyvern = Skyvern(api_key="YOUR_API_KEY") +# Login with a Bitwarden collection and website url filter +await skyvern.login(bitwarden_collection_id="BITWARDEN COLLECTION ID", url_filter="https://example.com") + +# Login with a Bitwarden item +await skyvern.login(bitwarden_item_id="BITWARDEN ITEM ID") +""" +LOGIN_CODE_SAMPLE_ONEPASSWORD = """# Login with password saved in 1Password +from skyvern import Skyvern + +skyvern = Skyvern(api_key="YOUR_API_KEY") +await skyvern.login(onepassword_vault_id="ONEPASSWORD VAULT ID", onepassword_item_id="ONEPASSWORD ITEM ID") """ # Workflows diff --git a/skyvern/forge/sdk/routes/run_blocks.py b/skyvern/forge/sdk/routes/run_blocks.py index 1c97b812..d400d46e 100644 --- a/skyvern/forge/sdk/routes/run_blocks.py +++ b/skyvern/forge/sdk/routes/run_blocks.py @@ -7,7 +7,11 @@ from skyvern.config import settings from skyvern.exceptions import MissingBrowserAddressError from skyvern.forge import app from skyvern.forge.sdk.core import skyvern_context -from skyvern.forge.sdk.routes.code_samples import LOGIN_CODE_SAMPLE +from skyvern.forge.sdk.routes.code_samples import ( + LOGIN_CODE_SAMPLE_BITWARDEN, + LOGIN_CODE_SAMPLE_ONEPASSWORD, + LOGIN_CODE_SAMPLE_SKYVERN, +) from skyvern.forge.sdk.routes.routers import base_router from skyvern.forge.sdk.schemas.organizations import Organization from skyvern.forge.sdk.services import org_auth_service @@ -39,7 +43,24 @@ If login is completed, you're successful.""" response_model=WorkflowRunResponse, openapi_extra={ "x-fern-sdk-method-name": "login", - "x-fern-examples": [{"code-samples": [{"sdk": "python", "code": LOGIN_CODE_SAMPLE}]}], + "x-fern-examples": [ + { + "code-samples": [ + { + "sdk": "python", + "code": LOGIN_CODE_SAMPLE_SKYVERN, + }, + { + "sdk": "python", + "code": LOGIN_CODE_SAMPLE_BITWARDEN, + }, + { + "sdk": "python", + "code": LOGIN_CODE_SAMPLE_ONEPASSWORD, + }, + ] + } + ], }, description="Log in to a website using either credential stored in Skyvern, Bitwarden or 1Password", summary="Login Task", @@ -80,8 +101,8 @@ async def login( yaml_parameters = [ BitwardenLoginCredentialParameterYAML( key=parameter_key, - collection_id=login_request.collection_id, - item_id=login_request.item_id, + collection_id=login_request.bitwarden_collection_id, + item_id=login_request.bitwarden_item_id, url=login_request.url, description="The ID of the bitwarden collection to use for login", bitwarden_client_id_aws_secret_key="SKYVERN_BITWARDEN_CLIENT_ID", @@ -93,8 +114,8 @@ async def login( yaml_parameters = [ OnePasswordCredentialParameterYAML( key=parameter_key, - vault_id=login_request.vault_id, - item_id=login_request.item_id, + vault_id=login_request.onepassword_vault_id, + item_id=login_request.onepassword_item_id, ) ] diff --git a/skyvern/schemas/run_blocks.py b/skyvern/schemas/run_blocks.py index c104d0bb..a3f1af73 100644 --- a/skyvern/schemas/run_blocks.py +++ b/skyvern/schemas/run_blocks.py @@ -13,36 +13,58 @@ class CredentialType(StrEnum): class LoginRequestBase(BaseModel): - url: str | None = None - prompt: str | None = None - webhook_url: str | None = None - proxy_location: ProxyLocation | None = None - totp_identifier: str | None = None - totp_url: str | None = None - browser_session_id: str | None = None - extra_http_headers: dict[str, str] | None = None - max_screenshot_scrolling_times: int | None = None + url: str | None = Field(default=None, description="Website url") + prompt: str | None = Field( + default=None, + description="Login instructions. Skyvern has default prompt/instruction for login if this field is not provided.", + ) + webhook_url: str | None = Field(default=None, description="Webhook URL to send login status updates") + proxy_location: ProxyLocation | None = Field(default=None, description="Proxy location to use") + totp_identifier: str | None = Field( + default=None, description="Identifier for TOTP (Time-based One-Time Password) if required" + ) + totp_url: str | None = Field(default=None, description="TOTP URL to fetch one-time passwords") + browser_session_id: str | None = Field( + default=None, description="ID of the browser session to use, which is prefixed by `pbs_` e.g. `pbs_123456`" + ) + extra_http_headers: dict[str, str] | None = Field( + default=None, description="Additional HTTP headers to include in requests" + ) + max_screenshot_scrolling_times: int | None = Field( + default=None, description="Maximum number of times to scroll for screenshots" + ) -class SkyvernCredentialLoginRequest(LoginRequestBase): +class SkyvernLoginRequest(LoginRequestBase): + """ + Login with password saved in Skyvern + """ + credential_type: Literal[CredentialType.skyvern] = CredentialType.skyvern - credential_id: str + credential_id: str = Field(..., description="ID of the Skyvern credential to use for login.") class BitwardenLoginRequest(LoginRequestBase): + """ + Login with password saved in Bitwarden + """ + credential_type: Literal[CredentialType.bitwarden] = CredentialType.bitwarden - collection_id: str | None = None - item_id: str | None = None - url: str | None = None + bitwarden_collection_id: str | None = Field(default=None, description="Bitwarden collection ID") + bitwarden_item_id: str | None = Field(default=None, description="Bitwarden item ID") class OnePasswordLoginRequest(LoginRequestBase): + """ + Login with password saved in 1Password + """ + credential_type: Literal[CredentialType.onepassword] = CredentialType.onepassword - vault_id: str - item_id: str + onepassword_vault_id: str = Field(..., description="1Password vault ID.") + onepassword_item_id: str = Field(..., description="1Password item ID.") LoginRequest = Annotated[ - Union[SkyvernCredentialLoginRequest, BitwardenLoginRequest, OnePasswordLoginRequest], + Union[SkyvernLoginRequest, BitwardenLoginRequest, OnePasswordLoginRequest], Field(discriminator="credential_type"), ]