Python 88.3%
TypeScript 7.6%
Shell 4.1%
1"""Videos API tests. List / retrieve / error shapes are free and always run; creation is gated by RUN_VIDEO_TESTS.2Videos API + Sora 2 models are scheduled for removal on 2026-09-24 — a 404/410 after that date is expected."""3from __future__ import annotations45import time67import pytest89TERMINAL = {"completed", "failed"}10STATES = {"queued", "in_progress"} | TERMINAL111213def test_list_videos(openai):14 st, body, _ = openai("GET", "/v1/videos?limit=2", note="test_video list (free)")15 if st in (404, 410):16 pytest.skip(f"Videos API answered {st} (scheduled shutdown 2026-09-24)")17 assert st == 200, body18 assert body["object"] == "list" and isinstance(body["data"], list) and "has_more" in body19 for v in body["data"]:20 assert v["object"] == "video" and v["status"] in STATES and v["id"].startswith("video")212223def test_retrieve_unknown_video_404(openai):24 st, body, _ = openai("GET", "/v1/videos/video_atlas_does_not_exist", note="test_video 404 shape (free)")25 if st == 410:26 pytest.skip("Videos API gone")27 assert st == 404, body28 assert body["error"]["type"] == "invalid_request_error" and "not found" in body["error"]["message"]293031def test_characters_has_no_list_operation(openai):32 st, body, _ = openai("GET", "/v1/videos/characters?limit=1", note="test_video characters list probe (free)")33 if st in (404, 410):34 pytest.skip("Videos API gone")35 assert st == 400 and body["error"]["param"] == "video_id"363738@pytest.mark.run_video_tests39def test_create_poll_video(openai):40 """~$0.40: 4 s sora-2 720p clip. Polls up to 15 min, then downloads the thumbnail."""41 st, job, _ = openai("POST", "/v1/videos", {"model": "sora-2", "prompt": "A simple blue geometric cube rotating on a white background.",42 "size": "720x1280", "seconds": "4"}, est_cost_usd=0.40, note="test_video create (RUN_VIDEO_TESTS)")43 assert st == 200, job44 assert job["object"] == "video" and job["status"] in STATES45 deadline = time.time() + 90046 while job["status"] not in TERMINAL and time.time() < deadline:47 time.sleep(15)48 st, job, _ = openai("GET", f"/v1/videos/{job['id']}", note="poll")49 assert st == 200, job50 assert job["status"] == "completed", job.get("error")51 st, content, hdrs = openai("GET", f"/v1/videos/{job['id']}/content?variant=thumbnail", note="download thumbnail")52 assert st == 200 and isinstance(content, bytes) and hdrs.get("Content-Type", "").startswith("image/")53