Download AGENTS.md from afluakd9/Video-downloader-CPU-basic: direct link, hf CLI and curl.
- Browser
- Download file 5.68 kB
-
https://huggingface.co/spaces/afluakd9/Video-downloader-CPU-basic/resolve/main/AGENTS.md
- Command line
-
hf download hf://spaces/afluakd9/Video-downloader-CPU-basic/AGENTS.md
-
curl -L -o AGENTS.md https://huggingface.co/spaces/afluakd9/Video-downloader-CPU-basic/resolve/main/AGENTS.md
AGENTS.md β ReClip Telegram Bot
Compact instruction file for OpenCode sessions working in this repository.
Project Overview
Self-hosted Telegram bot that downloads media from YouTube, TikTok, Instagram, and 1000+ other sites. Built from four Dockerized Python services:
| Service | Tech | Port | Role |
|---|---|---|---|
reclip/ |
Flask + yt-dlp | 8899 | Download engine with REST API |
bot/ |
python-telegram-bot + httpx | β | Telegram bot client |
dashboard/ |
FastAPI + aiosqlite + Jinja2 | 8080 | Admin panel with stats |
telegram-bot-api |
aiogram/telegram-bot-api | 8081 | Self-hosted Bot API for 2GB uploads |
Running Locally (No Docker)
Start services in this order β each needs its own terminal:
# 1. Reclip (download engine)
cd reclip
pip install flask yt-dlp
python app.py # listens on 8899
# 2. Dashboard (admin panel)
cd dashboard
pip install -r requirements.txt
ADMIN_PASSWORD=changeme DB_PATH=./reclip.db \
uvicorn main:create_app --factory --host 0.0.0.0 --port 8080
# 3. Bot (Telegram client)
cd bot
pip install -r requirements.txt
BOT_TOKEN=<token> RECLIP_URL=http://localhost:8899 \
DOWNLOADS_PATH=../reclip/downloads python bot.py
The bot waits up to 60s for the self-hosted Bot API server on startup. In Docker it talks to http://telegram-bot-api:8081; locally you need that container running too, or the bot will warn and start anyway (uploads >20MB will fail).
Running Tests
# Bot tests
cd bot
pip install -r requirements.txt
pip install pytest pytest-asyncio
python -m pytest tests/ -v
# Dashboard tests
cd dashboard
pip install -r requirements.txt
pip install pytest pytest-asyncio httpx
python -m pytest tests/ -v
Critical: Dashboard tests must set DB_PATH, ADMIN_PASSWORD, and SECRET_KEY before importing db.py or main.py. The test files do this via os.environ at the top of the file. If you add new dashboard test files, copy that pattern or imports will create the DB in the wrong place.
Architecture Notes
Reclip API Surface (reclip/app.py)
POST /api/infoβ returns title, thumbnail, duration, uploader, extractor, and available quality formatsPOST /api/downloadβ spawns a threaded yt-dlp download, returnsjob_idGET /api/status/<job_id>β returnsstatus(downloading|done|error), progress dict, file metadataGET /api/file/<job_id>β serves finished file as attachment
Bot β Dashboard Events (bot/event_client.py)
The bot sends fire-and-forget HTTP POSTs to DASHBOARD_URL/api/events with type: download_start | progress | download_done | download_error. These are best-effort; failures are logged at DEBUG and ignored.
Download Flow
- User sends URL β bot calls
reclip_client.get_info() - Bot shows thumbnail + format buttons (MP4 / MP3)
- MP4 path shows quality picker; MP3 path starts audio download directly
- Bot calls
start_download()β pollspoll_status()every 2s - Progress updates edit the Telegram message in real time
- On
status: done, bot uploads the file via the self-hosted Bot API
Post-Processing in Reclip
- yt-dlp downloads to
DOWNLOADS_PATH/<job_id>.<ext> - AV1/VP9/VP8 videos are transcoded to H264 via ffmpeg (Telegram compatibility)
- Other MP4s get
-movflags +faststartvia ffmpeg copy - File duration/width/height extracted with ffprobe
Concurrency & Limits
- Reclip uses
threading.Semaphore(MAX_CONCURRENT_DOWNLOADS)(default 3) - Each download has a hard timeout of
DOWNLOAD_TIMEOUTseconds (default 900) - Bot has a 10-minute in-memory session TTL (
STATE_TTL = 600)
Cleanup (bot/cleanup.py)
Background asyncio task that runs every CLEANUP_INTERVAL_SECONDS (default 300):
- Deletes files older than
CLEANUP_MAX_AGE_HOURS(default 1) - If disk usage exceeds
CLEANUP_MAX_DISK_MB(default 5000), deletes oldest files first
Environment Variables
Required:
BOT_TOKENβ from @BotFatherTELEGRAM_API_ID/TELEGRAM_API_HASHβ from my.telegram.orgDASHBOARD_PASSWORDβ dashboard login password
Commonly overridden for local dev:
RECLIP_URL=http://localhost:8899TELEGRAM_BOT_API_URL=http://localhost:8081DOWNLOADS_PATH=./downloadsDB_PATH=./reclip.dbSECRET_KEY=change-me(dashboard cookie signing)
See .env.example for the full list with defaults.
Code Conventions
- No linting / formatting / typechecking tooling is configured. There is no black, ruff, mypy, or pre-commit setup.
- Imports use
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))in test files to reach parent modules. - Dashboard DB uses SQLite with WAL mode (
PRAGMA journal_mode=WAL). - Auth is session-cookie based (itsdangerous URLSafeTimedSerializer), not JWT or OAuth.
- All event_client calls are fire-and-forget with a 2-second timeout; they must never crash the bot.
Common Gotchas
- Shared volume:
downloadsis a Docker shared volume between reclip, bot, and dashboard. Locally, all three services must point to the same filesystem path. - Bot API server first startup: The self-hosted Bot API downloads Telegram server data on first run. This can take 30β60 seconds. The bot polls
wait_for_bot_api()for up to 60s. - Dashboard DB path:
_db_path()re-readsDB_PATHfrom env on every call so tests can override it dynamically. - Reclip job state is in-memory:
jobs = {}inreclip/app.pyis not persistent. Restarting reclip loses active download state. - FFmpeg dependency: The reclip Dockerfile installs ffmpeg. Locally you need it installed (
apt install ffmpegor equivalent).