Rename old router to legacy_base_router (#2048)

Co-authored-by: Suchintan Singh <suchintansingh@gmail.com>
This commit is contained in:
Shuchang Zheng
2025-03-30 23:57:54 -07:00
committed by GitHub
parent 0107054a75
commit 83ad2adabd
15 changed files with 412 additions and 476 deletions

View File

@@ -18,9 +18,7 @@ from skyvern.forge import app as forge_app
from skyvern.forge.sdk.core import skyvern_context
from skyvern.forge.sdk.core.skyvern_context import SkyvernContext
from skyvern.forge.sdk.db.exceptions import NotFoundError
from skyvern.forge.sdk.routes.agent_protocol import base_router, official_api_router, v2_router
from skyvern.forge.sdk.routes.streaming import websocket_router
from skyvern.forge.sdk.routes.totp import totp_router
from skyvern.forge.sdk.routes.routers import base_router, legacy_base_router, legacy_v2_router
LOG = structlog.get_logger()
@@ -66,11 +64,9 @@ def get_agent_app() -> FastAPI:
allow_headers=["*"],
)
app.include_router(official_api_router, prefix="/v1")
app.include_router(base_router, prefix="/api/v1")
app.include_router(v2_router, prefix="/api/v2")
app.include_router(websocket_router, prefix="/api/v1/stream")
app.include_router(totp_router, prefix="/api/v1/totp")
app.include_router(base_router, prefix="/v1")
app.include_router(legacy_base_router, prefix="/api/v1")
app.include_router(legacy_v2_router, prefix="/api/v2")
app.openapi = custom_openapi
app.add_middleware(

View File

@@ -0,0 +1,4 @@
from skyvern.forge.sdk.routes import agent_protocol # noqa: F401
from skyvern.forge.sdk.routes import browser_sessions # noqa: F401
from skyvern.forge.sdk.routes import streaming # noqa: F401
from skyvern.forge.sdk.routes import totp # noqa: F401

View File

@@ -6,18 +6,7 @@ from typing import Annotated, Any
import structlog
import yaml
from fastapi import (
APIRouter,
BackgroundTasks,
Depends,
Header,
HTTPException,
Query,
Request,
Response,
UploadFile,
status,
)
from fastapi import BackgroundTasks, Depends, Header, HTTPException, Query, Request, Response, UploadFile, status
from fastapi.responses import ORJSONResponse
from skyvern import analytics
@@ -33,6 +22,7 @@ from skyvern.forge.sdk.core.security import generate_skyvern_signature
from skyvern.forge.sdk.db.enums import OrganizationAuthTokenType
from skyvern.forge.sdk.executor.factory import AsyncExecutorFactory
from skyvern.forge.sdk.models import Step
from skyvern.forge.sdk.routes.routers import base_router, legacy_base_router, legacy_v2_router
from skyvern.forge.sdk.schemas.ai_suggestions import AISuggestionBase, AISuggestionRequest
from skyvern.forge.sdk.schemas.organizations import (
GetOrganizationAPIKeysResponse,
@@ -73,11 +63,6 @@ from skyvern.forge.sdk.workflow.models.yaml import WorkflowCreateYAMLRequest
from skyvern.schemas.runs import RunEngine, RunResponse, RunType, TaskRunRequest, TaskRunResponse
from skyvern.services import run_service, task_v1_service, task_v2_service
from skyvern.webeye.actions.actions import Action
from skyvern.webeye.schemas import BrowserSessionResponse
official_api_router = APIRouter()
base_router = APIRouter()
v2_router = APIRouter()
LOG = structlog.get_logger()
@@ -103,15 +88,16 @@ class AISuggestionType(str, Enum):
DATA_SCHEMA = "data_schema"
@base_router.post(
@legacy_base_router.post(
"/webhook",
tags=["server"],
openapi_extra={
"x-fern-sdk-group-name": "server",
"x-fern-sdk-method-name": "webhook",
},
include_in_schema=False,
)
@base_router.post("/webhook/", include_in_schema=False)
@legacy_base_router.post("/webhook/", include_in_schema=False)
async def webhook(
request: Request,
x_skyvern_signature: Annotated[str | None, Header()] = None,
@@ -148,7 +134,7 @@ async def webhook(
return Response(content="webhook validation", status_code=200)
@base_router.get(
@legacy_base_router.get(
"/heartbeat",
tags=["server"],
openapi_extra={
@@ -156,7 +142,7 @@ async def webhook(
"x-fern-sdk-method-name": "heartbeat",
},
)
@base_router.get("/heartbeat/", include_in_schema=False)
@legacy_base_router.get("/heartbeat/", include_in_schema=False)
async def heartbeat() -> Response:
"""
Check if the server is running.
@@ -164,7 +150,7 @@ async def heartbeat() -> Response:
return Response(content="Server is running.", status_code=200)
@base_router.post(
@legacy_base_router.post(
"/tasks",
tags=["agent"],
response_model=CreateTaskResponse,
@@ -173,7 +159,7 @@ async def heartbeat() -> Response:
"x-fern-sdk-method-name": "run_task_v1",
},
)
@base_router.post(
@legacy_base_router.post(
"/tasks/",
response_model=CreateTaskResponse,
include_in_schema=False,
@@ -200,7 +186,7 @@ async def run_task_v1(
return CreateTaskResponse(task_id=created_task.task_id)
@base_router.get(
@legacy_base_router.get(
"/tasks/{task_id}",
tags=["agent"],
response_model=TaskResponse,
@@ -209,7 +195,7 @@ async def run_task_v1(
"x-fern-sdk-method-name": "get_task_v1",
},
)
@base_router.get("/tasks/{task_id}/", response_model=TaskResponse, include_in_schema=False)
@legacy_base_router.get("/tasks/{task_id}/", response_model=TaskResponse, include_in_schema=False)
async def get_task_v1(
task_id: str,
current_org: Organization = Depends(org_auth_service.get_current_org),
@@ -248,7 +234,7 @@ async def get_task_v1(
)
@base_router.post(
@legacy_base_router.post(
"/tasks/{task_id}/cancel",
tags=["agent"],
openapi_extra={
@@ -256,7 +242,7 @@ async def get_task_v1(
"x-fern-sdk-method-name": "cancel_task",
},
)
@base_router.post("/tasks/{task_id}/cancel/", include_in_schema=False)
@legacy_base_router.post("/tasks/{task_id}/cancel/", include_in_schema=False)
async def cancel_task(
task_id: str,
current_org: Organization = Depends(org_auth_service.get_current_org),
@@ -276,7 +262,7 @@ async def cancel_task(
await app.agent.execute_task_webhook(task=task, last_step=latest_step, api_key=x_api_key)
@base_router.post(
@legacy_base_router.post(
"/workflows/runs/{workflow_run_id}/cancel",
tags=["agent"],
openapi_extra={
@@ -284,7 +270,7 @@ async def cancel_task(
"x-fern-sdk-method-name": "cancel_workflow_run",
},
)
@base_router.post("/workflows/runs/{workflow_run_id}/cancel/", include_in_schema=False)
@legacy_base_router.post("/workflows/runs/{workflow_run_id}/cancel/", include_in_schema=False)
async def cancel_workflow_run(
workflow_run_id: str,
current_org: Organization = Depends(org_auth_service.get_current_org),
@@ -316,7 +302,7 @@ async def cancel_workflow_run(
await app.WORKFLOW_SERVICE.execute_workflow_webhook(workflow_run, api_key=x_api_key)
@base_router.post(
@legacy_base_router.post(
"/tasks/{task_id}/retry_webhook",
tags=["agent"],
response_model=TaskResponse,
@@ -325,7 +311,7 @@ async def cancel_workflow_run(
"x-fern-sdk-method-name": "retry_webhook",
},
)
@base_router.post(
@legacy_base_router.post(
"/tasks/{task_id}/retry_webhook/",
response_model=TaskResponse,
include_in_schema=False,
@@ -354,7 +340,7 @@ async def retry_webhook(
return await app.agent.build_task_response(task=task_obj, last_step=latest_step)
@base_router.get(
@legacy_base_router.get(
"/tasks",
tags=["agent"],
response_model=list[Task],
@@ -363,7 +349,7 @@ async def retry_webhook(
"x-fern-sdk-method-name": "get_tasks",
},
)
@base_router.get(
@legacy_base_router.get(
"/tasks/",
response_model=list[Task],
include_in_schema=False,
@@ -411,7 +397,7 @@ async def get_tasks(
return ORJSONResponse([(await app.agent.build_task_response(task=task)).model_dump() for task in tasks])
@base_router.get(
@legacy_base_router.get(
"/runs",
tags=["agent"],
response_model=list[WorkflowRun | Task],
@@ -420,7 +406,7 @@ async def get_tasks(
"x-fern-sdk-method-name": "get_runs",
},
)
@base_router.get(
@legacy_base_router.get(
"/runs/",
response_model=list[WorkflowRun | Task],
include_in_schema=False,
@@ -441,7 +427,7 @@ async def get_runs(
return ORJSONResponse([run.model_dump() for run in runs])
@official_api_router.get(
@base_router.get(
"/runs/{run_id}",
tags=["agent"],
response_model=RunResponse,
@@ -450,7 +436,7 @@ async def get_runs(
"x-fern-sdk-method-name": "get_run",
},
)
@official_api_router.get(
@base_router.get(
"/runs/{run_id}/",
response_model=RunResponse,
include_in_schema=False,
@@ -468,7 +454,7 @@ async def get_run(
return run_response
@base_router.get(
@legacy_base_router.get(
"/tasks/{task_id}/steps",
tags=["agent"],
response_model=list[Step],
@@ -477,7 +463,7 @@ async def get_run(
"x-fern-sdk-method-name": "get_steps",
},
)
@base_router.get(
@legacy_base_router.get(
"/tasks/{task_id}/steps/",
response_model=list[Step],
include_in_schema=False,
@@ -496,7 +482,7 @@ async def get_steps(
return ORJSONResponse([step.model_dump(exclude_none=True) for step in steps])
@base_router.get(
@legacy_base_router.get(
"/{entity_type}/{entity_id}/artifacts",
tags=["agent"],
response_model=list[Artifact],
@@ -505,7 +491,7 @@ async def get_steps(
"x-fern-sdk-method-name": "get_artifacts",
},
)
@base_router.get(
@legacy_base_router.get(
"/{entity_type}/{entity_id}/artifacts/",
response_model=list[Artifact],
include_in_schema=False,
@@ -560,7 +546,7 @@ async def get_artifacts(
return ORJSONResponse([artifact.model_dump() for artifact in artifacts])
@base_router.get(
@legacy_base_router.get(
"/tasks/{task_id}/steps/{step_id}/artifacts",
tags=["agent"],
response_model=list[Artifact],
@@ -569,7 +555,7 @@ async def get_artifacts(
"x-fern-sdk-method-name": "get_step_artifacts",
},
)
@base_router.get(
@legacy_base_router.get(
"/tasks/{task_id}/steps/{step_id}/artifacts/",
response_model=list[Artifact],
include_in_schema=False,
@@ -605,7 +591,7 @@ async def get_step_artifacts(
return ORJSONResponse([artifact.model_dump() for artifact in artifacts])
@base_router.get(
@legacy_base_router.get(
"/tasks/{task_id}/actions",
response_model=list[Action],
tags=["agent"],
@@ -614,7 +600,7 @@ async def get_step_artifacts(
"x-fern-sdk-method-name": "get_actions",
},
)
@base_router.get(
@legacy_base_router.get(
"/tasks/{task_id}/actions/",
response_model=list[Action],
include_in_schema=False,
@@ -628,7 +614,7 @@ async def get_actions(
return actions
@base_router.post(
@legacy_base_router.post(
"/workflows/{workflow_id}/run",
response_model=RunWorkflowResponse,
tags=["agent"],
@@ -637,7 +623,7 @@ async def get_actions(
"x-fern-sdk-method-name": "run_workflow",
},
)
@base_router.post(
@legacy_base_router.post(
"/workflows/{workflow_id}/run/",
response_model=RunWorkflowResponse,
include_in_schema=False,
@@ -703,7 +689,7 @@ async def run_workflow(
)
@base_router.get(
@legacy_base_router.get(
"/workflows/runs",
response_model=list[WorkflowRun],
tags=["agent"],
@@ -712,7 +698,7 @@ async def run_workflow(
"x-fern-sdk-method-name": "get_workflow_runs",
},
)
@base_router.get(
@legacy_base_router.get(
"/workflows/runs/",
response_model=list[WorkflowRun],
include_in_schema=False,
@@ -732,7 +718,7 @@ async def get_workflow_runs(
)
@base_router.get(
@legacy_base_router.get(
"/workflows/{workflow_id}/runs",
response_model=list[WorkflowRun],
tags=["agent"],
@@ -741,7 +727,7 @@ async def get_workflow_runs(
"x-fern-sdk-method-name": "get_workflow_runs_by_id",
},
)
@base_router.get(
@legacy_base_router.get(
"/workflows/{workflow_id}/runs/",
response_model=list[WorkflowRun],
include_in_schema=False,
@@ -763,7 +749,7 @@ async def get_workflow_runs_by_id(
)
@base_router.get(
@legacy_base_router.get(
"/workflows/{workflow_id}/runs/{workflow_run_id}",
tags=["agent"],
openapi_extra={
@@ -771,7 +757,7 @@ async def get_workflow_runs_by_id(
"x-fern-sdk-method-name": "get_workflow_run_with_workflow_id",
},
)
@base_router.get(
@legacy_base_router.get(
"/workflows/{workflow_id}/runs/{workflow_run_id}/",
include_in_schema=False,
)
@@ -797,7 +783,7 @@ async def get_workflow_run_with_workflow_id(
return return_dict
@base_router.get(
@legacy_base_router.get(
"/workflows/{workflow_id}/runs/{workflow_run_id}/timeline",
tags=["agent"],
openapi_extra={
@@ -805,7 +791,7 @@ async def get_workflow_run_with_workflow_id(
"x-fern-sdk-method-name": "get_workflow_run_timeline",
},
)
@base_router.get(
@legacy_base_router.get(
"/workflows/{workflow_id}/runs/{workflow_run_id}/timeline/",
include_in_schema=False,
)
@@ -818,7 +804,7 @@ async def get_workflow_run_timeline(
return await _flatten_workflow_run_timeline(current_org.organization_id, workflow_run_id)
@base_router.get(
@legacy_base_router.get(
"/workflows/runs/{workflow_run_id}",
response_model=WorkflowRunResponse,
tags=["agent"],
@@ -827,7 +813,7 @@ async def get_workflow_run_timeline(
"x-fern-sdk-method-name": "get_workflow_run",
},
)
@base_router.get(
@legacy_base_router.get(
"/workflows/runs/{workflow_run_id}/",
response_model=WorkflowRunResponse,
include_in_schema=False,
@@ -843,7 +829,7 @@ async def get_workflow_run(
)
@base_router.post(
@legacy_base_router.post(
"/workflows",
openapi_extra={
"requestBody": {
@@ -856,7 +842,7 @@ async def get_workflow_run(
response_model=Workflow,
tags=["agent"],
)
@base_router.post(
@legacy_base_router.post(
"/workflows/",
openapi_extra={
"requestBody": {
@@ -890,7 +876,7 @@ async def create_workflow(
raise FailedToCreateWorkflow(str(e))
@base_router.put(
@legacy_base_router.put(
"/workflows/{workflow_permanent_id}",
openapi_extra={
"requestBody": {
@@ -903,7 +889,7 @@ async def create_workflow(
response_model=Workflow,
tags=["agent"],
)
@base_router.put(
@legacy_base_router.put(
"/workflows/{workflow_permanent_id}/",
openapi_extra={
"requestBody": {
@@ -945,7 +931,7 @@ async def update_workflow(
raise FailedToUpdateWorkflow(workflow_permanent_id, f"<{type(e).__name__}: {str(e)}>")
@base_router.delete(
@legacy_base_router.delete(
"/workflows/{workflow_permanent_id}",
tags=["agent"],
openapi_extra={
@@ -953,7 +939,7 @@ async def update_workflow(
"x-fern-sdk-method-name": "delete_workflow",
},
)
@base_router.delete("/workflows/{workflow_permanent_id}/", include_in_schema=False)
@legacy_base_router.delete("/workflows/{workflow_permanent_id}/", include_in_schema=False)
async def delete_workflow(
workflow_permanent_id: str,
current_org: Organization = Depends(org_auth_service.get_current_org),
@@ -962,7 +948,7 @@ async def delete_workflow(
await app.WORKFLOW_SERVICE.delete_workflow_by_permanent_id(workflow_permanent_id, current_org.organization_id)
@base_router.get(
@legacy_base_router.get(
"/workflows",
response_model=list[Workflow],
tags=["agent"],
@@ -971,7 +957,7 @@ async def delete_workflow(
"x-fern-sdk-method-name": "get_workflows",
},
)
@base_router.get(
@legacy_base_router.get(
"/workflows/",
response_model=list[Workflow],
include_in_schema=False,
@@ -1020,7 +1006,7 @@ async def get_workflows(
)
@base_router.get(
@legacy_base_router.get(
"/workflows/templates",
response_model=list[Workflow],
tags=["agent"],
@@ -1029,7 +1015,7 @@ async def get_workflows(
"x-fern-sdk-method-name": "get_workflow_templates",
},
)
@base_router.get(
@legacy_base_router.get(
"/workflows/templates/",
response_model=list[Workflow],
include_in_schema=False,
@@ -1048,7 +1034,7 @@ async def get_workflow_templates() -> list[Workflow]:
return workflows
@base_router.get(
@legacy_base_router.get(
"/workflows/{workflow_permanent_id}",
response_model=Workflow,
tags=["agent"],
@@ -1057,7 +1043,7 @@ async def get_workflow_templates() -> list[Workflow]:
"x-fern-sdk-method-name": "get_workflow",
},
)
@base_router.get("/workflows/{workflow_permanent_id}/", response_model=Workflow, include_in_schema=False)
@legacy_base_router.get("/workflows/{workflow_permanent_id}/", response_model=Workflow, include_in_schema=False)
async def get_workflow(
workflow_permanent_id: str,
version: int | None = None,
@@ -1076,7 +1062,7 @@ async def get_workflow(
)
@base_router.post(
@legacy_base_router.post(
"/suggest/{ai_suggestion_type}",
include_in_schema=False,
tags=["agent"],
@@ -1085,7 +1071,7 @@ async def get_workflow(
"x-fern-sdk-method-name": "suggest",
},
)
@base_router.post("/suggest/{ai_suggestion_type}/", include_in_schema=False)
@legacy_base_router.post("/suggest/{ai_suggestion_type}/", include_in_schema=False)
async def suggest(
ai_suggestion_type: AISuggestionType,
data: AISuggestionRequest,
@@ -1114,7 +1100,7 @@ async def suggest(
raise HTTPException(status_code=400, detail="Failed to suggest data schema. Please try again later.")
@base_router.post(
@legacy_base_router.post(
"/generate/task",
tags=["agent"],
openapi_extra={
@@ -1122,7 +1108,7 @@ async def suggest(
"x-fern-sdk-method-name": "generate_task",
},
)
@base_router.post("/generate/task/", include_in_schema=False)
@legacy_base_router.post("/generate/task/", include_in_schema=False)
async def generate_task(
data: GenerateTaskRequest,
current_org: Organization = Depends(org_auth_service.get_current_org),
@@ -1134,7 +1120,7 @@ async def generate_task(
)
@base_router.put(
@legacy_base_router.put(
"/organizations",
tags=["server"],
openapi_extra={
@@ -1142,7 +1128,7 @@ async def generate_task(
"x-fern-sdk-method-name": "update_organization",
},
)
@base_router.put(
@legacy_base_router.put(
"/organizations",
include_in_schema=False,
)
@@ -1156,7 +1142,7 @@ async def update_organization(
)
@base_router.get(
@legacy_base_router.get(
"/organizations",
tags=["server"],
openapi_extra={
@@ -1164,7 +1150,7 @@ async def update_organization(
"x-fern-sdk-method-name": "get_organizations",
},
)
@base_router.get(
@legacy_base_router.get(
"/organizations/",
include_in_schema=False,
)
@@ -1174,7 +1160,7 @@ async def get_organizations(
return GetOrganizationsResponse(organizations=[current_org])
@base_router.get(
@legacy_base_router.get(
"/organizations/{organization_id}/apikeys/",
tags=["server"],
openapi_extra={
@@ -1182,7 +1168,7 @@ async def get_organizations(
"x-fern-sdk-method-name": "get_api_keys",
},
)
@base_router.get(
@legacy_base_router.get(
"/organizations/{organization_id}/apikeys",
include_in_schema=False,
)
@@ -1215,7 +1201,7 @@ async def _validate_file_size(file: UploadFile) -> UploadFile:
return file
@base_router.post(
@legacy_base_router.post(
"/upload_file",
tags=["server"],
openapi_extra={
@@ -1223,7 +1209,7 @@ async def _validate_file_size(file: UploadFile) -> UploadFile:
"x-fern-sdk-method-name": "upload_file",
},
)
@base_router.post(
@legacy_base_router.post(
"/upload_file/",
include_in_schema=False,
)
@@ -1268,7 +1254,7 @@ async def upload_file(
)
@v2_router.post(
@legacy_v2_router.post(
"/tasks",
tags=["agent"],
openapi_extra={
@@ -1276,7 +1262,7 @@ async def upload_file(
"x-fern-sdk-method-name": "run_task_v2",
},
)
@v2_router.post(
@legacy_v2_router.post(
"/tasks/",
include_in_schema=False,
)
@@ -1327,7 +1313,7 @@ async def run_task_v2(
return task_v2.model_dump(by_alias=True)
@v2_router.get(
@legacy_v2_router.get(
"/tasks/{task_id}",
tags=["agent"],
openapi_extra={
@@ -1335,7 +1321,7 @@ async def run_task_v2(
"x-fern-sdk-method-name": "get_task_v2",
},
)
@v2_router.get(
@legacy_v2_router.get(
"/tasks/{task_id}/",
include_in_schema=False,
)
@@ -1349,102 +1335,6 @@ async def get_task_v2(
return task_v2.model_dump(by_alias=True)
@base_router.get(
"/browser_sessions/{browser_session_id}",
response_model=BrowserSessionResponse,
tags=["session"],
openapi_extra={
"x-fern-sdk-group-name": "session",
"x-fern-sdk-method-name": "get_browser_session",
},
)
@base_router.get(
"/browser_sessions/{browser_session_id}/",
response_model=BrowserSessionResponse,
include_in_schema=False,
)
async def get_browser_session(
browser_session_id: str,
current_org: Organization = Depends(org_auth_service.get_current_org),
) -> BrowserSessionResponse:
analytics.capture("skyvern-oss-agent-workflow-run-get")
browser_session = await app.PERSISTENT_SESSIONS_MANAGER.get_session(
browser_session_id,
current_org.organization_id,
)
if not browser_session:
raise HTTPException(status_code=404, detail=f"Browser session {browser_session_id} not found")
return BrowserSessionResponse.from_browser_session(browser_session)
@base_router.get(
"/browser_sessions",
response_model=list[BrowserSessionResponse],
tags=["session"],
openapi_extra={
"x-fern-sdk-group-name": "session",
"x-fern-sdk-method-name": "get_browser_sessions",
},
)
@base_router.get(
"/browser_sessions/",
response_model=list[BrowserSessionResponse],
include_in_schema=False,
)
async def get_browser_sessions(
current_org: Organization = Depends(org_auth_service.get_current_org),
) -> list[BrowserSessionResponse]:
"""Get all active browser sessions for the organization"""
analytics.capture("skyvern-oss-agent-browser-sessions-get")
browser_sessions = await app.PERSISTENT_SESSIONS_MANAGER.get_active_sessions(current_org.organization_id)
return [BrowserSessionResponse.from_browser_session(browser_session) for browser_session in browser_sessions]
@base_router.post(
"/browser_sessions",
response_model=BrowserSessionResponse,
tags=["session"],
openapi_extra={
"x-fern-sdk-group-name": "session",
"x-fern-sdk-method-name": "create_browser_session",
},
)
@base_router.post(
"/browser_sessions/",
response_model=BrowserSessionResponse,
include_in_schema=False,
)
async def create_browser_session(
current_org: Organization = Depends(org_auth_service.get_current_org),
) -> BrowserSessionResponse:
browser_session = await app.PERSISTENT_SESSIONS_MANAGER.create_session(current_org.organization_id)
return BrowserSessionResponse.from_browser_session(browser_session)
@base_router.post(
"/browser_sessions/{session_id}/close",
tags=["session"],
openapi_extra={
"x-fern-sdk-group-name": "session",
"x-fern-sdk-method-name": "close_browser_session",
},
)
@base_router.post(
"/browser_sessions/{session_id}/close/",
include_in_schema=False,
)
async def close_browser_session(
session_id: str,
current_org: Organization = Depends(org_auth_service.get_current_org),
) -> ORJSONResponse:
await app.PERSISTENT_SESSIONS_MANAGER.close_session(current_org.organization_id, session_id)
return ORJSONResponse(
content={"message": "Browser session closed"},
status_code=200,
media_type="application/json",
)
async def _flatten_workflow_run_timeline(organization_id: str, workflow_run_id: str) -> list[WorkflowRunTimeline]:
"""
Get the timeline workflow runs including the nested workflow runs in a flattened list
@@ -1494,15 +1384,21 @@ async def _flatten_workflow_run_timeline(organization_id: str, workflow_run_id:
return final_workflow_run_block_timeline
@official_api_router.post(
@base_router.post(
"/tasks",
tags=["agent"],
tags=["Agent"],
openapi_extra={
"x-fern-sdk-group-name": "agent",
"x-fern-sdk-method-name": "run_task",
},
description="Run a task",
summary="Run a task",
responses={
200: {"description": "Successfully run task"},
400: {"description": "Invalid agent engine"},
},
)
@official_api_router.post("/tasks/", include_in_schema=False)
@base_router.post("/tasks/", include_in_schema=False)
async def run_task(
request: Request,
background_tasks: BackgroundTasks,

View File

@@ -0,0 +1,165 @@
from fastapi import Depends, HTTPException
from fastapi.responses import ORJSONResponse
from skyvern import analytics
from skyvern.forge import app
from skyvern.forge.sdk.routes.routers import base_router, legacy_base_router
from skyvern.forge.sdk.schemas.organizations import Organization
from skyvern.forge.sdk.services import org_auth_service
from skyvern.webeye.schemas import BrowserSessionResponse
@base_router.get(
"/browser_sessions/{browser_session_id}",
response_model=BrowserSessionResponse,
tags=["Browser Sessions"],
openapi_extra={
"x-fern-sdk-group-name": "browser_session",
"x-fern-sdk-method-name": "get_browser_session",
},
description="Get details about a specific browser session by ID",
summary="Get browser session details",
responses={
200: {"description": "Successfully retrieved browser session details"},
404: {"description": "Browser session not found"},
401: {"description": "Unauthorized - Invalid or missing authentication"},
},
)
@legacy_base_router.get(
"/browser_sessions/{browser_session_id}",
response_model=BrowserSessionResponse,
tags=["session"],
openapi_extra={
"x-fern-sdk-group-name": "session",
"x-fern-sdk-method-name": "get_browser_session",
},
)
@legacy_base_router.get(
"/browser_sessions/{browser_session_id}/",
response_model=BrowserSessionResponse,
include_in_schema=False,
)
async def get_browser_session(
browser_session_id: str,
current_org: Organization = Depends(org_auth_service.get_current_org),
) -> BrowserSessionResponse:
analytics.capture("skyvern-oss-agent-browser-session-get")
browser_session = await app.PERSISTENT_SESSIONS_MANAGER.get_session(
browser_session_id,
current_org.organization_id,
)
if not browser_session:
raise HTTPException(status_code=404, detail=f"Browser session {browser_session_id} not found")
return BrowserSessionResponse.from_browser_session(browser_session)
@base_router.get(
"/browser_sessions",
response_model=list[BrowserSessionResponse],
tags=["Browser Sessions"],
openapi_extra={
"x-fern-sdk-group-name": "browser_session",
"x-fern-sdk-method-name": "get_browser_sessions",
},
description="Get all active browser sessions for the organization",
summary="Get all active browser sessions",
responses={
200: {"description": "Successfully retrieved all active browser sessions"},
401: {"description": "Unauthorized - Invalid or missing authentication"},
},
)
@legacy_base_router.get(
"/browser_sessions",
response_model=list[BrowserSessionResponse],
tags=["session"],
openapi_extra={
"x-fern-sdk-group-name": "browser_sessions",
"x-fern-sdk-method-name": "get_browser_sessions",
},
)
@legacy_base_router.get(
"/browser_sessions/",
response_model=list[BrowserSessionResponse],
include_in_schema=False,
)
async def get_browser_sessions(
current_org: Organization = Depends(org_auth_service.get_current_org),
) -> list[BrowserSessionResponse]:
"""Get all active browser sessions for the organization"""
analytics.capture("skyvern-oss-agent-browser-sessions-get")
browser_sessions = await app.PERSISTENT_SESSIONS_MANAGER.get_active_sessions(current_org.organization_id)
return [BrowserSessionResponse.from_browser_session(browser_session) for browser_session in browser_sessions]
@base_router.post(
"/browser_sessions",
response_model=BrowserSessionResponse,
tags=["Browser Sessions"],
openapi_extra={
"x-fern-sdk-group-name": "browser_session",
"x-fern-sdk-method-name": "create_browser_session",
},
description="Create a new browser session",
summary="Create a new browser session",
responses={
200: {"description": "Successfully created browser session"},
401: {"description": "Unauthorized - Invalid or missing authentication"},
},
)
@legacy_base_router.post(
"/browser_sessions",
response_model=BrowserSessionResponse,
tags=["Browser Sessions"],
openapi_extra={
"x-fern-sdk-group-name": "session",
"x-fern-sdk-method-name": "create_browser_session",
},
)
@legacy_base_router.post(
"/browser_sessions/",
response_model=BrowserSessionResponse,
include_in_schema=False,
)
async def create_browser_session(
current_org: Organization = Depends(org_auth_service.get_current_org),
) -> BrowserSessionResponse:
browser_session = await app.PERSISTENT_SESSIONS_MANAGER.create_session(current_org.organization_id)
return BrowserSessionResponse.from_browser_session(browser_session)
@base_router.post(
"/browser_sessions/{browser_session_id}/close",
tags=["Browser Sessions"],
openapi_extra={
"x-fern-sdk-group-name": "browser_session",
"x-fern-sdk-method-name": "close_browser_session",
},
description="Close a browser session",
summary="Close a browser session",
responses={
200: {"description": "Successfully closed browser session"},
401: {"description": "Unauthorized - Invalid or missing authentication"},
},
)
@legacy_base_router.post(
"/browser_sessions/{browser_session_id}/close",
tags=["Browser Sessions"],
openapi_extra={
"x-fern-sdk-group-name": "browser_session",
"x-fern-sdk-method-name": "close_browser_session",
},
)
@legacy_base_router.post(
"/browser_sessions/{browser_session_id}/close/",
include_in_schema=False,
)
async def close_browser_session(
browser_session_id: str,
current_org: Organization = Depends(org_auth_service.get_current_org),
) -> ORJSONResponse:
await app.PERSISTENT_SESSIONS_MANAGER.close_session(current_org.organization_id, browser_session_id)
return ORJSONResponse(
content={"message": "Browser session closed"},
status_code=200,
media_type="application/json",
)

View File

@@ -0,0 +1,5 @@
from fastapi import APIRouter
base_router = APIRouter()
legacy_base_router = APIRouter(include_in_schema=False)
legacy_v2_router = APIRouter(include_in_schema=False)

View File

@@ -3,21 +3,21 @@ import base64
from datetime import datetime
import structlog
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
from fastapi import WebSocket, WebSocketDisconnect
from pydantic import ValidationError
from websockets.exceptions import ConnectionClosedOK
from skyvern.forge import app
from skyvern.forge.sdk.routes.routers import legacy_base_router
from skyvern.forge.sdk.schemas.tasks import TaskStatus
from skyvern.forge.sdk.services.org_auth_service import get_current_org
from skyvern.forge.sdk.workflow.models.workflow import WorkflowRunStatus
LOG = structlog.get_logger()
websocket_router = APIRouter()
STREAMING_TIMEOUT = 300
@websocket_router.websocket("/tasks/{task_id}")
@legacy_base_router.websocket("/stream/tasks/{task_id}")
async def task_stream(
websocket: WebSocket,
task_id: str,
@@ -119,7 +119,7 @@ async def task_stream(
return
@websocket_router.websocket("/workflow_runs/{workflow_run_id}")
@legacy_base_router.websocket("/stream/workflow_runs/{workflow_run_id}")
async def workflow_run_streaming(
websocket: WebSocket,
workflow_run_id: str,

View File

@@ -1,25 +1,25 @@
import structlog
from fastapi import APIRouter, Depends, HTTPException
from fastapi import Depends, HTTPException
from skyvern.forge import app
from skyvern.forge.prompts import prompt_engine
from skyvern.forge.sdk.routes.routers import legacy_base_router
from skyvern.forge.sdk.schemas.organizations import Organization
from skyvern.forge.sdk.schemas.totp_codes import TOTPCode, TOTPCodeCreate
from skyvern.forge.sdk.services import org_auth_service
LOG = structlog.get_logger()
totp_router = APIRouter()
@totp_router.post(
"",
@legacy_base_router.post(
"/totp",
tags=["agent"],
openapi_extra={
"x-fern-sdk-group-name": "agent",
"x-fern-sdk-method-name": "send_totp_code",
},
)
@totp_router.post("/", include_in_schema=False)
@legacy_base_router.post("/totp/", include_in_schema=False)
async def send_totp_code(
data: TOTPCodeCreate, curr_org: Organization = Depends(org_auth_service.get_current_org)
) -> TOTPCode:

View File

@@ -3,6 +3,7 @@ from enum import StrEnum
from typing import Any, List
from pydantic import BaseModel, field_validator
from typing_extensions import deprecated
from skyvern.forge.sdk.schemas.files import FileInfo
from skyvern.forge.sdk.schemas.task_v2 import TaskV2
@@ -13,6 +14,7 @@ from skyvern.schemas.runs import ProxyLocation
from skyvern.utils.url_validators import validate_url
@deprecated("Use WorkflowRunRequest instead")
class WorkflowRequestBody(BaseModel):
data: dict[str, Any] | None = None
proxy_location: ProxyLocation | None = None
@@ -29,6 +31,7 @@ class WorkflowRequestBody(BaseModel):
return validate_url(url)
@deprecated("Use WorkflowRunResponse instead")
class RunWorkflowResponse(BaseModel):
workflow_id: str
workflow_run_id: str