manim_mcp / models.py
euler314's picture
Upload 19 files
626a57f verified
Raw
History Blame Contribute Delete
6.02 kB
"""
Pydantic models for request/response validation and OpenAPI schema generation
"""
from typing import Optional, Dict
from pydantic import BaseModel, Field
from datetime import datetime
class RenderRequest(BaseModel):
"""Request model for rendering Manim animations"""
code: str = Field(
...,
description="Python code containing Manim Scene class definition",
json_schema_extra={
"example": (
"from manim import *\n\n"
"class SquareToCircle(Scene):\n"
" def construct(self):\n"
" square = Square()\n"
" circle = Circle()\n"
" self.play(Transform(square, circle))\n"
" self.wait()"
)
}
)
quality: str = Field(
default="720p",
description="Quality preset for rendering",
json_schema_extra={
"enum": ["4k", "2k", "1080p", "720p", "480p"]
}
)
fps: Optional[int] = Field(
None,
description="Custom frames per second (overrides quality preset default)",
ge=1,
le=120,
json_schema_extra={
"example": 30
}
)
output_format: str = Field(
default="mp4",
description="Output video format(s). Use 'all' for MP4, GIF, and WebM",
json_schema_extra={
"enum": ["mp4", "gif", "webm", "all"]
}
)
scene_name: Optional[str] = Field(
None,
description="Specific Scene class name to render (required if code contains multiple scenes)",
json_schema_extra={
"example": "SquareToCircle"
}
)
class Config:
json_schema_extra = {
"example": {
"code": "from manim import *\n\nclass MyScene(Scene):\n def construct(self):\n text = Text('Hello, Manim!')\n self.play(Write(text))\n self.wait()",
"quality": "720p",
"fps": 30,
"output_format": "mp4",
"scene_name": "MyScene"
}
}
class RenderResponse(BaseModel):
"""Response model for render requests"""
request_id: str = Field(
...,
description="Unique identifier for this render request"
)
status: str = Field(
...,
description="Status of the render: 'success', 'error', or 'processing'",
json_schema_extra={
"enum": ["success", "error", "processing"]
}
)
message: str = Field(
...,
description="Human-readable status message"
)
urls: Optional[Dict[str, str]] = Field(
None,
description="URLs to download rendered video files (available when status is 'success')",
json_schema_extra={
"example": {
"mp4": "https://your-space.hf.space/media/abc123-def456/output.mp4",
"gif": "https://your-space.hf.space/media/abc123-def456/output.gif",
"webm": "https://your-space.hf.space/media/abc123-def456/output.webm"
}
}
)
expires_at: Optional[str] = Field(
None,
description="ISO 8601 timestamp when files will be automatically deleted (1 hour from creation)",
json_schema_extra={
"example": "2025-12-19T15:30:00Z"
}
)
error_details: Optional[str] = Field(
None,
description="Detailed error message and traceback (available when status is 'error')"
)
class Config:
json_schema_extra = {
"example": {
"request_id": "abc123-def456-789",
"status": "success",
"message": "Animation rendered successfully",
"urls": {
"mp4": "https://your-space.hf.space/media/abc123-def456-789/output.mp4"
},
"expires_at": "2025-12-19T15:30:00Z",
"error_details": None
}
}
class HealthResponse(BaseModel):
"""Response model for health check endpoint"""
status: str = Field(
...,
description="Overall system health status",
json_schema_extra={
"enum": ["healthy", "degraded", "unhealthy"]
}
)
manim_version: str = Field(
...,
description="Installed Manim version"
)
ffmpeg_available: bool = Field(
...,
description="Whether FFmpeg is available for video conversion"
)
disk_space_mb: Optional[float] = Field(
None,
description="Available disk space in megabytes"
)
active_renders: Optional[int] = Field(
None,
description="Number of currently active render processes"
)
class Config:
json_schema_extra = {
"example": {
"status": "healthy",
"manim_version": "0.18.1",
"ffmpeg_available": True,
"disk_space_mb": 5120.5,
"active_renders": 0
}
}
class StatusResponse(BaseModel):
"""Response model for checking render status"""
request_id: str = Field(
...,
description="Request ID being queried"
)
status: str = Field(
...,
description="Current status: 'ready', 'processing', 'not_found', or 'expired'",
json_schema_extra={
"enum": ["ready", "processing", "not_found", "expired"]
}
)
files_available: Optional[list[str]] = Field(
None,
description="List of available file formats (e.g., ['mp4', 'gif'])"
)
urls: Optional[Dict[str, str]] = Field(
None,
description="Download URLs for available files"
)
expires_at: Optional[str] = Field(
None,
description="ISO 8601 timestamp when files will be deleted"
)
log_tail: Optional[str] = Field(
None,
description="Recent log output for in-progress renders"
)