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(
|
||||
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]:
|
||||
# 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"}}
|
||||
# context comes from app.WORKFLOW_CONTEXT_MANAGER.get_workflow_run_context(workflow_run_id)
|
||||
context = skyvern_context.current()
|
||||
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)
|
||||
parameters_in_workflow_context = workflow_run_context.parameters
|
||||
for key in parameters:
|
||||
@@ -23,7 +26,7 @@ async def setup(
|
||||
parameter = parameters_in_workflow_context[key]
|
||||
if parameter.workflow_parameter_type == WorkflowParameterType.CREDENTIAL_ID:
|
||||
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(
|
||||
parameters=parameters,
|
||||
page=skyvern_page,
|
||||
|
||||
@@ -71,7 +71,7 @@ class SkyvernPage:
|
||||
self._record = recorder or (lambda ac: None)
|
||||
|
||||
@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()
|
||||
if context and context.workflow_run_id and context.organization_id:
|
||||
workflow_run = await app.DATABASE.get_workflow_run(
|
||||
@@ -79,12 +79,13 @@ class SkyvernPage:
|
||||
)
|
||||
if 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:
|
||||
raise WorkflowRunNotFound(workflow_run_id=context.workflow_run_id)
|
||||
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
|
||||
|
||||
@classmethod
|
||||
@@ -103,10 +104,13 @@ class SkyvernPage:
|
||||
return browser_state
|
||||
|
||||
@classmethod
|
||||
async def create(cls) -> SkyvernPage:
|
||||
async def create(
|
||||
cls,
|
||||
browser_session_id: str | None = None,
|
||||
) -> SkyvernPage:
|
||||
# initialize browser state
|
||||
# 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(
|
||||
browser_state=browser_state,
|
||||
url="",
|
||||
|
||||
@@ -2438,7 +2438,13 @@ class WorkflowService:
|
||||
return None, rendered_cache_key_value
|
||||
|
||||
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:
|
||||
"""
|
||||
Execute the related workflow script instead of running the workflow blocks.
|
||||
@@ -2458,6 +2464,7 @@ class WorkflowService:
|
||||
organization_id=organization.organization_id,
|
||||
parameters=parameters,
|
||||
workflow_run_id=workflow_run.workflow_run_id,
|
||||
browser_session_id=browser_session_id,
|
||||
background_tasks=None, # Execute synchronously
|
||||
)
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ async def execute_script(
|
||||
organization_id: str,
|
||||
parameters: dict[str, Any] | None = None,
|
||||
workflow_run_id: str | None = None,
|
||||
browser_session_id: str | None = None,
|
||||
background_tasks: BackgroundTasks | None = None,
|
||||
) -> None:
|
||||
# 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}
|
||||
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:
|
||||
# Execute asynchronously in background
|
||||
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:
|
||||
# Execute synchronously
|
||||
script_path = os.path.join(script.script_id, "main.py")
|
||||
if os.path.exists(script_path):
|
||||
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:
|
||||
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,
|
||||
organization_id: str | None = None,
|
||||
workflow_run_id: str | None = None,
|
||||
browser_session_id: str | None = None,
|
||||
) -> None:
|
||||
# register the script run
|
||||
context = skyvern_context.current()
|
||||
if not context:
|
||||
context = skyvern_context.ensure_context()
|
||||
skyvern_context.set(skyvern_context.SkyvernContext())
|
||||
context.browser_session_id = browser_session_id
|
||||
if workflow_run_id and organization_id:
|
||||
workflow_run = await app.DATABASE.get_workflow_run(
|
||||
workflow_run_id=workflow_run_id, organization_id=organization_id
|
||||
|
||||
Reference in New Issue
Block a user