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-youporn
For TS→MP4 remuxing support (recommended for HLS downloads), install with the optional av dependency:
pip install unofficial-api-for-youporn[av]
eaf_base_api ≥ 4.0.0, which is installed automatically.
Quick Start
Wrap YouPorn API calls inside an asynchronous main function:
import asyncio
from youporn_api import Client
from base_api import DownloadConfigHLS, DownloadConfigRAW
async def main():
client = Client()
# Fetch a video profile
video = await client.get_video("https://www.youporn.com/watch/12345/example-video")
print(video.title)
print(video.views)
# Download video via stream-matching HLS/RAW configurations
hls_config = DownloadConfigHLS(quality="best", path="./downloads")
raw_config = DownloadConfigRAW(quality="best", path="./downloads")
await video.download(configuration=hls_config, backup_configuration=raw_config)
asyncio.run(main())
Configuration
Proxy/interface, timeout, request-attempt/delay, bandwidth, cache, and concurrency settings are managed by RuntimeConfig inside the shared BaseCore package.
Please refer to the eaf_base_api Documentation for the complete reference.
from base_api import BaseCore
from base_api.modules.config import RuntimeConfig
from youporn_api import Client
my_config = RuntimeConfig()
my_config.proxy = "socks5://127.0.0.1:9050"
my_config.request_attempts = 4
my_config.videos_concurrency = 8
my_config.pages_concurrency = 2
core = BaseCore(configuration=my_config)
client = Client(core=core)
Client
Main class serving as the core interface wrapper.
from youporn_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. Parses the media definition variants.Parameters
- url str — The YouPorn video page URL
- load_html bool — Pre-load and extract properties immediately (default:
True)
Returns
→ VideoFetch Pornstar get_pornstar()
Pornstar object.Parameters
- url str — The pornstar profile page URL
- load_html bool — Pre-load and extract properties immediately (default:
True)
Returns
→ PornstarFetch Channel get_channel()
Channel object.Parameters
- url str — The publisher channel URL
- load_html bool — Pre-load and extract properties immediately (default:
True)
Returns
→ ChannelFetch Collection get_collection()
Collection object.Parameters
- url str — The collection playlist URL
- load_html bool — Pre-load and extract properties immediately (default:
True)
Returns
→ CollectionSearch Videos search_videos()
Parameters
- query str — Search query words
- pages int — Pages to fetch
- filter_relevance str — Sort criteria (e.g.
"views","rating") - filter_duration_minimum str — Min minutes duration
- filter_duration_maximum str — Max minutes duration
- filter_resolution str — Video resolution category (e.g.
"HD","VR") - iterator_config IteratorConfig | None — Concurrency, ordering, source loading, retry, and terminal-error policy. The package default loads the
htmlsource.
Returns
→ AsyncGenerator[ScrapeResult[Video], None]Video
dataclass Inherits from BaseMedia. Represents a single video with details extracted from JavaScript parameters embedded in the page.
Attributes
| Attribute | Type | Description |
|---|---|---|
url | str | The video page URL |
title | str | None | Video title |
publish_date | str | None | Upload / publish date string |
length | str | None | Duration string (e.g. 12:34) |
rating | str | None | Like percentage value |
views | str | None | Total views count |
thumbnail | str | None | Cover image thumbnail URL |
categories | list[str] | None | List of category labels |
m3u8_base_url | str | None | Constructed HLS master playlist URL or direct MP4 URL depending on availability |
author_link | str | None | Uploader profile URL |
pornstars_urls | list[str] | None | Starring pornstar relative profile paths |
uploader_id | str | None | Uploader identifier |
uploader_status | str | None | Uploader status |
uploader_type | str | None | Uploader type |
uploader_name | str | None | Uploader profile name |
video_id | str | None | Unique video key ID |
is_hls | bool | None | Boolean indicating stream delivery type (True: HLS, False: Raw MP4) |
Methods
Get Video Pornstars pornstars
Pornstar objects directly rather than ScrapeResult.Returns
→ AsyncGenerator[Pornstar, None]Download Video download()
configuration. If it falls back to raw MP4, processes it via backup_configuration.Parameters
- configuration DownloadConfigHLS — Main HLS download config
- backup_configuration DownloadConfigRAW | None — Backup direct file download config (required if
is_hls=False)
Returns
→ bool | DownloadReportFetch Video Author author()
Pornstar or Channel object.Parameters
- load_html bool — Pre-load uploader properties (default:
True)
Returns
→ Pornstar | ChannelBaseProfile, Channel, Pornstar, & Collection
BaseProfile inherits from BaseMedia and provides the common header properties (name, avatar, banner, and description) shared by both Channel and Pornstar profiles. Scrapers representing publisher channels, custom collections, and pornstar profile pages provide listing iterators via videos().
BaseProfile Attributes
| Attribute | Type | Description |
|---|---|---|
url | str | Profile page URL |
name | str | None | Profile display name |
avatar | str | None | Avatar image URL |
banner | str | None | Profile header banner image URL |
description | str | None | Profile bio description |
Methods
Fetch Profile Videos videos()
Parameters
- pages int — Pages to load
- iterator_config IteratorConfig | None — Complete iterator policy. The package default loads the
htmlsource.
Returns
→ AsyncGenerator[ScrapeResult[Video], None]User
dataclass Inherits from BaseMedia. Represents a registered user account profile page.
Attributes
| Attribute | Type | Description |
|---|---|---|
url | str | Profile page URL |
name | str | None | Username display name |
collection_urls | list[str] | None | List of relative collection paths created by the user |
Methods
Get User Collections get_collections()
Parameters
- load_html bool — Pre-load full collection metadata (default:
True)
Returns
→ AsyncGenerator[Collection, None]Downloading Options
YouPorn serves videos as both HLS playlists and raw MP4 direct links. In order to handle both cases securely, provide a backup RAW configuration along with the HLS options:
from base_api import DownloadConfigHLS, DownloadConfigRAW
hls_config = DownloadConfigHLS(
quality="best",
path="./downloads",
no_title=False
)
raw_config = DownloadConfigRAW(
quality="best",
path="./downloads",
no_title=False
)
# Will download via HLS if is_hls=True, or fall back to raw direct file downloader if false
success = await video.download(configuration=hls_config, backup_configuration=raw_config)
For more configurations, see references in eaf_base_api Documentation.
Scraping Results
Concurrent search and profile listing methods accept one IteratorConfig policy and yield immutable ScrapeResult[Video] values. The package default loads html, skips terminal page failures, and resolves its unset retry policies from the active RuntimeConfig.request_* settings. A supplied configuration replaces that default, so preserve the HTML source and page error mode explicitly; the example below deliberately opts into yielding page failures. The Video.pornstars and User.get_collections() generators remain direct object iterators.
The public configuration fields are max_page_concurrency, max_item_concurrency, max_pending_items, extract_in_thread, order, both *_error_mode, both *_retry, both *_error_handler, load_specific_fields, and load_specific_sources.
from base_api import ErrorAction, ErrorMode, ResultOrder, RetryPolicy, ScrapeErrorContext
from base_api.modules.config import IteratorConfig
async def handle_error(context: ScrapeErrorContext) -> ErrorAction:
if context.attempt < context.max_attempts:
return ErrorAction.RETRY
return ErrorAction.YIELD
iterator_config = IteratorConfig(
max_page_concurrency=2,
max_item_concurrency=8,
order=ResultOrder.ORIGINAL,
load_specific_sources=("html",),
page_retry=RetryPolicy(max_attempts=4, base_delay=0.5, jitter=0.25),
item_retry=RetryPolicy(max_attempts=4, base_delay=0.5, jitter=0.25),
page_error_mode=ErrorMode.YIELD,
item_error_mode=ErrorMode.YIELD,
page_error_handler=handle_error,
item_error_handler=handle_error,
)
async for result in client.search_videos(
"milf", pages=2, iterator_config=iterator_config
):
if result.succeeded:
video = result.unwrap()
print(video.title)
else:
print(result.stage, result.url, result.attempts, result.error)
ScrapeErrorContext(stage, url, error, attempt, max_attempts, page_index, item_index) and returns ErrorAction.RETRY, RAISE, YIELD, or SKIP. RetryPolicy exposes max_attempts, base_delay, multiplier, max_delay, jitter, and retry_for; attempts include the first call.
ScrapeResult Attributes
| Attribute | Type | Description |
|---|---|---|
stage | ScrapeStage | PAGE or ITEM |
url | str | The page or item target URL |
page_index | int | Zero-based source-page index |
item_index | int | None | Zero-based item index; None for page failures |
attempts | int | Number of attempts consumed |
item | Video | None | The loaded item on success |
error | ScrapeOperationError | None | The typed terminal error on failure |
succeeded | bool | True when the result contains an item |
unwrap() | Video | Returns the item or raises its terminal error |
Error Handling
Source loaders translate request failures into exceptions from youporn_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. Direct unresolved-field access raises base_api.DataNotLoadedError, while operations outside media loading may 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.
The provider-specific RegionBlocked and legacy youporn_api.modules.errors.DataNotLoadedError now derive from ScraperException. The legacy class is distinct from base_api.DataNotLoadedError, which is raised for unresolved media fields.
See Logging & Cleanup for application logging setup.
| Exception | Trigger Cause |
|---|---|
VideoUnavailable | The server returned HTTP 404, or the requested video is deleted or unavailable |
RegionBlocked | Video content is blocked in user's geographic region |
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 youporn_api.modules.errors import RegionBlocked
try:
video = await client.get_video(url)
except MediaLoadError as error:
if isinstance(error.original_error, RegionBlocked):
print("This video is blocked in your country! Try a permitted proxy if appropriate.")
else:
raise
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.
YouPorn API includes a command-line interface accessible via youporn_api or python -m youporn_api:
# Download a single video
youporn_api --download "https://www.youporn.com/watch/1234567/sample-title/" --quality best --output ./downloads --no-title False
# Or invoke via python -m
python -m youporn_api --download "https://www.youporn.com/watch/1234567/sample-title/" --quality best --output ./downloads --no-title False
# Download from a line-separated file of URLs
youporn_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 |
Changelog
| Date | Commit | Changes |
|---|---|---|
| 2026-09-15 | 8144589 / 874e7ab / f4272be | Adopted shared request and download error handling with base_api.modules.provider (requiring eaf-base-api>=4.2.0). Failed downloads now raise DownloadFailed with complete diagnostic context. Added BaseProfile class for common header attributes (name, avatar, banner, description) across Channel and Pornstar. Added complete public type-hint coverage across the API. |
| 2026-08-11 | 6c2af7f | Completed additional public type-hint coverage. |
| 2026-08-11 | b7c2cb3 | Released 1.8 with typing improvements and the py.typed marker. |
| 2026-08-08 | 36a06fe | Centralized concurrent scraping on IteratorConfig and forwarded package source/retry defaults. |
| 2026-08-07 | f163c07 | Migrated source-aware media, explicit loading, bounded retries, and structured scrape results to eaf v4. |