Files
media-downloader/docs/archive/WEB_GUI_API_SPEC.md
Todd 0d7b2b1aab Initial commit
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 22:42:55 -04:00

19 KiB

API Specification - Media Downloader Web GUI

Overview

RESTful API with WebSocket support for real-time updates.

Base URL: http://localhost:8000/api/v1 Authentication: JWT Bearer Token Content-Type: application/json


Authentication Endpoints

POST /auth/login

Login with username and password.

Request:

{
  "username": "admin",
  "password": "secretpassword"
}

Response (200 OK):

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "bearer",
  "expires_in": 900,
  "user": {
    "id": 1,
    "username": "admin",
    "email": "admin@example.com",
    "role": "admin"
  }
}

Error Response (401 Unauthorized):

{
  "detail": "Incorrect username or password"
}

POST /auth/refresh

Refresh access token using refresh token.

Request:

{
  "refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}

Response (200 OK):

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "bearer",
  "expires_in": 900
}

GET /auth/me

Get current authenticated user.

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Response (200 OK):

{
  "id": 1,
  "username": "admin",
  "email": "admin@example.com",
  "role": "admin",
  "created_at": "2025-10-01T10:00:00Z",
  "last_login": "2025-10-13T14:30:00Z"
}

Download Endpoints

GET /downloads

List downloads with filtering and pagination.

Query Parameters:

  • page (int): Page number (default: 1)
  • per_page (int): Items per page (default: 50, max: 200)
  • platform (str): Filter by platform (instagram, tiktok, forum)
  • source (str): Filter by source (username/forum name)
  • status (str): Filter by status (completed, failed)
  • date_from (date): Filter from date (YYYY-MM-DD)
  • date_to (date): Filter to date (YYYY-MM-DD)
  • search (str): Search in URLs and filenames

Example Request:

GET /downloads?platform=instagram&source=evalongoria&page=1&per_page=20

Response (200 OK):

{
  "items": [
    {
      "id": 1885,
      "url": "https://instagram.com/p/ABC123/",
      "url_hash": "a1b2c3d4e5f6...",
      "platform": "instagram",
      "source": "evalongoria",
      "content_type": "post",
      "filename": "evalongoria_20251012_141523_123456789.jpg",
      "file_path": "/opt/media-downloader/downloads/fastdl/evalongoria/evalongoria_20251012_141523_123456789.jpg",
      "file_size": 2457600,
      "file_hash": "sha256:abc123...",
      "post_date": "2025-10-12T14:15:23Z",
      "download_date": "2025-10-12T14:20:45Z",
      "status": "completed",
      "attempts": 1,
      "metadata": {
        "media_id": "123456789",
        "resolution": "640x640",
        "upgraded": false
      }
    }
  ],
  "total": 1885,
  "page": 1,
  "per_page": 20,
  "total_pages": 95
}

GET /downloads/{id}

Get single download by ID.

Response (200 OK):

{
  "id": 1885,
  "url": "https://instagram.com/p/ABC123/",
  "platform": "instagram",
  "source": "evalongoria",
  "content_type": "post",
  "filename": "evalongoria_20251012_141523_123456789.jpg",
  "file_path": "/opt/media-downloader/downloads/fastdl/evalongoria/evalongoria_20251012_141523_123456789.jpg",
  "file_size": 2457600,
  "file_hash": "sha256:abc123...",
  "post_date": "2025-10-12T14:15:23Z",
  "download_date": "2025-10-12T14:20:45Z",
  "status": "completed",
  "attempts": 1,
  "metadata": {
    "media_id": "123456789",
    "resolution": "640x640",
    "upgraded": false
  },
  "thumbnail_url": "/api/v1/downloads/1885/thumbnail"
}

DELETE /downloads/{id}

Delete download record (optionally delete file).

Query Parameters:

  • delete_file (bool): Also delete the physical file (default: false)

Response (204 No Content)


GET /downloads/stats

Get download statistics.

Query Parameters:

  • period (str): Time period (today, week, month, year, all)
  • group_by (str): Group by field (platform, source, content_type)

Response (200 OK):

{
  "total_downloads": 1885,
  "completed": 1870,
  "failed": 15,
  "success_rate": 99.2,
  "total_size_bytes": 45678901234,
  "by_platform": {
    "instagram": 333,
    "fastdl": 18,
    "tiktok": 12,
    "forum": 1522
  },
  "by_source": {
    "evalongoria": 186,
    "PicturePub": 1332,
    "HQCelebCorner": 190
  },
  "timeline": [
    {"date": "2025-10-06", "count": 15},
    {"date": "2025-10-07", "count": 23},
    {"date": "2025-10-08", "count": 31}
  ]
}

POST /downloads/bulk

Bulk operations on downloads.

Request:

{
  "action": "delete",  // delete, retry, mark_upgraded
  "ids": [1, 2, 3, 4, 5],
  "delete_files": false
}

Response (200 OK):

{
  "success": 5,
  "failed": 0,
  "errors": []
}

Queue Endpoints

GET /queue

Get download queue items.

Query Parameters:

  • status (str): Filter by status (pending, downloading, completed, failed)
  • platform (str): Filter by platform
  • page (int): Page number
  • per_page (int): Items per page

Response (200 OK):

{
  "items": [
    {
      "id": 2731,
      "url": "https://instagram.com/evalongoria",
      "platform": "forum",
      "source": "PicturePub",
      "referer": null,
      "save_path": "/opt/media-downloader/downloads/forum/PicturePub",
      "priority": 5,
      "status": "pending",
      "attempts": 0,
      "max_attempts": 3,
      "created_date": "2025-10-13T10:30:00Z",
      "started_at": null,
      "download_date": null,
      "progress": 0,
      "estimated_completion": null,
      "assigned_worker": null,
      "error_message": null,
      "metadata": {
        "thread_id": "thread-12345",
        "content_type": "images"
      }
    }
  ],
  "total": 2731,
  "pending": 2731,
  "downloading": 0,
  "completed": 0,
  "failed": 0
}

POST /queue

Add item to download queue.

Request:

{
  "url": "https://instagram.com/evalongoria",
  "platform": "instagram",
  "source": "evalongoria",
  "content_type": "posts",
  "priority": 5,
  "max_downloads": 15,
  "metadata": {
    "downloader": "fastdl"
  }
}

Response (201 Created):

{
  "id": 2732,
  "url": "https://instagram.com/evalongoria",
  "platform": "instagram",
  "source": "evalongoria",
  "status": "pending",
  "created_date": "2025-10-13T15:45:00Z",
  "task_id": "celery-task-uuid-here"
}

PATCH /queue/{id}

Update queue item.

Request:

{
  "priority": 1,
  "status": "paused"
}

Response (200 OK):

{
  "id": 2732,
  "status": "paused",
  "priority": 1
}

DELETE /queue/{id}

Remove item from queue.

Response (204 No Content)


POST /queue/{id}/retry

Retry failed download.

Response (200 OK):

{
  "id": 2732,
  "status": "pending",
  "attempts": 1,
  "task_id": "celery-task-uuid-here"
}

POST /queue/clear

Clear completed/failed items from queue.

Request:

{
  "status": ["completed", "failed"]
}

Response (200 OK):

{
  "deleted": 125
}

GET /queue/stats

Get queue statistics.

Response (200 OK):

{
  "total": 2731,
  "pending": 2700,
  "downloading": 5,
  "completed": 20,
  "failed": 6,
  "avg_wait_time_seconds": 120,
  "estimated_completion": "2025-10-13T18:30:00Z",
  "active_workers": 4
}

Scheduler Endpoints

GET /scheduler/jobs

List all scheduled jobs.

Response (200 OK):

{
  "jobs": [
    {
      "id": "instagram-evalongoria-posts",
      "name": "Eva Longoria Instagram Posts",
      "platform": "instagram",
      "source": "evalongoria",
      "content_type": "posts",
      "schedule": "0 */4 * * *",  // Every 4 hours
      "schedule_human": "Every 4 hours",
      "enabled": true,
      "last_run": "2025-10-13T12:00:00Z",
      "last_run_status": "success",
      "last_run_items": 8,
      "next_run": "2025-10-13T16:00:00Z",
      "total_runs": 245,
      "success_count": 240,
      "failure_count": 5,
      "config": {
        "max_downloads": 15,
        "downloader": "fastdl"
      }
    }
  ]
}

POST /scheduler/jobs

Create new scheduled job.

Request:

{
  "name": "Eva Longoria Stories",
  "platform": "instagram",
  "source": "evalongoria",
  "content_type": "stories",
  "schedule": "0 */6 * * *",
  "enabled": true,
  "config": {
    "max_downloads": 50,
    "downloader": "fastdl"
  }
}

Response (201 Created):

{
  "id": "instagram-evalongoria-stories",
  "name": "Eva Longoria Stories",
  "next_run": "2025-10-13T18:00:00Z",
  "enabled": true
}

PATCH /scheduler/jobs/{id}

Update scheduled job.

Request:

{
  "schedule": "0 */8 * * *",
  "enabled": false
}

Response (200 OK):

{
  "id": "instagram-evalongoria-stories",
  "schedule": "0 */8 * * *",
  "enabled": false,
  "next_run": null
}

DELETE /scheduler/jobs/{id}

Delete scheduled job.

Response (204 No Content)


POST /scheduler/jobs/{id}/run

Manually trigger job execution.

Response (202 Accepted):

{
  "task_id": "celery-task-uuid",
  "status": "queued",
  "message": "Job execution queued"
}

GET /scheduler/history

Get job execution history.

Query Parameters:

  • job_id (str): Filter by job ID
  • status (str): Filter by status (success, failure)
  • limit (int): Number of records (default: 100)

Response (200 OK):

{
  "history": [
    {
      "id": 1234,
      "job_id": "instagram-evalongoria-posts",
      "started_at": "2025-10-13T12:00:00Z",
      "completed_at": "2025-10-13T12:03:45Z",
      "duration_seconds": 225,
      "status": "success",
      "items_downloaded": 8,
      "error_message": null
    }
  ]
}

Platform Endpoints

GET /platforms

List all supported platforms.

Response (200 OK):

{
  "platforms": [
    {
      "name": "instagram",
      "display_name": "Instagram",
      "enabled": true,
      "downloaders": [
        {
          "name": "fastdl",
          "display_name": "FastDL (640x640)",
          "enabled": true
        },
        {
          "name": "toolzu",
          "display_name": "Toolzu (1920x1440)",
          "enabled": true
        }
      ],
      "content_types": ["posts", "stories", "reels"],
      "features": ["quality_upgrade", "date_filtering", "limit_downloads"],
      "status": "operational",
      "last_successful_download": "2025-10-13T14:30:00Z"
    },
    {
      "name": "tiktok",
      "display_name": "TikTok",
      "enabled": true,
      "content_types": ["videos"],
      "status": "operational"
    }
  ]
}

POST /platforms/instagram/download

Start Instagram download.

Request:

{
  "username": "evalongoria",
  "content_type": "posts",
  "downloader": "fastdl",
  "max_downloads": 15,
  "days_back": 7,
  "priority": 5
}

Response (202 Accepted):

{
  "queue_id": 2733,
  "task_id": "celery-task-uuid",
  "status": "queued",
  "message": "Download queued successfully"
}

POST /platforms/tiktok/download

Start TikTok download.

Request:

{
  "username": "evalongoria",
  "max_downloads": 10,
  "priority": 5
}

Response (202 Accepted):

{
  "queue_id": 2734,
  "task_id": "celery-task-uuid",
  "status": "queued"
}

POST /platforms/forum/monitor

Start forum thread monitoring.

Request:

{
  "forum_name": "PicturePub",
  "thread_url": "https://example.com/thread/123",
  "thread_title": "Celebrity Photos",
  "monitor_days": 30
}

Response (201 Created):

{
  "thread_id": "thread-123",
  "status": "active",
  "monitor_until": "2025-11-12T15:00:00Z"
}

Settings Endpoints

GET /settings

Get all application settings.

Response (200 OK):

{
  "general": {
    "download_directory": "/opt/media-downloader/downloads",
    "concurrent_downloads": 4,
    "retry_attempts": 3,
    "default_priority": 5,
    "storage_limit_gb": 500,
    "auto_cleanup_days": 180
  },
  "platforms": {
    "instagram": {
      "fastdl": {
        "enabled": true,
        "rate_limit_per_hour": 100
      },
      "toolzu": {
        "enabled": true,
        "auto_upgrade": true,
        "captcha_api_key": "***"
      }
    },
    "tiktok": {
      "enabled": true,
      "quality": "hd"
    }
  },
  "notifications": {
    "email": {
      "enabled": false,
      "smtp_host": "",
      "smtp_port": 587
    },
    "browser": {
      "enabled": true
    }
  }
}

PATCH /settings

Update settings.

Request:

{
  "general": {
    "concurrent_downloads": 6
  },
  "platforms": {
    "instagram": {
      "toolzu": {
        "auto_upgrade": false
      }
    }
  }
}

Response (200 OK):

{
  "message": "Settings updated successfully",
  "updated_fields": 2
}

Logs Endpoints

GET /logs

Get application logs.

Query Parameters:

  • level (str): Filter by level (DEBUG, INFO, WARNING, ERROR)
  • module (str): Filter by module (Instagram, TikTok, Scheduler, etc.)
  • search (str): Search in log messages
  • date_from (datetime): From timestamp
  • date_to (datetime): To timestamp
  • limit (int): Number of records (default: 100, max: 1000)

Response (200 OK):

{
  "logs": [
    {
      "id": 12345,
      "timestamp": "2025-10-13T15:45:23.456Z",
      "level": "INFO",
      "module": "Instagram",
      "message": "Downloaded 8 posts from evalongoria",
      "metadata": {
        "username": "evalongoria",
        "count": 8,
        "duration_seconds": 45
      }
    }
  ],
  "total": 12345,
  "filtered": 100
}

GET /logs/download

Download log file.

Query Parameters:

  • date (date): Log file date (YYYY-MM-DD)
  • format (str): Format (json, text)

Response (200 OK):

Content-Type: application/octet-stream
Content-Disposition: attachment; filename="media_downloader_20251013.log"

[Log file content]

DELETE /logs

Clear old logs.

Query Parameters:

  • older_than_days (int): Delete logs older than N days

Response (200 OK):

{
  "deleted_files": 15,
  "deleted_size_bytes": 52428800
}

Statistics Endpoints

GET /stats/overview

Get dashboard overview statistics.

Response (200 OK):

{
  "downloads": {
    "today": 45,
    "week": 312,
    "month": 1205,
    "total": 1885
  },
  "queue": {
    "pending": 2731,
    "downloading": 5,
    "failed": 6
  },
  "success_rate": {
    "today": 97.8,
    "week": 98.5,
    "month": 99.2
  },
  "storage": {
    "used_bytes": 45678901234,
    "used_human": "42.5 GB",
    "limit_bytes": 536870912000,
    "limit_human": "500 GB",
    "percent": 8.5
  },
  "platforms": {
    "instagram": {
      "status": "operational",
      "downloads_today": 35
    },
    "tiktok": {
      "status": "operational",
      "downloads_today": 2
    },
    "forum": {
      "status": "operational",
      "downloads_today": 8
    }
  },
  "next_scheduled_task": {
    "job_id": "instagram-evalongoria-posts",
    "job_name": "Eva Longoria Instagram Posts",
    "scheduled_time": "2025-10-13T16:00:00Z",
    "in_seconds": 873
  }
}

GET /stats/timeline

Get downloads over time.

Query Parameters:

  • period (str): Period (day, week, month, year)
  • group_by (str): Group by (hour, day, week, month)

Response (200 OK):

{
  "timeline": [
    {
      "timestamp": "2025-10-06T00:00:00Z",
      "downloads": 45,
      "success": 44,
      "failed": 1
    },
    {
      "timestamp": "2025-10-07T00:00:00Z",
      "downloads": 52,
      "success": 52,
      "failed": 0
    }
  ]
}

GET /stats/platforms

Get breakdown by platform.

Response (200 OK):

{
  "platforms": [
    {
      "platform": "instagram",
      "downloads": 351,
      "success": 348,
      "failed": 3,
      "success_rate": 99.1,
      "total_size_bytes": 15678901234
    },
    {
      "platform": "forum",
      "downloads": 1522,
      "success": 1520,
      "failed": 2,
      "success_rate": 99.9,
      "total_size_bytes": 28678901234
    }
  ]
}

WebSocket Events

Connection

WS ws://localhost:8000/ws/downloads?token=JWT_TOKEN

Download Progress Event

{
  "type": "download_progress",
  "timestamp": "2025-10-13T15:45:23.456Z",
  "data": {
    "queue_id": 2733,
    "url": "https://instagram.com/evalongoria",
    "platform": "instagram",
    "source": "evalongoria",
    "status": "downloading",
    "progress": 65,
    "items_downloaded": 13,
    "items_total": 20,
    "current_item": "evalongoria_20251012_141523_123456789.jpg",
    "speed_mbps": 2.5,
    "eta_seconds": 45
  }
}

Download Complete Event

{
  "type": "download_completed",
  "timestamp": "2025-10-13T15:48:15.123Z",
  "data": {
    "queue_id": 2733,
    "platform": "instagram",
    "source": "evalongoria",
    "items_downloaded": 20,
    "duration_seconds": 172,
    "status": "completed"
  }
}

Queue Update Event

{
  "type": "queue_updated",
  "timestamp": "2025-10-13T15:45:00.000Z",
  "data": {
    "action": "added",
    "item": {
      "id": 2734,
      "platform": "tiktok",
      "source": "evalongoria",
      "status": "pending"
    }
  }
}

Log Event

{
  "type": "log",
  "timestamp": "2025-10-13T15:45:23.456Z",
  "data": {
    "level": "INFO",
    "module": "Instagram",
    "message": "Started downloading posts from evalongoria"
  }
}

System Notification Event

{
  "type": "notification",
  "timestamp": "2025-10-13T15:48:15.123Z",
  "data": {
    "level": "success",
    "title": "Download Complete",
    "message": "Downloaded 20 posts from evalongoria",
    "action": {
      "label": "View Downloads",
      "link": "/history?source=evalongoria"
    },
    "auto_dismiss_seconds": 5
  }
}

Error Responses

All errors follow this format:

{
  "detail": "Error message",
  "error_code": "SPECIFIC_ERROR_CODE",
  "timestamp": "2025-10-13T15:45:23.456Z",
  "request_id": "uuid-here"
}

Common HTTP Status Codes

  • 200 OK - Success
  • 201 Created - Resource created
  • 202 Accepted - Request accepted (async)
  • 204 No Content - Success with no response body
  • 400 Bad Request - Invalid input
  • 401 Unauthorized - Authentication required
  • 403 Forbidden - Insufficient permissions
  • 404 Not Found - Resource not found
  • 409 Conflict - Resource conflict (duplicate)
  • 422 Unprocessable Entity - Validation error
  • 429 Too Many Requests - Rate limit exceeded
  • 500 Internal Server Error - Server error
  • 503 Service Unavailable - Service temporarily unavailable

Rate Limiting

Headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1697203200

Limits:

  • Public endpoints: 100 requests/hour
  • Authenticated endpoints: 1000 requests/hour
  • WebSocket connections: 10 per user

Pagination

All list endpoints support pagination:

Request:

GET /downloads?page=2&per_page=50

Response Headers:

X-Total-Count: 1885
X-Page: 2
X-Per-Page: 50
X-Total-Pages: 38
Link: </api/v1/downloads?page=1>; rel="first", </api/v1/downloads?page=3>; rel="next"