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

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

  1. [minor] app.py:147 — On any failure inside download() (including yt-dlp errors), str(exc) is returned verbatim to the browser as the message field. 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 against app.py / requirements.txt.
  • python -m py_compile app.py — succeeded.
  • Installed fastapi, uvicorn, httpx, python-multipart, yt-dlp into a scratch venv and exercised the app with starlette.testclient.TestClient, mocking yt_dlp.YoutubeDL to avoid live network calls:
    • GET / → 200, body contains "Download MP3" and "Download Video".
    • POST /download with a garbage (non-http) URL → 400 JSON {"message": ...}.
    • POST /download with an empty URL → 400 JSON.
    • POST /download missing the mode field (triggers RequestValidationError handler) → 400 JSON with .message.
    • POST /download with a valid URL, mode mp3, mocked yt-dlp writing a fake file → 200, correct bytes streamed, Content-Disposition: attachment; filename="...", temp dir cleaned up via BackgroundTask.
    • POST /download where mocked yt-dlp raises RuntimeError → 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 /download with 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.