Batch-download files and directories from a remote SFTP server β with scheduling, resume, retry, and progress display.
- π File-list driven β specify remote paths in a simple text file
- β° Scheduled downloads β optionally start at a specific date/time
- π Resume & retry β interrupted downloads resume automatically; failures retry with back-off
- π Progress bars β real-time tqdm progress for every file
- π Recursive folders β directories are downloaded recursively, preserving structure
- π Special characters β handles spaces, accents, and special characters in paths
- Python 3.12+
- Access to an SFTP server (hostname, port, username, password)
# Clone the repository
git clone <repo-url>
cd file_fetcher
# Create a virtual environment (recommended)
python -m venv .venv
source .venv/bin/activate # macOS / Linux
# .venv\Scripts\activate # Windows
# Install the package
pip install -e .Copy the template and fill in your values:
cp .env.example .envThen edit .env:
# ββ SFTP Server ββββββββββββββββββββββββββββββββββ
SFTP_HOST=your.server.com
SFTP_PORT=22
SFTP_USER=your_username
SFTP_PASSWORD=your_password
# ββ Paths ββββββββββββββββββββββββββββββββββββββββ
FILE_LIST=files_to_download.txt
DOWNLOAD_DIR=./downloads| Variable | Required | Default | Description |
|---|---|---|---|
SFTP_HOST |
β | β | Hostname or IP of the SFTP server |
SFTP_PORT |
β | 22 |
SFTP port |
SFTP_USER |
β | β | Username for authentication |
SFTP_PASSWORD |
β | β | Password for authentication |
FILE_LIST |
β | files_to_download.txt |
Path to the file list |
DOWNLOAD_DIR |
β | ./downloads |
Local directory for downloaded files |
Create a text file with one remote path per line. Both individual files and full directories are supported. Lines starting with # are treated as comments.
# Movies
/media/Films/The Last Horizon (2026).mkv
/media/4k/Neon Shadows/
# TV Shows
/media/SΓ©ries TV/Show Name/Season 01/
Note: Paths with spaces, accents, and special characters are fully supported β no quoting or escaping needed.
To delay the download until a specific date and time, edit config.yaml:
schedule:
date: "2026-03-01"
time: "02:00"Omit the schedule section (or leave it commented out) to start downloading immediately.
File Fetcher supports finding media on your server using natural language. It uses a Google ADK agent backed by Gemini β the agent autonomously searches your SFTP server, fetches ratings from OMDb (IMDb & Rotten Tomatoes), and semantically filters results before presenting them.
Get a Gemini API key from the Google AI Studio and add it to your .env:
GOOGLE_API_KEY=your_google_api_keyTo display IMDb and Rotten Tomatoes ratings in the console, File Fetcher uses the OMDb API.
- Get a free API key (1,000 requests/day limit) from omdbapi.com.
- Add it to your
.envfile:OMDB_API_KEY=your_issued_key_here
The easiest way to run the program is to use the provided run.sh script. It automatically ensures the Python virtual environment is created, dependencies are installed, and launches the app directly.
# Make the script executable (only needed once)
chmod +x run.sh
# Immediate download
./run.sh downloadIf you prefer to manage the environment manually:
# Activate your virtual environment first
source .venv/bin/activate
python -m file_fetcher download
# Or, if installed via pip install -e .:
file-fetcher download- Set
schedule.dateandschedule.timeinconfig.yaml. - Launch the app β it will display a countdown and start automatically at the scheduled time.
./run.shββββββββββββββββββββββββββββββββββββββββ
β π File Fetcher v0.1 β
ββββββββββββββββββββββββββββββββββββββββ
π 3 path(s) to download
π Destination: /Users/you/downloads
β³ Download scheduled for 2026-03-01 02:00. Waiting 6h 30m 15s β¦
Both TV shows and Movies are fully supported. Find items on the server by describing them:
./run.sh search "find me the latest sci-fi movies from 2025 or 2026"The app will:
- Send your query to an ADK agent (Gemini).
- The agent scans the remote server over SFTP.
- The agent looks up IMDb and Rotten Tomatoes ratings.
- Results are semantically filtered and you're prompted to download!
π€ Sending query to ADK agent (model: gemini-2.5-flash)β¦
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# | Title | Year | RT | IMDb | Uploaded
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1 | The Secret Agent | 2025 | 88% | 7.6 | 2026-02-15
2 | Beyond the Horizon | 2026 | 92% | 8.1 | 2026-02-10
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2 items found.
π₯ Enter numbers to download (e.g. 1,3), 'all', or 'q' to quit: 1
π Downloading 1 item(s)...
If a download is interrupted (Ctrl+C, network drop, etc.), simply re-run the same command. File Fetcher will:
- Skip files that are already fully downloaded.
- Resume partially downloaded files from where they left off.
- Retry failed transfers automatically (up to 3 attempts with back-off).
ββββββββββββββββββββββββββββββββββββββββ
β π File Fetcher v0.1 β
ββββββββββββββββββββββββββββββββββββββββ
π 3 path(s) to download
π Destination: /Users/you/downloads
π Connecting to your.server.com:22 β¦
β
Connected.
ββ [1/3] /media/Films/The Last Horizon (2026).mkv
The Last Horizon (2026).mkv: 100%|ββββββββββ| 4.20G/4.20G [05:32<00:00, 12.6MB/s]
ββ [2/3] /media/4k/Neon Shadows/
Neon.Shadows.2160p.mkv: 100%|ββββββββββ| 8.10G/8.10G [10:15<00:00, 13.1MB/s]
ββ [3/3] /media/SΓ©ries TV/Show Name/Season 01/
S01E01.mkv: 100%|ββββββββββ| 1.50G/1.50G [01:55<00:00, 12.9MB/s]
S01E02.mkv: 100%|ββββββββββ| 1.48G/1.48G [01:52<00:00, 13.0MB/s]
ββββββββββββββββββββββββββββββββββββββββββββββββββ
π Summary: 4 items processed
β
4 downloaded
βοΈ 0 skipped (already complete)
β 0 failed
π Disconnected.
file_fetcher/
βββ README.md
βββ pyproject.toml # Dependencies & entry point
βββ config.yaml # Schedule configuration
βββ .env # Credentials (gitignored)
βββ .env.example # Template for .env
βββ files_to_download.txt # Remote paths to download
β
βββ src/file_fetcher/
β βββ __init__.py
β βββ __main__.py # CLI entry point
β βββ config.py # Configuration loader
β βββ scheduler.py # Wait-until-target-time
β βββ sftp_client.py # SFTP download engine
β βββ scanner.py # SFTP media scanner
β βββ ratings.py # OMDb API client
β βββ report.py # CLI report & download prompt
β βββ progress.py # tqdm progress wrapper
β βββ agent/ # ADK agent (Gemini-backed)
β βββ __init__.py
β βββ agent.py # Agent definition & runner
β βββ tools.py # ADK tool factories
β
βββ tests/ # Unit tests
| Problem | Solution |
|---|---|
β Missing required environment variable: SFTP_HOST |
Copy .env.example to .env and fill in your server details. |
Connection refused |
Verify the host, port, and that the SFTP service is running. |
Authentication failed |
Double-check SFTP_USER and SFTP_PASSWORD in .env. |
Path not found on server |
Ensure the paths in files_to_download.txt are correct absolute paths. |
| Filenames with special characters fail | This shouldn't happen β if it does, please open an issue. |
See LICENSE.