Skip to content

feat(python-sdk): add VideoOutput type and video support to MultimodalResponse (#469)#473

Merged
santoshkumarradha merged 2 commits intodev/add-videofrom
feat/469-video-output
Apr 18, 2026
Merged

feat(python-sdk): add VideoOutput type and video support to MultimodalResponse (#469)#473
santoshkumarradha merged 2 commits intodev/add-videofrom
feat/469-video-output

Conversation

@santoshkumarradha
Copy link
Copy Markdown
Member

Summary

  • Adds VideoOutput Pydantic model with save(), get_bytes(), and metadata fields (duration, resolution, aspect_ratio, has_audio, cost_usd)
  • Adds videos property, has_video property to MultimodalResponse
  • Updates is_multimodal, __repr__, save_all to include videos
  • Updates FalProvider.generate_video() to return both files (backward compat) and videos

DX

result = await app.ai_generate_video("A cat playing", model="fal-ai/minimax-video/image-to-video")
print(result.has_video)            # True
print(result.videos[0].duration)   # 8.0
await result.videos[0].save("cat.mp4")
print(result.has_file)             # Also True (backward compat)

Test plan

  • 5 TestVideoOutput tests (create, metadata, base64, save, error)
  • 5 TestMultimodalResponseVideo tests (has_video, is_multimodal, repr, backward compat)
  • Full test suite passes, ruff clean

Closes #469

@santoshkumarradha santoshkumarradha self-assigned this Apr 18, 2026
@santoshkumarradha santoshkumarradha requested review from a team and AbirAbbas as code owners April 18, 2026 08:45
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 18, 2026

Performance

SDK Memory Δ Latency Δ Tests Status
Python 7.9 KB -13% 0.56 µs +60%

✓ No regressions detected

…imeouts (#469)

- CRITICAL: sanitize filenames in save_all() via os.path.basename() to
  prevent path traversal from API-supplied filenames (videos + files)
- HIGH: export VideoOutput from __init__.py alongside other Output types
- HIGH: pass videos=[] in detect_multimodal_response() constructor call
- HIGH: add timeout=120 to requests.get() in VideoOutput.save/get_bytes
- MED: skip video mime_type files in the files save loop to avoid
  double-writes when videos appear in both _files and _videos
@santoshkumarradha santoshkumarradha merged commit 8ade081 into dev/add-video Apr 18, 2026
19 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

📊 Coverage gate

Thresholds from .coverage-gate.toml: per-surface ≥ 86%, aggregate ≥ 88%, max per-surface regression ≤ 1.0 pp, max aggregate regression ≤ 0.50 pp.

Surface Current Baseline Δ
control-plane 87.30% 87.30% → +0.00 pp 🟡
sdk-go 90.70% 90.70% → +0.00 pp 🟢
sdk-python 93.63% 93.63% ↑ +0.00 pp 🟢
sdk-typescript 92.56% 92.56% → +0.00 pp 🟢
web-ui 90.02% 90.01% ↑ +0.01 pp 🟢
aggregate 89.02% 89.01% ↑ +0.01 pp 🟡

✅ Gate passed

No surface regressed past the allowed threshold and the aggregate stayed above the floor.

@github-actions
Copy link
Copy Markdown
Contributor

📐 Patch coverage gate

Threshold: 80% on lines this PR touches vs origin/main (from .coverage-gate.toml:thresholds.min_patch).

Surface Touched lines Patch coverage Status
control-plane 0 ➖ no changes
sdk-go 0 ➖ no changes
sdk-python 0 ➖ no changes
sdk-typescript 0 ➖ no changes
web-ui 0 ➖ no changes

✅ Patch gate passed

Every surface whose lines were touched by this PR has patch coverage at or above the threshold.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant