run script with browser session (#3368)
This commit is contained in:
@@ -9,13 +9,16 @@ from skyvern.forge.sdk.workflow.models.parameter import WorkflowParameterType
|
|||||||
|
|
||||||
|
|
||||||
async def setup(
|
async def setup(
|
||||||
parameters: dict[str, Any], generated_parameter_cls: type[BaseModel] | None = None
|
parameters: dict[str, Any],
|
||||||
|
generated_parameter_cls: type[BaseModel] | None = None,
|
||||||
|
browser_session_id: str | None = None,
|
||||||
) -> tuple[SkyvernPage, RunContext]:
|
) -> tuple[SkyvernPage, RunContext]:
|
||||||
# transform any secrets/credential parameters. For example, if there's only one credential in the parameters: {"cred_12345": "cred_12345"},
|
# transform any secrets/credential parameters. For example, if there's only one credential in the parameters: {"cred_12345": "cred_12345"},
|
||||||
# it should be transformed to {"cred_12345": {"username": "secret_5fBoa_username", "password": "secret_5fBoa_password"}}
|
# it should be transformed to {"cred_12345": {"username": "secret_5fBoa_username", "password": "secret_5fBoa_password"}}
|
||||||
# context comes from app.WORKFLOW_CONTEXT_MANAGER.get_workflow_run_context(workflow_run_id)
|
# context comes from app.WORKFLOW_CONTEXT_MANAGER.get_workflow_run_context(workflow_run_id)
|
||||||
context = skyvern_context.current()
|
context = skyvern_context.current()
|
||||||
if context and context.organization_id and context.workflow_run_id:
|
if context and context.organization_id and context.workflow_run_id:
|
||||||
|
browser_session_id = browser_session_id or context.browser_session_id
|
||||||
workflow_run_context = app.WORKFLOW_CONTEXT_MANAGER.get_workflow_run_context(context.workflow_run_id)
|
workflow_run_context = app.WORKFLOW_CONTEXT_MANAGER.get_workflow_run_context(context.workflow_run_id)
|
||||||
parameters_in_workflow_context = workflow_run_context.parameters
|
parameters_in_workflow_context = workflow_run_context.parameters
|
||||||
for key in parameters:
|
for key in parameters:
|
||||||
@@ -23,7 +26,7 @@ async def setup(
|
|||||||
parameter = parameters_in_workflow_context[key]
|
parameter = parameters_in_workflow_context[key]
|
||||||
if parameter.workflow_parameter_type == WorkflowParameterType.CREDENTIAL_ID:
|
if parameter.workflow_parameter_type == WorkflowParameterType.CREDENTIAL_ID:
|
||||||
parameters[key] = workflow_run_context.values[key]
|
parameters[key] = workflow_run_context.values[key]
|
||||||
skyvern_page = await SkyvernPage.create()
|
skyvern_page = await SkyvernPage.create(browser_session_id=browser_session_id)
|
||||||
run_context = RunContext(
|
run_context = RunContext(
|
||||||
parameters=parameters,
|
parameters=parameters,
|
||||||
page=skyvern_page,
|
page=skyvern_page,
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class SkyvernPage:
|
|||||||
self._record = recorder or (lambda ac: None)
|
self._record = recorder or (lambda ac: None)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def _get_or_create_browser_state(cls) -> BrowserState:
|
async def _get_or_create_browser_state(cls, browser_session_id: str | None = None) -> BrowserState:
|
||||||
context = skyvern_context.current()
|
context = skyvern_context.current()
|
||||||
if context and context.workflow_run_id and context.organization_id:
|
if context and context.workflow_run_id and context.organization_id:
|
||||||
workflow_run = await app.DATABASE.get_workflow_run(
|
workflow_run = await app.DATABASE.get_workflow_run(
|
||||||
@@ -79,12 +79,13 @@ class SkyvernPage:
|
|||||||
)
|
)
|
||||||
if workflow_run:
|
if workflow_run:
|
||||||
browser_state = await app.BROWSER_MANAGER.get_or_create_for_workflow_run(
|
browser_state = await app.BROWSER_MANAGER.get_or_create_for_workflow_run(
|
||||||
workflow_run=workflow_run, browser_session_id=None
|
workflow_run=workflow_run,
|
||||||
|
browser_session_id=browser_session_id,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise WorkflowRunNotFound(workflow_run_id=context.workflow_run_id)
|
raise WorkflowRunNotFound(workflow_run_id=context.workflow_run_id)
|
||||||
else:
|
else:
|
||||||
browser_state = await app.BROWSER_MANAGER.get_or_create_for_script()
|
browser_state = await app.BROWSER_MANAGER.get_or_create_for_script(browser_session_id=browser_session_id)
|
||||||
return browser_state
|
return browser_state
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -103,10 +104,13 @@ class SkyvernPage:
|
|||||||
return browser_state
|
return browser_state
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def create(cls) -> SkyvernPage:
|
async def create(
|
||||||
|
cls,
|
||||||
|
browser_session_id: str | None = None,
|
||||||
|
) -> SkyvernPage:
|
||||||
# initialize browser state
|
# initialize browser state
|
||||||
# TODO: add workflow_run_id or eventually script_id/script_run_id
|
# TODO: add workflow_run_id or eventually script_id/script_run_id
|
||||||
browser_state = await cls._get_or_create_browser_state()
|
browser_state = await cls._get_or_create_browser_state(browser_session_id=browser_session_id)
|
||||||
scraped_page = await scrape_website(
|
scraped_page = await scrape_website(
|
||||||
browser_state=browser_state,
|
browser_state=browser_state,
|
||||||
url="",
|
url="",
|
||||||
|
|||||||
@@ -2438,7 +2438,13 @@ class WorkflowService:
|
|||||||
return None, rendered_cache_key_value
|
return None, rendered_cache_key_value
|
||||||
|
|
||||||
async def _execute_workflow_script(
|
async def _execute_workflow_script(
|
||||||
self, script_id: str, workflow: Workflow, workflow_run: WorkflowRun, api_key: str, organization: Organization
|
self,
|
||||||
|
script_id: str,
|
||||||
|
workflow: Workflow,
|
||||||
|
workflow_run: WorkflowRun,
|
||||||
|
api_key: str,
|
||||||
|
organization: Organization,
|
||||||
|
browser_session_id: str | None = None,
|
||||||
) -> WorkflowRun:
|
) -> WorkflowRun:
|
||||||
"""
|
"""
|
||||||
Execute the related workflow script instead of running the workflow blocks.
|
Execute the related workflow script instead of running the workflow blocks.
|
||||||
@@ -2458,6 +2464,7 @@ class WorkflowService:
|
|||||||
organization_id=organization.organization_id,
|
organization_id=organization.organization_id,
|
||||||
parameters=parameters,
|
parameters=parameters,
|
||||||
workflow_run_id=workflow_run.workflow_run_id,
|
workflow_run_id=workflow_run.workflow_run_id,
|
||||||
|
browser_session_id=browser_session_id,
|
||||||
background_tasks=None, # Execute synchronously
|
background_tasks=None, # Execute synchronously
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ async def execute_script(
|
|||||||
organization_id: str,
|
organization_id: str,
|
||||||
parameters: dict[str, Any] | None = None,
|
parameters: dict[str, Any] | None = None,
|
||||||
workflow_run_id: str | None = None,
|
workflow_run_id: str | None = None,
|
||||||
|
browser_session_id: str | None = None,
|
||||||
background_tasks: BackgroundTasks | None = None,
|
background_tasks: BackgroundTasks | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
# TODO: assume the script only has one ScriptFile called main.py
|
# TODO: assume the script only has one ScriptFile called main.py
|
||||||
@@ -229,17 +230,26 @@ async def execute_script(
|
|||||||
parameters = {wf_param.key: run_param.value for wf_param, run_param in parameter_tuples}
|
parameters = {wf_param.key: run_param.value for wf_param, run_param in parameter_tuples}
|
||||||
LOG.info("Script run Parameters is using workflow run parameters", parameters=parameters)
|
LOG.info("Script run Parameters is using workflow run parameters", parameters=parameters)
|
||||||
|
|
||||||
|
script_path = os.path.join(script.script_id, "main.py")
|
||||||
if background_tasks:
|
if background_tasks:
|
||||||
# Execute asynchronously in background
|
# Execute asynchronously in background
|
||||||
background_tasks.add_task(
|
background_tasks.add_task(
|
||||||
run_script, parameters=parameters, organization_id=organization_id, workflow_run_id=workflow_run_id
|
run_script,
|
||||||
|
script_path,
|
||||||
|
parameters=parameters,
|
||||||
|
organization_id=organization_id,
|
||||||
|
workflow_run_id=workflow_run_id,
|
||||||
|
browser_session_id=browser_session_id,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Execute synchronously
|
# Execute synchronously
|
||||||
script_path = os.path.join(script.script_id, "main.py")
|
|
||||||
if os.path.exists(script_path):
|
if os.path.exists(script_path):
|
||||||
await run_script(
|
await run_script(
|
||||||
script_path, parameters=parameters, organization_id=organization_id, workflow_run_id=workflow_run_id
|
script_path,
|
||||||
|
parameters=parameters,
|
||||||
|
organization_id=organization_id,
|
||||||
|
workflow_run_id=workflow_run_id,
|
||||||
|
browser_session_id=browser_session_id,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
LOG.error("Script main.py not found", script_path=script_path, script_id=script_id)
|
LOG.error("Script main.py not found", script_path=script_path, script_id=script_id)
|
||||||
@@ -1252,12 +1262,14 @@ async def run_script(
|
|||||||
parameters: dict[str, Any] | None = None,
|
parameters: dict[str, Any] | None = None,
|
||||||
organization_id: str | None = None,
|
organization_id: str | None = None,
|
||||||
workflow_run_id: str | None = None,
|
workflow_run_id: str | None = None,
|
||||||
|
browser_session_id: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
# register the script run
|
# register the script run
|
||||||
context = skyvern_context.current()
|
context = skyvern_context.current()
|
||||||
if not context:
|
if not context:
|
||||||
context = skyvern_context.ensure_context()
|
context = skyvern_context.ensure_context()
|
||||||
skyvern_context.set(skyvern_context.SkyvernContext())
|
skyvern_context.set(skyvern_context.SkyvernContext())
|
||||||
|
context.browser_session_id = browser_session_id
|
||||||
if workflow_run_id and organization_id:
|
if workflow_run_id and organization_id:
|
||||||
workflow_run = await app.DATABASE.get_workflow_run(
|
workflow_run = await app.DATABASE.get_workflow_run(
|
||||||
workflow_run_id=workflow_run_id, organization_id=organization_id
|
workflow_run_id=workflow_run_id, organization_id=organization_id
|
||||||
|
|||||||
Reference in New Issue
Block a user