two more public endpoints: retry_run_webhook, get_artifact (#2445)
This commit is contained in:
@@ -29,6 +29,8 @@ from skyvern.forge.sdk.routes.code_samples import (
|
|||||||
CREATE_WORKFLOW_CODE_SAMPLE_PYTHON,
|
CREATE_WORKFLOW_CODE_SAMPLE_PYTHON,
|
||||||
DELETE_WORKFLOW_CODE_SAMPLE,
|
DELETE_WORKFLOW_CODE_SAMPLE,
|
||||||
GET_RUN_CODE_SAMPLE,
|
GET_RUN_CODE_SAMPLE,
|
||||||
|
GET_WORKFLOWS_CODE_SAMPLE,
|
||||||
|
RETRY_RUN_WEBHOOK_CODE_SAMPLE,
|
||||||
RUN_TASK_CODE_SAMPLE,
|
RUN_TASK_CODE_SAMPLE,
|
||||||
RUN_WORKFLOW_CODE_SAMPLE,
|
RUN_WORKFLOW_CODE_SAMPLE,
|
||||||
UPDATE_WORKFLOW_CODE_SAMPLE,
|
UPDATE_WORKFLOW_CODE_SAMPLE,
|
||||||
@@ -666,6 +668,69 @@ async def delete_workflow(
|
|||||||
await app.WORKFLOW_SERVICE.delete_workflow_by_permanent_id(workflow_id, current_org.organization_id)
|
await app.WORKFLOW_SERVICE.delete_workflow_by_permanent_id(workflow_id, current_org.organization_id)
|
||||||
|
|
||||||
|
|
||||||
|
@base_router.get(
|
||||||
|
"/artifacts/{artifact_id}",
|
||||||
|
tags=["Artifacts"],
|
||||||
|
response_model=Artifact,
|
||||||
|
openapi_extra={
|
||||||
|
"x-fern-sdk-group-name": "artifacts",
|
||||||
|
"x-fern-sdk-method-name": "get_artifact",
|
||||||
|
},
|
||||||
|
description="Get an artifact",
|
||||||
|
summary="Get an artifact",
|
||||||
|
responses={
|
||||||
|
200: {"description": "Successfully retrieved artifact"},
|
||||||
|
404: {"description": "Artifact not found"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
@base_router.get("/artifacts/{artifact_id}/", response_model=Artifact, include_in_schema=False)
|
||||||
|
async def get_artifact(
|
||||||
|
artifact_id: str,
|
||||||
|
current_org: Organization = Depends(org_auth_service.get_current_org),
|
||||||
|
) -> Artifact:
|
||||||
|
analytics.capture("skyvern-oss-artifact-get")
|
||||||
|
artifact = await app.DATABASE.get_artifact_by_id(
|
||||||
|
artifact_id=artifact_id,
|
||||||
|
organization_id=current_org.organization_id,
|
||||||
|
)
|
||||||
|
if not artifact:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Artifact not found {artifact_id}",
|
||||||
|
)
|
||||||
|
if settings.ENV != "local" or settings.GENERATE_PRESIGNED_URLS:
|
||||||
|
signed_urls = await app.ARTIFACT_MANAGER.get_share_links([artifact])
|
||||||
|
if signed_urls:
|
||||||
|
artifact.signed_url = signed_urls[0]
|
||||||
|
else:
|
||||||
|
LOG.warning(
|
||||||
|
"Failed to get signed url for artifact",
|
||||||
|
artifact_id=artifact_id,
|
||||||
|
)
|
||||||
|
return artifact
|
||||||
|
|
||||||
|
|
||||||
|
@base_router.post(
|
||||||
|
"/runs/{run_id}/retry_webhook",
|
||||||
|
tags=["Agent"],
|
||||||
|
openapi_extra={
|
||||||
|
"x-fern-sdk-group-name": "agent",
|
||||||
|
"x-fern-sdk-method-name": "retry_run_webhook",
|
||||||
|
"x-fern-examples": [{"code-samples": [{"sdk": "python", "code": RETRY_RUN_WEBHOOK_CODE_SAMPLE}]}],
|
||||||
|
},
|
||||||
|
description="Retry sending the webhook for a run",
|
||||||
|
summary="Retry run webhook",
|
||||||
|
)
|
||||||
|
@base_router.post("/runs/{run_id}/retry_webhook/", include_in_schema=False)
|
||||||
|
async def retry_run_webhook(
|
||||||
|
run_id: str = Path(..., description="The id of the task run or the workflow run.", examples=["tsk_123", "wr_123"]),
|
||||||
|
current_org: Organization = Depends(org_auth_service.get_current_org),
|
||||||
|
x_api_key: Annotated[str | None, Header()] = None,
|
||||||
|
) -> None:
|
||||||
|
analytics.capture("skyvern-oss-agent-run-retry-webhook")
|
||||||
|
await run_service.retry_run_webhook(run_id, organization_id=current_org.organization_id, api_key=x_api_key)
|
||||||
|
|
||||||
|
|
||||||
################# Legacy Endpoints #################
|
################# Legacy Endpoints #################
|
||||||
@legacy_base_router.post(
|
@legacy_base_router.post(
|
||||||
"/webhook",
|
"/webhook",
|
||||||
@@ -1344,6 +1409,17 @@ async def get_workflow_run(
|
|||||||
response_model=list[Workflow],
|
response_model=list[Workflow],
|
||||||
include_in_schema=False,
|
include_in_schema=False,
|
||||||
)
|
)
|
||||||
|
@base_router.get(
|
||||||
|
"/workflows",
|
||||||
|
response_model=list[Workflow],
|
||||||
|
tags=["Workflows"],
|
||||||
|
openapi_extra={
|
||||||
|
"x-fern-sdk-group-name": "workflows",
|
||||||
|
"x-fern-sdk-method-name": "get_workflows",
|
||||||
|
"x-fern-examples": [{"code-samples": [{"sdk": "python", "code": GET_WORKFLOWS_CODE_SAMPLE}]}],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
@base_router.get("/workflows/", response_model=list[Workflow], include_in_schema=False)
|
||||||
async def get_workflows(
|
async def get_workflows(
|
||||||
page: int = Query(1, ge=1),
|
page: int = Query(1, ge=1),
|
||||||
page_size: int = Query(10, ge=1),
|
page_size: int = Query(10, ge=1),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# Agent
|
||||||
RUN_TASK_CODE_SAMPLE = """from skyvern import Skyvern
|
RUN_TASK_CODE_SAMPLE = """from skyvern import Skyvern
|
||||||
|
|
||||||
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
||||||
@@ -19,6 +20,13 @@ CANCEL_RUN_CODE_SAMPLE = """from skyvern import Skyvern
|
|||||||
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
||||||
await skyvern.agent.cancel_run(run_id="tsk_v2_123")
|
await skyvern.agent.cancel_run(run_id="tsk_v2_123")
|
||||||
"""
|
"""
|
||||||
|
RETRY_RUN_WEBHOOK_CODE_SAMPLE = """from skyvern import Skyvern
|
||||||
|
|
||||||
|
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
||||||
|
await skyvern.agent.retry_run_webhook(run_id="tsk_v2_123")
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Workflows
|
||||||
CREATE_WORKFLOW_CODE_SAMPLE = """curl -X POST https://api.skyvern.com/v1/workflows \
|
CREATE_WORKFLOW_CODE_SAMPLE = """curl -X POST https://api.skyvern.com/v1/workflows \
|
||||||
--header 'x-api-key: {{x-api-key}}' \
|
--header 'x-api-key: {{x-api-key}}' \
|
||||||
--header 'Content-Type: text/plain' \
|
--header 'Content-Type: text/plain' \
|
||||||
@@ -353,6 +361,14 @@ DELETE_WORKFLOW_CODE_SAMPLE = """from skyvern import Skyvern
|
|||||||
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
||||||
await skyvern.workflows.delete_workflow(workflow_id="wpid_123")
|
await skyvern.workflows.delete_workflow(workflow_id="wpid_123")
|
||||||
"""
|
"""
|
||||||
|
GET_WORKFLOWS_CODE_SAMPLE = """from skyvern import Skyvern
|
||||||
|
|
||||||
|
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
||||||
|
workflows = await skyvern.workflows.get_workflows()
|
||||||
|
print(workflows)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Credentials
|
||||||
SEND_TOTP_CODE_CODE_SAMPLE = """from skyvern import Skyvern
|
SEND_TOTP_CODE_CODE_SAMPLE = """from skyvern import Skyvern
|
||||||
|
|
||||||
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
||||||
@@ -400,6 +416,9 @@ skyvern = Skyvern(api_key="YOUR_API_KEY")
|
|||||||
credentials = await skyvern.credentials.get_credentials()
|
credentials = await skyvern.credentials.get_credentials()
|
||||||
print(credentials)
|
print(credentials)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Browser Sessions
|
||||||
|
|
||||||
CREATE_BROWSER_SESSION_CODE_SAMPLE = """from skyvern import Skyvern
|
CREATE_BROWSER_SESSION_CODE_SAMPLE = """from skyvern import Skyvern
|
||||||
|
|
||||||
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
skyvern = Skyvern(api_key="YOUR_API_KEY")
|
||||||
|
|||||||
@@ -137,3 +137,40 @@ async def cancel_run(run_id: str, organization_id: str | None = None, api_key: s
|
|||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail=f"Invalid run type to cancel: {run.task_run_type}",
|
detail=f"Invalid run type to cancel: {run.task_run_type}",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def retry_run_webhook(run_id: str, organization_id: str | None = None, api_key: str | None = None) -> None:
|
||||||
|
"""Retry sending the webhook for a run."""
|
||||||
|
|
||||||
|
run = await app.DATABASE.get_run(run_id, organization_id=organization_id)
|
||||||
|
if not run:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Run not found {run_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
if run.task_run_type in [RunType.task_v1, RunType.openai_cua, RunType.anthropic_cua]:
|
||||||
|
task = await app.DATABASE.get_task(run_id, organization_id=organization_id)
|
||||||
|
if not task:
|
||||||
|
raise TaskNotFound(task_id=run_id)
|
||||||
|
latest_step = await app.DATABASE.get_latest_step(run_id, organization_id=organization_id)
|
||||||
|
if latest_step:
|
||||||
|
await app.agent.execute_task_webhook(task=task, last_step=latest_step, api_key=api_key)
|
||||||
|
elif run.task_run_type == RunType.task_v2:
|
||||||
|
task_v2 = await app.DATABASE.get_task_v2(run_id, organization_id=organization_id)
|
||||||
|
if not task_v2:
|
||||||
|
raise TaskNotFound(task_id=run_id)
|
||||||
|
await task_v2_service.send_task_v2_webhook(task_v2)
|
||||||
|
elif run.task_run_type == RunType.workflow_run:
|
||||||
|
workflow_run = await app.DATABASE.get_workflow_run(
|
||||||
|
workflow_run_id=run_id,
|
||||||
|
organization_id=organization_id,
|
||||||
|
)
|
||||||
|
if not workflow_run:
|
||||||
|
raise WorkflowRunNotFound(workflow_run_id=run_id)
|
||||||
|
await app.WORKFLOW_SERVICE.execute_workflow_webhook(workflow_run, api_key=api_key)
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=f"Invalid run type to retry webhook: {run.task_run_type}",
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user