{
"page_id": "71848",
"language_code": "en",
"content": "# canvas_app.py\n\n---\n\n## Overview\n\ncanvas_app.py is a Flask-based API module that manages "canvas" resources within the InfiniFlow system. A canvas here represents a user-configurable workflow or data processing pipeline, described using a domain-specific language (DSL). This module provides RESTful endpoints to create, retrieve, update, delete, and run canvases, manage their versions, upload related files, perform debugging, and handle related auxiliary operations such as database connection testing and log tracing.\n\nThe API enforces user authentication and authorization, ensuring users can only modify or access canvases they own or have permissions for. It also integrates with various backend services and utilities, including user management, file handling, versioning, and external crawling tools.\n\n---\n\n## Detailed Components\n\n### Flask Blueprint: manager\n\nAll routes are decorated on an object manager, assumed to be a Flask blueprint or app instance (not shown in this file). Each route corresponds to a REST API endpoint.\n\n---\n\n### Endpoints\n\n#### 1. /templates - GET\n\n* Description: Fetches all canvas templates categorized under CanvasCategory.Agent.\n\n* Authentication: Required (@login_required).\n\n* Response: JSON list of canvas templates.\n\n* Usage Example:\n\nhttp\nGET /templates\nAuthorization: Bearer <token>\n\n\n\n---\n\n#### 2. /list - GET\n\n* Description: Lists all canvases owned by the current user in the CanvasCategory.Agent category, sorted by last update time descending.\n\n* Authentication: Required.\n\n* Response: JSON list of canvases.\n\n---\n\n#### 3. /rm - POST\n\n* Description: Deletes canvases specified by their IDs.\n\n* Parameters: JSON body with \"canvas_ids\": [id1, id2, ...].\n\n* Authorization: Only the owner of each canvas can delete.\n\n* Response: Success boolean.\n\n* Errors: Returns operating error if unauthorized.\n\n---\n\n#### 4. /set - POST\n\n* Description: Creates or updates a canvas.\n\n* Parameters:\n\n * dsl (string or JSON): The DSL describing the canvas.\n\n * title (string): The canvas title.\n\n * Optional id (string): If provided, updates existing canvas; else creates new.\n\n* Behavior:\n\n * Validates uniqueness of title on creation.\n\n * Saves a version snapshot after save/update.\n\n * Deletes all old versions after saving a new one (likely to keep only the latest).\n\n* Returns: The saved canvas data.\n\n* Errors: Unauthorized access or duplicate title.\n\n---\n\n#### 5. /get/<canvas_id> - GET\n\n* Description: Retrieves a canvas by ID.\n\n* Authorization: Only accessible by owner.\n\n* Response: Canvas data JSON.\n\n---\n\n#### 6. /getsse/<canvas_id> - GET\n\n* Description: Retrieves canvas data using API token authentication (via Authorization header).\n\n* Response: Canvas data if token is valid and owner matches.\n\n* Errors: Invalid token or not owner.\n\n---\n\n#### 7. /completion - POST\n\n* Description: Runs the canvas with a query and optional files/inputs, returning a Server-Sent Events (SSE) stream of results.\n\n* Parameters: JSON body with:\n\n * id: canvas ID.\n\n * query: query string.\n\n * files: list of files.\n\n * inputs: dictionary of additional inputs.\n\n * Optional user_id.\n\n* Authorization: Owner only.\n\n* Implementation Details:\n\n * Instantiates a Canvas object with the DSL.\n\n * Runs canvas.run() generator yielding partial results.\n\n * Updates canvas DSL after run.\n\n* Response: SSE stream with JSON data packets.\n\n---\n\n#### 8. /reset - POST\n\n* Description: Resets the state of a canvas to its initial state.\n\n* Parameters: JSON with id (canvas ID).\n\n* Returns: Updated DSL after reset.\n\n* Authorization: Owner only.\n\n---\n\n#### 9. /upload/<canvas_id> - POST\n\n* Description: Uploads a file or fetches content from a URL to associate with a canvas.\n\n* Parameters:\n\n * Multipart form file upload or URL query parameter.\n\n* Behavior:\n\n * If URL provided, uses crawl4ai async crawler to download page or PDF.\n\n * Files are stored via FileService.put_blob.\n\n * PDF files are preprocessed to handle broken PDFs.\n\n* Response: Metadata about the uploaded file.\n\n---\n\n#### 10. /input_form - GET\n\n* Description: Retrieves the input form schema for a specific component in a canvas.\n\n* Parameters: Query parameters id (canvas ID), component_id.\n\n* Authorization: Owner only.\n\n* Response: JSON describing the component input form.\n\n---\n\n#### 11. /debug - POST\n\n* Description: Debugs a specific component in a canvas with provided parameters.\n\n* Parameters: JSON with id (canvas ID), component_id, and params (component inputs).\n\n* Behavior: Resets component, sets debug inputs (if LLM type), invokes component, and returns outputs.\n\n* Authorization: Owner only.\n\n* Response: Output data from component invocation.\n\n---\n\n#### 12. /test_db_connect - POST\n\n* Description: Tests connectivity to various supported databases.\n\n* Parameters: JSON with db_type, database, username, host, port, password.\n\n* Supported DBs: MySQL, MariaDB, PostgreSQL (identified as \"postgres\"), MSSQL.\n\n* Response: Success message or error.\n\n* Usage: Useful to validate DB credentials before configuration.\n\n---\n\n#### 13. /getlistversion/<canvas_id> - GET\n\n* Description: Lists all saved versions of a canvas DSL, sorted by update time descending.\n\n* Authorization: Owner only.\n\n* Response: List of version metadata.\n\n---\n\n#### 14. /getversion/<version_id> - GET\n\n* Description: Retrieves a specific version of a canvas DSL by version ID.\n\n* Authorization: Owner only.\n\n---\n\n#### 15. /listteam - GET\n\n* Description: Lists canvases accessible by the current user across their tenants/teams.\n\n* Parameters: Supports pagination, ordering, keyword filtering.\n\n* Authorization: User must be part of tenant.\n\n* Response: Paginated list of canvases and total count.\n\n---\n\n#### 16. /setting - POST\n\n* Description: Updates canvas settings such as title, description, permission, avatar.\n\n* Parameters: JSON with id, title, permission, optionally others.\n\n* Authorization: Owner only.\n\n* Response: Number of updated records (typically 1).\n\n---\n\n#### 17. /trace - GET\n\n* Description: Retrieves logs associated with a canvas and message ID from Redis.\n\n* Parameters: Query canvas_id and message_id.\n\n* Response: JSON log data or empty dict if none.\n\n---\n\n#### 18. /<canvas_id>/sessions - GET\n\n* Description: Retrieves conversation sessions associated with a canvas.\n\n* Parameters: Pagination, filtering by user, keywords, date range, ordering, and whether to include DSL.\n\n* Authorization: Owner only.\n\n* Response: Total count and list of sessions.\n\n---\n\n#### 19. /prompts - GET\n\n* Description: Returns predefined prompt templates used in various canvas-related tasks.\n\n* Authorization: Required.\n\n* Response: Dictionary of prompt strings (task analysis, plan generation, reflection, citation guidelines).\n\n---\n\n## Important Implementation Details\n\n* Authorization Checks: Most endpoints verify ownership using UserCanvasService.accessible() before allowing modifications or access.\n\n* Canvas DSL Handling: Canvases' DSLs are stored as JSON strings or dicts. The code ensures consistent JSON format when saving or loading.\n\n* Versioning: Each save operation records a new version with timestamped title. Old versions are deleted after save — this might be intended for pruning but could imply only one version is kept.\n\n* Streaming Responses: The /completion endpoint streams results back to the client using Server-Sent Events (SSE) for real-time updates.\n\n* File Handling: Supports both direct file uploads and URL-based content crawling with async web crawling (crawl4ai).\n\n* Database Support: Supports connection testing for multiple DB types including MySQL, MariaDB, PostgreSQL (using postgres as identifier), and MSSQL.\n\n* Redis Usage: Logs for canvas runs are stored and retrieved from Redis cache.\n\n* Exception Handling: Most endpoints catch exceptions and return error responses consistently using utility functions like server_error_response().\n\n---\n\n## Interaction with Other System Components\n\n* Canvas DSL & Execution: Uses the Canvas class (from agent.canvas) to instantiate and run canvas workflows.\n\n* Database Services: Interacts heavily with backend services (UserCanvasService, CanvasTemplateService, UserCanvasVersionService, API4ConversationService, TenantService, etc.) for CRUD operations on canvases and users.\n\n* File Services: Uses FileService and DocumentService for file storage and validation.\n\n* Authentication: Uses flask_login for user session management.\n\n* Async Crawling: Integrates with crawl4ai for fetching external web content as canvas inputs.\n\n* Redis: Uses Redis connection REDIS_CONN for caching logs.\n\n* API Token Authentication: Supports API token based canvas access for non-interactive clients.\n\n---\n\n## Usage Examples\n\n### Create a New Canvas\n\nhttp\nPOST /set\nAuthorization: Bearer <token>\nContent-Type: application/json\n\n{\n \"dsl\": \"{\\\"nodes\\\":[],\\\"edges\\\":[]}\",\n \"title\": \"My New Canvas\"\n}\n\n\n\n### Run a Canvas and Stream Results\n\nhttp\nPOST /completion\nAuthorization: Bearer <token>\nContent-Type: application/json\n\n{\n \"id\": \"canvas-uuid\",\n \"query\": \"Analyze sales data\",\n \"files\": [],\n \"inputs\": {}\n}\n\n\n\nResponse will be a streaming SSE:\n\n\ndata: {\"progress\": 10, \"result\": \"Step 1 output\"}\ndata: {\"progress\": 50, \"result\": \"Step 2 output\"}\n...\n\n\n\n### Upload a File\n\nhttp\nPOST /upload/<canvas_id>\nAuthorization: Bearer <token>\nContent-Type: multipart/form-data\n\nfile: <binary PDF or other file>\n\n\n\n---\n\n## Mermaid Class Diagram\n\nmermaid\nclassDiagram\n class Canvas {\n +__init__(dsl: str, user_id: str, canvas_id: str = None)\n +run(query: str, files: list, user_id: str, inputs: dict) generator\n +reset()\n +get_component(component_id: str)\n +get_component_input_form(component_id: str)\n +__str__()\n }\n\n class UserCanvasService {\n +query(user_id: str, canvas_category: CanvasCategory, id: str = None)\n +accessible(canvas_id: str, user_id: str) bool\n +save(**kwargs) bool\n +update_by_id(canvas_id: str, data: dict) int\n +delete_by_id(canvas_id: str)\n +get_by_id(canvas_id: str) (bool, Canvas)\n +get_by_tenant_id(canvas_id: str) (bool, Canvas)\n +get_by_tenant_ids(tenant_ids: list, user_id: str, page: int, page_size: int, orderby: str, desc: bool, keywords: str, canvas_category: CanvasCategory)\n }\n\n class UserCanvasVersionService {\n +insert(user_canvas_id: str, dsl: dict, title: str)\n +delete_all_versions(user_canvas_id: str)\n +list_by_canvas_id(canvas_id: str) list\n +get_by_id(version_id: str) (bool, CanvasVersion)\n }\n\n class FileService {\n +put_blob(user_id: str, location: str, blob: bytes)\n }\n\n class DocumentService {\n +check_doc_health(user_id: str, filename: str)\n }\n\n Canvas ..> UserCanvasService : uses\n Canvas ..> UserCanvasVersionService : versioning\n Canvas ..> FileService : file uploads\n Canvas ..> DocumentService : file validation\n\n\n\n---\n\n## Summary\n\ncanvas_app.py is the core REST API module managing canvases — user-defined processing workflows — within the InfiniFlow platform. It provides comprehensive endpoints for lifecycle management, execution, versioning, file handling, debugging, and monitoring. The module tightly integrates with backend services for persistence and user management, employs strong authorization, and supports real-time streaming and async content fetching to provide a rich, interactive user experience.\n\n---\n\nIf you require further details or example code snippets for specific endpoints or components, please ask!"
}