sim
sim copied to clipboard
feat(export): Add workflow export as standalone Python/FastAPI service
Summary
Adds the ability to export Sim Studio workflows as standalone, self-contained Python services that can be deployed independently via Docker, Railway, or any container platform.
Features
Multi-Provider LLM Support
- Anthropic: Claude 3/4 models (Opus, Sonnet, Haiku)
- OpenAI: GPT-4, GPT-4o, o1, o3 models
- Google: Gemini Pro, Gemini Flash models
- Automatic provider detection from model name
- Provider-specific API key environment variables
Supported Block Types
- Start/Trigger blocks
- Agent blocks (with multi-provider support)
- Function blocks (JavaScript transpiled to Python)
- Condition/Router blocks
- API blocks (HTTP requests)
- Loop blocks (for, forEach, while, doWhile)
- Variables blocks
- Response blocks
Export Validation
- Pre-export validation for unsupported block types
- Pre-export validation for unsupported providers
- Clear error messages shown to users before export fails
- Prevents silent failures with actionable feedback
Production Features
- FastAPI server with /execute, /health, /ready endpoints
- Rate limiting (configurable, default 60 req/min)
- Request size limits (configurable, default 10MB)
- Automatic retry with exponential backoff
- MCP tool support via official Python SDK
- File operation sandboxing (WORKSPACE_DIR)
- Docker and docker-compose configuration
- Environment variable management (.env, .env.example)
UI Integration
- "Export as Service" context menu option
- Single workflow export only (no bulk)
- User-friendly error alerts for validation failures
Files Changed
-
apps/sim/app/api/workflows/[id]/export-service/route.ts- API endpoint -
apps/sim/app/api/workflows/[id]/export-service/route.test.ts- 13 unit tests -
apps/sim/app/workspace/.../hooks/use-export-service.ts- React hook -
apps/sim/app/workspace/.../context-menu/context-menu.tsx- UI menu -
apps/sim/app/workspace/.../workflow-item/workflow-item.tsx- UI wiring
Testing
cd apps/sim && bun run vitest run "export-service"
# 13 tests passing
Usage
- Right-click workflow in sidebar
- Select "Export as Service"
- Extract ZIP and configure .env with API keys
- Run:
docker compose uporuvicorn main:app - Call:
POST /executewith workflow inputs
@aadamsx is attempting to deploy a commit to the Sim Team on Vercel.
A member of the Team first needs to authorize it.
Greptile Summary
This PR adds workflow export as standalone Python/FastAPI services, enabling users to deploy workflows independently via Docker or Railway.
Key Changes
- Export validation: Pre-export checks for unsupported block types (evaluator, code_interpreter) and providers (non-Anthropic/OpenAI/Google models) with user-friendly error messages
-
JavaScript to Python transpilation: Function blocks are transpiled at export time (not runtime) from JavaScript to Python, including operators (
===→==,&&→and), literals (null→None), and control structures - Multi-provider LLM support: Automatic provider detection from model names (claude → Anthropic, gpt/o1/o3 → OpenAI, gemini → Google) with provider-specific API key environment variables
- Production-ready service: FastAPI server with rate limiting (60 req/min default), request size limits (10MB default), automatic retry with exponential backoff, health/readiness endpoints, and file operation sandboxing
- MCP tool support: Official Python MCP SDK integration for tool execution via Streamable HTTP transport
-
Security: Decrypted API keys included in
.envfile with clear security warnings in README;.env.exampleprovided with masked values - UI integration: Single context menu item "Export as Service" (single workflow only, no bulk export) with permission checks
Tests
13 unit tests cover authentication, validation (unsupported blocks/providers), provider detection (Claude/GPT/o1/Gemini models), and error handling scenarios.
Confidence Score: 4/5
- This PR is safe to merge with minor considerations around user experience
- The implementation is well-tested with 13 passing unit tests, includes comprehensive validation, and follows established patterns. The code is production-ready with rate limiting, retries, and security considerations. Score is 4 (not 5) due to the use of
alert()for error messages instead of a toast system, which is noted in the code as a temporary solution. - No files require special attention - the implementation is solid across all changed files
Important Files Changed
| Filename | Overview |
|---|---|
| apps/sim/app/api/workflows/[id]/export-service/route.ts | Comprehensive export service API route with validation, transpilation, and ZIP generation - well-structured with proper error handling |
| apps/sim/app/api/workflows/[id]/export-service/route.test.ts | Thorough test coverage with 13 tests covering authentication, validation, provider detection, and error handling |
| apps/sim/app/workspace/[workspaceId]/w/hooks/use-export-service.ts | Clean React hook for export service with proper error handling and state management - uses alert() instead of toast system |
Sequence Diagram
sequenceDiagram
participant User
participant UI as Workflow Context Menu
participant Hook as useExportService
participant API as /api/workflows/[id]/export-service
participant DB as Database
participant Env as Environment Service
participant Zip as ZIP Generator
User->>UI: Right-click workflow
User->>UI: Select "Export as Service"
UI->>Hook: handleExportService()
Hook->>Hook: Check isExporting state
Hook->>API: GET /api/workflows/[id]/export-service
API->>API: Authenticate user/API key
API->>DB: Fetch workflow metadata
API->>API: Fetch workflow state (internal API)
API->>API: validateWorkflowForExport()
alt Validation fails
API-->>Hook: 400 Bad Request (unsupported blocks/providers)
Hook->>User: alert(errorMessage)
else Validation passes
API->>API: Fetch workflow variables
API->>Env: getEffectiveDecryptedEnv()
API->>API: preTranspileWorkflow() (JS → Python)
API->>Zip: Create ZIP with files
Note over Zip: workflow.json, .env, .env.example,<br/>main.py, executor.py, handlers/,<br/>Dockerfile, README.md
API-->>Hook: 200 OK (application/zip)
Hook->>Hook: Create blob URL
Hook->>User: Download ZIP file
Hook->>User: File download complete
end