Other Options:
• PayPal
• Ko-Fi
For extended features, enterprise integrations, or custom commercial licensing, please contact EchterAlsFakeBS@proton.me.
Installation
Install from PyPI using pip:
pip install unofficial-api-for-xfreehd
eaf-base-api>=4.0.0. The compatible networking core is installed automatically.
Quick Start
All operations are asynchronous and should run within an async context:
import asyncio
from xfreehd_api import Client
from base_api import DownloadConfigRAW
async def main():
client = Client()
# Fetch a video
video = await client.get_video("https://xfreehd.com/video/12345/example-video")
# Access metadata
print(video.title)
print(video.views)
# Download video using RAW downloader (direct MP4)
config = DownloadConfigRAW(quality="hd", path="./downloads")
await video.download(configuration=config)
# Fetch an album and get image links
album = await client.get_album("https://xfreehd.com/album/12345/example-album")
images = await album.get_all_images()
print(f"Found {len(images)} images in album.")
asyncio.run(main())
Configuration
XFreeHD API uses eaf_base_api 4.x for networking. You can configure a proxy, timeouts, request attempts, limits, and HTTP parameters via a custom BaseCore.
Please refer to the eaf_base_api Documentation for the complete reference on how to set up RuntimeConfig and BaseCore.
from base_api import BaseCore
from base_api.modules.config import RuntimeConfig
from xfreehd_api import Client
my_config = RuntimeConfig()
my_config.proxy = "socks5://127.0.0.1:9050"
my_config.request_attempts = 4
core = BaseCore(configuration=my_config)
client = Client(core=core)
IteratorConfig, retry policy, and custom scrape errors
Iterator methods take one iterator_config object. Keep load_specific_sources=("html",) when replacing XFreeHD's defaults so full Video metadata is loaded.
from base_api import ErrorAction, ErrorMode, ResultOrder, RetryPolicy, ScrapeErrorContext
from base_api.modules.config import IteratorConfig
async def handle_scrape_error(context: ScrapeErrorContext) -> ErrorAction:
print(context.stage, context.url, context.error, context.attempt)
return ErrorAction.RETRY
retry = RetryPolicy(
max_attempts=3, base_delay=0.5, multiplier=2, max_delay=8, jitter=0.25
)
iterator_config = IteratorConfig(
max_page_concurrency=2,
max_item_concurrency=5,
order=ResultOrder.ORIGINAL,
load_specific_sources=("html",),
page_retry=retry,
item_retry=retry,
page_error_mode=ErrorMode.SKIP,
item_error_mode=ErrorMode.YIELD,
page_error_handler=handle_scrape_error,
item_error_handler=handle_scrape_error,
)
async for result in client.search("beach", iterator_config=iterator_config):
print(result.unwrap().title if result.succeeded else result.error)
max_attempts includes the first attempt. page_error_handler and item_error_handler are routed independently. This example shares one callable because it intentionally applies the same retry decision to both stages; use separate callables when page and item policy differ.
Client
The main class to interact with the XFreeHD scraper ecosystem.
from xfreehd_api import Client
from base_api import BaseCore
client = Client()
client_custom = Client(core=BaseCore())
Constructor Parameters
- core BaseCore — Networking core instance (default:
BaseCore())
Methods
Fetch Video get_video()
Video object.Parameters
- url str — The XFreeHD video page URL
- load_html bool — If
True(default), fetches and extracts metadata immediately
Returns
→ VideoFetch Album get_album()
Album object.Parameters
- url str — The XFreeHD photo album page URL
- load_html bool — If
True(default), fetches and extracts metadata immediately
Returns
→ AlbumSearch Videos search()
Parameters
- query str — Search keywords
- pages int — Number of search pages to parse (default:
5) - iterator_config IteratorConfig | None — Per-iterator concurrency, source loading, ordering, retry, error-mode, and custom-handler settings. The package default loads the
htmlsource.
Returns
→ AsyncGenerator[ScrapeResult[Video], None]Video
dataclass Inherits from BaseMedia. Represents a single video with details extracted from player page HTML elements.
Attributes
| Attribute | Type | Description |
|---|---|---|
url | str | The video page URL |
title | str | None | Video title |
likes | str | None | Number of likes |
dislikes | str | None | Number of dislikes |
publish_date | str | None | Publication / upload date string |
views | str | None | Number of views |
author | str | None | Username of the video uploader |
author_thumbnail | str | None | Uploader avatar picture URL |
author_url | str | None | Uploader channel profile URL |
author_subscribers | str | None | Uploader subscriber count |
thumbnail | str | None | Cover image thumbnail URL |
length | str | None | Duration string (e.g. 12:34) |
categories | list[str] | None | List of category labels |
tags | list[str] | None | List of video tags |
cdn_urls | list[str] | None | Direct MP4 CDN paths (up to two qualities: SD, HD) |
embed_url | str | None | Embeddable iframe player URL |
rating | str | None | Ratings metadata loaded from HTML |
Methods
Video Qualities video_qualities()
Returns
→ list[int]Download Video download()
DownloadConfigRAW. Supports hd and sd quality configuration.Video.download() returns True when the RAW downloader completes. On an exception it raises DownloadFailed with the video URL and original cause; it no longer returns an exception object. Replace checks such as isinstance(result, DownloadFailed) with try/except DownloadFailed.
Parameters
- configuration DownloadConfigRAW — RAW download options. Set
quality="hd"orquality="sd". See Downloading Options.
Returns
→ boolAlbum
dataclass Inherits from BaseMedia. Represents a picture gallery album with support for paginated photo fetching.
Attributes
| Attribute | Type | Description |
|---|---|---|
url | str | Album page URL |
title | str | None | Album title |
total_pages_count | int | None | Calculated total pages in the album |
Methods
Get Images by Page get_images_by_page()
get_images_by_page(page) raises NotFound when page exceeds total_pages_count; the message includes the requested page, album URL, and total page count.
Parameters
- page int — Page index (1-based, default:
1)
Returns
→ list[str]Get All Images get_all_images()
Returns
→ list[str]Downloading Options
Video.download() returns True when the RAW downloader completes. On an exception it raises DownloadFailed with the video URL and original cause; it no longer returns an exception object. Replace checks such as isinstance(result, DownloadFailed) with try/except DownloadFailed.
XFreeHD video files are direct MP4 assets on CDNs. Configure downloads using DownloadConfigRAW:
from base_api import DownloadConfigRAW
config = DownloadConfigRAW(
quality="hd", # Set to "hd" for high quality, or "sd" for standard quality
path="./downloads", # Destination path
no_title=False, # If False, automatically appends title + ".mp4"
allow_multipart=True, # Enable parallel segmented downloads using range requests
max_workers=5 # Concurrent download segment threads
)
success = await video.download(configuration=config)
For full details on RAW download parameters, see the reference in eaf_base_api Documentation.
Scraping Results
Iterating methods like client.search() return async generators yielding ScrapeResult instances:
async for result in client.search("beach", pages=2):
if result.succeeded:
video = result.unwrap() # The Video object
print(video.title)
else:
print(f"{result.stage} failed: {result.error}")
ScrapeResult Attributes
| Attribute | Type | Description |
|---|---|---|
succeeded | bool | Whether the scraping task succeeded. |
unwrap() | Video | Returns the parsed video, or raises the stored error. |
item | Video | None | The parsed video when successful. |
error | ScrapeOperationError | None | The typed page or item failure. |
stage | ScrapeStage | The iterator stage: PAGE or ITEM. |
Error Handling
Source loaders translate request failures into exceptions from xfreehd_api.modules.errors. Calls that load media expose ordinary loader failures through base_api.MediaLoadError (or MediaLoadErrors for several sources); inspect original_error/errors as shown. Operations outside media loading may still raise package or core exceptions directly.
Request and download failures are logged with the operation, target URL, and full original traceback. Translated exceptions retain the original error in __cause__. Download preparation failures (including metadata loading, quality selection, and output path setup) are also wrapped in DownloadFailed; inspect its cause when diagnosing a failure. The specific availability exceptions listed below remain supported. An explicit DownloadCancelled or asyncio.CancelledError propagates without being wrapped in DownloadFailed. Base downloader False and DownloadReport results remain supported; inspect the result as well as handling exceptions.
The common provider errors NotFound, NetworkError, BotDetection, ProxyError, UnknownNetworkError, and DownloadFailed are catchable through base_api.modules.errors. They derive from ScraperException, which now derives from BaseScraperError. Existing provider import paths remain valid.
See Logging & Cleanup for application logging setup.
| Exception | Trigger Cause |
|---|---|
NotFound | Server returned HTTP 404 (e.g. video/album deleted) |
NetworkError | Request failed due to a network error, exhausted request retries, or a non-404 HTTPStatusError |
BotDetection | Bot-protection challenge block detected |
ProxyError | Proxy configuration failed or proxy is down |
UnknownNetworkError | Unexpected network errors |
DownloadFailed | Download preparation or transfer failed; the video URL is included and __cause__ retains the original exception |
from base_api import MediaLoadError
from xfreehd_api.modules.errors import NotFound, BotDetection
try:
video = await client.get_video(url)
except MediaLoadError as error:
if isinstance(error.original_error, NotFound):
print("This video does not exist!")
elif isinstance(error.original_error, BotDetection):
print("Scraper was blocked by anti-bot measures.")
else:
raise
Changelog
1.7.1 — 2026-09-15
a728c0e/b18b650/fb5e92c— Adopted shared request and download error handling frombase_api.modules.provider(requiringeaf-base-api>=4.2.0). Failed downloads now raiseDownloadFailedwith complete diagnostic context. ExpandedVideometadata withauthor_thumbnail,author_url,author_subscribers,embed_url, andrating. Cleanly report removed or unavailable videos viaResourceGone. Added robust fallback selectors and offline extraction unit tests.
1.7.1 — 2026-08-14 264b618
- Added
Video.video_qualities()for consumers that need numeric quality tiers for the current one- or two-CDN layouts.
1.7 — 2026-08-11 d41c536
- Added the
py.typedmarker and changed unset iterator retry policies to resolve from the liveRuntimeConfig. - Updated the package version from 1.6 to 1.7.
IteratorConfig synchronization — 2026-08-08 5f55f07
- Replaced the legacy per-call iterator arguments with
IteratorConfig. - Preserved the required
htmlsource loading for search results.
Core v4 migration — 2026-08-07 bf40a03
- Migrated to eaf-base-api 4.x with explicit request methods and source-aware media loading.
- Added bounded retries, structured errors, extractor validation, improved concurrency, and deterministic stream cleanup.
- Removed obsolete compatibility code and adopted the current
ScrapeResultmodel.
CLI Usage
The CLI entry point configures console logging at INFO level. Caught per-URL failures include the URL and full traceback; the default log format shows the logger, file, line, and function. Library applications should configure logging once at startup.
XFreeHD API includes a command-line interface accessible via xfreehd_api or python -m xfreehd_api:
# Download a single video
xfreehd_api --download "https://www.xfreehd.com/video/12345/sample" --quality best --output ./downloads --no-title False
# Or invoke via python -m
python -m xfreehd_api --download "https://www.xfreehd.com/video/12345/sample" --quality best --output ./downloads --no-title False
# Download from a line-separated file of URLs
xfreehd_api --file urls.txt --quality best --output ./downloads --no-title False
CLI Options
| Flag | Description |
|---|---|
--download URL | Video URL to download |
--file FILE | Text file with URLs (separated by newlines) |
--quality QUALITY | Video quality: best, half, worst |
--output DIR | Destination directory or output file path |
--no-title True/False | Skip auto-appending video title to output filename (default: False) |
Supported Platforms
| Platform | Architecture | Status |
|---|---|---|
| Windows 11 | x64 | ✅ Tested |
| macOS Sequoia | x86_64 / arm64 | ✅ Tested |
| Linux (Arch) | x86_64 | ✅ Tested |
| Android 16 | aarch64 | ✅ Tested |