You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2.9 KiB
2.9 KiB
REVIEW
Append-only review log. Each task section is appended or updated in place; prior task history is preserved.
T-001 — FastAPI backend (app.py) + inline HTML/JS frontend (requirements.txt)
Verdict: PASS_WITH_NOTES
Findings
- [minor]
app.py:147— On any failure insidedownload()(including yt-dlp errors),str(exc)is returned verbatim to the browser as themessagefield. yt-dlp exceptions can include local filesystem paths (the temp dir) or verbose internal detail. Not a required fix for this local/self-hosted tool, but consider mapping to a generic message (e.g. "The video could not be downloaded.") and logging the raw exception server-side instead, before this is exposed beyond local/dev use.- Required fix: No.
No blocker or major findings.
Verification
Steps performed:
- Re-read
.ai/PLAN.md(Phase 1 spec for T-001) and diffed it againstapp.py/requirements.txt. python -m py_compile app.py— succeeded.- Installed
fastapi,uvicorn,httpx,python-multipart,yt-dlpinto a scratch venv and exercised the app withstarlette.testclient.TestClient, mockingyt_dlp.YoutubeDLto avoid live network calls:GET /→ 200, body contains "Download MP3" and "Download Video".POST /downloadwith a garbage (non-http) URL → 400 JSON{"message": ...}.POST /downloadwith an empty URL → 400 JSON.POST /downloadmissing themodefield (triggersRequestValidationErrorhandler) → 400 JSON with.message.POST /downloadwith a valid URL, modemp3, mocked yt-dlp writing a fake file → 200, correct bytes streamed,Content-Disposition: attachment; filename="...", temp dir cleaned up viaBackgroundTask.POST /downloadwhere mocked yt-dlp raisesRuntimeError→ 500 JSON{"message": "..."}(no server crash), temp dir cleaned up on the error path.- Filename containing non-ASCII characters (e.g. "café mix 🎵.mp3") → correctly RFC 5987-encoded as
filename*=utf-8''...by Starlette; no crash or mojibake.
Findings from verification: All acceptance criteria for T-001 hold:
GET /returns 200 with HTML containing "Download MP3".POST /downloadwith a valid URL + mode streams a file.- Invalid URL returns 400 JSON with
.message.
Risks:
- No live network test against real YouTube was performed (would require external network access and a real video URL); mocked yt-dlp calls confirm the FastAPI plumbing (routing, form validation, error handling, file streaming, temp-dir cleanup) is correct, but do not confirm yt-dlp/ffmpeg behavior against a live video. This risk carries into the Docker-level validation planned for T-002 (
docker build+ smoke test), where a live download should be attempted at least once. - Large/long-running downloads have no timeout or size cap — acceptable for v1 per
ROADMAP.md(out of scope), but worth revisiting if this moves beyond local/dev use.