feat: add MuAPI video generation tool#196
Conversation
📝 WalkthroughWalkthroughA new file ChangesMuApi Video Generation Tool
Sequence DiagramsequenceDiagram
participant Caller
participant MuApiVideoGenerationTool
participant muapi_ai as muapi.ai API
Caller->>MuApiVideoGenerationTool: text_to_video(prompt, save_at, duration, config)
MuApiVideoGenerationTool->>muapi_ai: POST /t2v-endpoint (_submit)
muapi_ai-->>MuApiVideoGenerationTool: {"request_id": "..."}
loop _poll until completed or timeout
MuApiVideoGenerationTool->>muapi_ai: GET /predictions/{request_id}
muapi_ai-->>MuApiVideoGenerationTool: {status, output: [url]}
end
MuApiVideoGenerationTool->>muapi_ai: GET output_url (download bytes)
muapi_ai-->>MuApiVideoGenerationTool: video bytes
MuApiVideoGenerationTool-->>Caller: {"status": "success", "video_path": save_at}
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/director/tools/muapi_video.py`:
- Around line 123-127: The _submit method directly accesses
resp.json()["request_id"] which will raise a raw KeyError if the key is missing
from the API response. Wrap the resp.json()["request_id"] access in a try-except
block to catch KeyError, and when caught, raise a more informative exception
that includes the actual response content to aid debugging. This will provide
clear context about what the API returned instead of the expected request_id.
- Around line 162-172: The exception handling in the video generation code is
losing the original traceback by re-raising a new Exception without preserving
the exception chain. Modify the raise statement in the except block (where the
message "Error generating video" is constructed) to use the `from e` syntax to
preserve the original exception context. Apply the same fix to the
`image_to_video` method (mentioned at line 202) where this issue also exists.
This ensures the full traceback is retained for better debugging.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: fda5b229-148f-4b43-aa38-9f0d6164ad14
📒 Files selected for processing (1)
backend/director/tools/muapi_video.py
| def _submit(self, endpoint: str, payload: dict) -> str: | ||
| """Submit a generation request and return the request_id.""" | ||
| resp = self.session.post(f"{self.BASE_URL}/{endpoint}", json=payload, timeout=30) | ||
| resp.raise_for_status() | ||
| return resp.json()["request_id"] |
There was a problem hiding this comment.
Handle missing request_id in API response.
If the API response doesn't contain the expected request_id key (e.g., due to an API change or unexpected error format), a raw KeyError is raised without context. Adding explicit handling improves debuggability.
Proposed fix
def _submit(self, endpoint: str, payload: dict) -> str:
"""Submit a generation request and return the request_id."""
resp = self.session.post(f"{self.BASE_URL}/{endpoint}", json=payload, timeout=30)
resp.raise_for_status()
- return resp.json()["request_id"]
+ data = resp.json()
+ if "request_id" not in data:
+ raise Exception(f"API response missing 'request_id': {data}")
+ return data["request_id"]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def _submit(self, endpoint: str, payload: dict) -> str: | |
| """Submit a generation request and return the request_id.""" | |
| resp = self.session.post(f"{self.BASE_URL}/{endpoint}", json=payload, timeout=30) | |
| resp.raise_for_status() | |
| return resp.json()["request_id"] | |
| def _submit(self, endpoint: str, payload: dict) -> str: | |
| """Submit a generation request and return the request_id.""" | |
| resp = self.session.post(f"{self.BASE_URL}/{endpoint}", json=payload, timeout=30) | |
| resp.raise_for_status() | |
| data = resp.json() | |
| if "request_id" not in data: | |
| raise Exception(f"API response missing 'request_id': {data}") | |
| return data["request_id"] |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/director/tools/muapi_video.py` around lines 123 - 127, The _submit
method directly accesses resp.json()["request_id"] which will raise a raw
KeyError if the key is missing from the API response. Wrap the
resp.json()["request_id"] access in a try-except block to catch KeyError, and
when caught, raise a more informative exception that includes the actual
response content to aid debugging. This will provide clear context about what
the API returned instead of the expected request_id.
| try: | ||
| request_id = self._submit(endpoint, payload) | ||
| video_url = self._poll(request_id) | ||
| video_data = requests.get(video_url, timeout=120) | ||
| video_data.raise_for_status() | ||
| with open(save_at, "wb") as f: | ||
| f.write(video_data.content) | ||
| except Exception as e: | ||
| raise Exception(f"Error generating video: {type(e).__name__}: {str(e)}") | ||
|
|
||
| return {"status": "success", "video_path": save_at} |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Preserve exception chain with raise ... from e.
The re-raised exception loses the original traceback, making debugging harder. Using exception chaining preserves the full context. The same issue applies to image_to_video (line 202).
Proposed fix for both methods
except Exception as e:
- raise Exception(f"Error generating video: {type(e).__name__}: {str(e)}")
+ raise Exception(f"Error generating video: {type(e).__name__}: {e}") from eApply to both line 170 and line 202.
🧰 Tools
🪛 Ruff (0.15.17)
[warning] 169-169: Do not catch blind exception: Exception
(BLE001)
[warning] 170-170: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
[warning] 170-170: Use explicit conversion flag
Replace with conversion flag
(RUF010)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/director/tools/muapi_video.py` around lines 162 - 172, The exception
handling in the video generation code is losing the original traceback by
re-raising a new Exception without preserving the exception chain. Modify the
raise statement in the except block (where the message "Error generating video"
is constructed) to use the `from e` syntax to preserve the original exception
context. Apply the same fix to the `image_to_video` method (mentioned at line
202) where this issue also exists. This ensures the full traceback is retained
for better debugging.
Source: Linters/SAST tools
Summary
Adds a new video generation tool backed by muapi.ai — a generative media API aggregator that provides unified access to 400+ models across multiple providers.
What this adds
backend/director/tools/muapi_video.py—MuApiVideoGenerationToolclass withtext_to_video()andimage_to_video()methodsfal_video.py,kling.py, etc.)Usage
Get an API key at muapi.ai/dashboard/api-keys.
Summary by CodeRabbit