two more public endpoints: retry_run_webhook, get_artifact (#2445)

This commit is contained in:
Shuchang Zheng
2025-05-24 00:24:56 -07:00
committed by GitHub
parent d277a03b80
commit b8b3821bc9
3 changed files with 132 additions and 0 deletions

View File

@@ -29,6 +29,8 @@ from skyvern.forge.sdk.routes.code_samples import (
CREATE_WORKFLOW_CODE_SAMPLE_PYTHON,
DELETE_WORKFLOW_CODE_SAMPLE,
GET_RUN_CODE_SAMPLE,
GET_WORKFLOWS_CODE_SAMPLE,
RETRY_RUN_WEBHOOK_CODE_SAMPLE,
RUN_TASK_CODE_SAMPLE,
RUN_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)
@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_base_router.post(
"/webhook",
@@ -1344,6 +1409,17 @@ async def get_workflow_run(
response_model=list[Workflow],
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(
page: int = Query(1, ge=1),
page_size: int = Query(10, ge=1),

View File

@@ -1,3 +1,4 @@
# Agent
RUN_TASK_CODE_SAMPLE = """from skyvern import Skyvern
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")
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 \
--header 'x-api-key: {{x-api-key}}' \
--header 'Content-Type: text/plain' \
@@ -353,6 +361,14 @@ DELETE_WORKFLOW_CODE_SAMPLE = """from skyvern import Skyvern
skyvern = Skyvern(api_key="YOUR_API_KEY")
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
skyvern = Skyvern(api_key="YOUR_API_KEY")
@@ -400,6 +416,9 @@ skyvern = Skyvern(api_key="YOUR_API_KEY")
credentials = await skyvern.credentials.get_credentials()
print(credentials)
"""
# Browser Sessions
CREATE_BROWSER_SESSION_CODE_SAMPLE = """from skyvern import Skyvern
skyvern = Skyvern(api_key="YOUR_API_KEY")

View File

@@ -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,
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}",
)