Other Options:
• PayPal
• Ko-Fi
For extended features, enterprise integrations, or custom commercial licensing, please contact EchterAlsFakeBS@proton.me.
Installation
Install the library from PyPI using pip:
pip install unofficial-api-for-tnaflix
eaf-base-api>=4.2.2. The networking engine is installed automatically.
Quick Start
All operations are asynchronous and should be executed within an async context:
import asyncio
from tnaflix_api import Client
from base_api import DownloadConfigRAW
async def main():
client = Client()
# Fetch a video
video = await client.get_video("https://www.tnaflix.com/hd-videos/example-video-12345")
# Print metadata
print(f"Title: {video.title}")
print(f"Duration: {video.length} ({video.duration}s)")
print(f"Available Qualities: {video.video_qualities}")
# Download video using progressive MP4 downloader
config = DownloadConfigRAW(quality="best", path="./downloads")
success = await video.download(configuration=config)
print(f"Download complete: {success}")
asyncio.run(main())
Configuration
TNAFlix API uses eaf_base_api for networking. Configure proxies, request attempts, timeouts, limits, and headers through 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 tnaflix_api import Client
config = RuntimeConfig()
config.proxy = "socks5://127.0.0.1:9050"
config.request_attempts = 3
core = BaseCore(configuration=config)
client = Client(core=core)
IteratorConfig, retry policy, and custom scrape errors
Iterator methods accept an iterator_config object. By default, the API eagerly loads the html source for extracted media items.
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)
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("college", iterator_config=iterator_config):
print(result.unwrap().title if result.succeeded else result.error)
Client
The Client class is the primary entry point to interact with the TNAFlix scraper ecosystem.
from tnaflix_api import Client
from base_api import BaseCore
client = Client()
client_custom = Client(core=BaseCore())
Constructor Parameters
- core BaseCore — Shared networking core instance (default:
BaseCore())
Methods
Fetch Video get_video()
Video object.Parameters
- url str — The full TNAFlix video page URL
- load_html bool — If
True(default), fetches and extracts metadata immediately
Returns
→ VideoFetch Channel get_channel()
Channel object.Parameters
- url str — The TNAFlix channel URL (e.g.
https://www.tnaflix.com/channel/team-skeet) - load_html bool — If
True(default), fetches and extracts metadata immediately
Returns
→ ChannelFetch Profile get_profile()
Profile object.Parameters
- url str — The TNAFlix profile page URL (e.g.
https://www.tnaflix.com/profile/username) - load_html bool — If
True(default), fetches and extracts metadata immediately
Returns
→ ProfileFetch Pornstar get_pornstar()
Pornstar object.Parameters
- url str — The TNAFlix pornstar profile URL (e.g.
https://www.tnaflix.com/profile/lyla-lei) - load_html bool — If
True(default), fetches and extracts metadata immediately
Returns
→ PornstarSearch Videos search()
Parameters
- query str — Search query term
- sorting_sort str | Sort — Sort criteria enum (default:
Sort.RECENT) - sorting_date str | SortDate — Date filtering enum (default:
SortDate.ALL_TIME) - pages int | str — Number of search pages to parse (default:
2) or"all" - iterator_config IteratorConfig | None — Optional v4 iterator policy. Defaults to eagerly loading
htmlsource.
Returns
→ AsyncGenerator[ScrapeResult[Video], None]Video
dataclass Inherits from BaseMedia. Represents a TNAFlix video item with metadata extracted from HTML5 Plyr player configurations and JSON-LD structured data.
Attributes
| Attribute | Type | Description |
|---|---|---|
url | str | The video page URL |
video_id | str | None | Unique video identifier key |
title | str | None | Video title |
description | str | None | Video description |
thumbnail_url | str | None | Primary video cover image thumbnail URL |
mosaic_url_template | str | None | Timeline storyboard mosaic image template URL |
preview_video_url | str | None | Short teaser preview video clip URL |
publish_date | str | None | Upload date (ISO string) |
publish_date_relative | str | None | Relative upload time string |
duration | int | None | Duration in integer seconds |
length | str | None | Formatted duration string (e.g. 12:34) |
author_name | str | None | Username of the uploader |
author_link | str | None | Profile URL of the author |
author_verified | bool | None | Whether the author has a verified badge |
pornstars | list[dict[str, str]] | None | Featured pornstars with name and URL |
pornstars_urls | list[str] | None | Profile URLs of featured performers |
categories | list[dict[str, str]] | None | List of category labels and URLs |
tags | list[str] | None | List of video tags |
views | str | None | Formatted view count |
likes | str | None | Like count |
dislikes | str | None | Dislike count |
rating | str | None | Rating score value |
rating_percent | str | None | Rating percentage string |
rating_votes | str | None | Total rating votes count |
embed_url | str | None | Embeddable iframe player URL |
direct_download_urls | dict[int, str] | None | Mapping of resolution height (e.g. 720, 1080) to direct signed progressive MP4 CDN URLs |
video_qualities | list[int] | None | Available progressive video resolutions sorted ascending (e.g. [360, 480, 720, 1080]) |
Methods
Download Video download()
DownloadConfigRAW.Parameters
- configuration DownloadConfigRAW — RAW download options. See Downloading Options.
Returns
→ boolChannel
dataclass Inherits from BaseMedia. Represents an official publisher studio or content creator channel on TNAFlix (e.g. /channel/team-skeet).
Attributes
| Attribute | Type | Description |
|---|---|---|
url | str | Channel page URL |
slug | str | None | Channel URL slug identifier |
title | str | None | Studio or channel name |
description | str | None | Official channel description text |
avatar_url | str | None | Channel logo avatar picture URL |
cover_url | str | None | Channel header banner cover image URL |
verified | bool | Whether the channel is an officially verified partner |
subscribers_count | str | None | Total channel subscribers count |
total_videos_count | str | None | Total videos uploaded to this channel |
video_views | str | None | Cumulative video views across all channel videos |
Methods
Get Channel Videos videos()
Parameters
- pages int | str — Number of pages to iterate (default:
2) or"all" - iterator_config IteratorConfig | None — Per-iterator concurrency, source loading, ordering, retry, error-mode, and custom-handler settings.
Returns
→ AsyncGenerator[ScrapeResult[Video], None]Profile
dataclass Inherits from BaseMedia. Represents a TNAFlix user profile page containing uploader statistics and community profile information.
Attributes
| Attribute | Type | Description |
|---|---|---|
url | str | Profile page URL |
username | str | None | Profile username |
slug | str | None | Profile URL slug identifier |
display_name | str | None | Display name or page title |
avatar_url | str | None | Profile avatar image URL |
cover_url | str | None | Profile header cover banner URL |
bio | str | None | Biography or description text |
rank | str | None | Site ranking position |
profile_views | str | None | Total profile views count |
subscribers_count | str | None | Total subscriber count |
video_views | str | None | Cumulative views across all uploaded videos |
total_videos_count | str | None | Total uploaded videos count |
gender | str | None | Stated gender identity |
interested_in | str | None | Sexual orientation preference |
location | str | None | Geographical location |
age | str | None | Age of the user |
relationship_status | str | None | Relationship status |
is_pornstar | bool | Whether this profile represents a recognized adult performer |
Methods
Get Profile Videos videos()
Parameters
- pages int | str — Number of pages to iterate (default:
2) or"all" - iterator_config IteratorConfig | None — Per-iterator concurrency, source loading, ordering, retry, error-mode, and custom-handler settings.
Returns
→ AsyncGenerator[ScrapeResult[Video], None]Pornstar
dataclass Inherits from Profile. Represents a verified performer or pornstar on TNAFlix (found under /profile/). It shares all underlying profile fields while explicitly indicating an adult model entry with is_pornstar=True.
Performer Fields
| Attribute | Type | Description |
|---|---|---|
url | str | Pornstar profile page URL |
display_name | str | None | Performer stage name |
slug | str | None | Performer URL slug identifier |
avatar_url | str | None | Performer portrait avatar picture URL |
cover_url | str | None | Performer cover banner image URL |
bio | str | None | Biography or introduction text |
rank | str | None | Site ranking position among pornstars |
profile_views | str | None | Accumulated views on this pornstar profile |
subscribers_count | str | None | Total followers and subscribers count |
video_views | str | None | Cumulative video views across all starring videos |
total_videos_count | str | None | Total count of videos featuring this performer |
gender | str | None | Performer gender |
interested_in | str | None | Sexual orientation preference |
location | str | None | Country or city of origin |
age | str | None | Age of the performer |
relationship_status | str | None | Relationship status indicator |
is_pornstar | bool | Always True for Pornstar instances |
Methods
Get Performer Videos videos()
Parameters
- pages int | str — Number of pages to iterate (default:
2) or"all" - iterator_config IteratorConfig | None — Per-iterator concurrency, source loading, ordering, retry, error-mode, and custom-handler settings.
Returns
→ AsyncGenerator[ScrapeResult[Video], None]Search & Filtering
Perform advanced video searches on TNAFlix using the client.search() generator combined with sorting criteria:
from tnaflix_api import Client
from tnaflix_api.modules.sorting import Sort, SortDate
client = Client()
# Search for top-rated videos from the past month
async for result in client.search(
query="blonde",
sorting_sort=Sort.TOP_RATED,
sorting_date=SortDate.THIS_MONTH,
pages=3
):
if result.succeeded:
video = result.unwrap()
print(video.title, video.url, video.length)
else:
print(f"Error: {result.error}")
Sorting Enums
The search interface accepts sorting options defined in tnaflix_api.modules.sorting:
Sort (Order)
| Enum Member | API String Value | Description |
|---|---|---|
Sort.RECENT | "recent" | Sort by latest upload date (default) |
Sort.POPULAR | "popular" | Sort by most popular |
Sort.TOP_RATED | "top_rated" | Sort by highest community rating |
Sort.MOST_VIEWED | "most_viewed" | Sort by highest view counts |
Sort.MOST_FAVORITED | "most_favorited" | Sort by most favorited |
Sort.LONGEST | "longest" | Sort by video duration descending |
SortDate (Period)
| Enum Member | API String Value | Description |
|---|---|---|
SortDate.ALL_TIME | "all_time" | All time historical search (default) |
SortDate.TODAY | "today" | Videos uploaded today |
SortDate.THIS_WEEK | "this_week" | Videos uploaded within this week |
SortDate.THIS_MONTH | "this_month" | Videos uploaded within this month |
Downloading Options
TNAFlix serves progressive direct MP4 streams with signed tokens. Downloads are configured via DownloadConfigRAW:
from base_api import DownloadConfigRAW
config = DownloadConfigRAW(
quality="best", # "best", "half", "worst", or height int (e.g. 720, 1080)
path="./downloads", # Destination directory or file path
no_title=False, # If False, automatically appends video title + ".mp4"
allow_multipart=True, # Enable multi-threaded byte-range chunk downloading
max_workers=5 # Concurrent download workers
)
success = await video.download(configuration=config)
For more options and configuration details, refer to the eaf_base_api Documentation.
Scraping Results
Iterators yield ScrapeResult containers encapsulating item success or typed error details:
async for result in client.search("college", pages=2):
if result.succeeded:
video = result.unwrap()
print(f"Found: {video.title}")
else:
print(f"Stage {result.stage} error: {result.error}")
ScrapeResult Attributes
| Attribute | Type | Description |
|---|---|---|
succeeded | bool | Whether the scraping task succeeded |
unwrap() | Video | Returns the parsed item or raises the underlying exception |
item | Video | None | Parsed video object on success |
error | ScrapeOperationError | None | Typed failure when unsuccessful |
stage | ScrapeStage | Stage where execution occurred: PAGE or ITEM |
Error Handling
Source loaders wrap low-level network errors into typed exceptions from tnaflix_api.modules.errors. Media-loading calls expose errors via base_api.MediaLoadError.
| Exception | Trigger Cause |
|---|---|
NotFound | Server returned HTTP 404 (e.g. video or profile removed) |
NetworkError | Request failed due to connection error, exhausted retries, or HTTP status error |
BotDetection | Cloudflare or anti-bot challenge block encountered |
ProxyError | Proxy configuration error or proxy endpoint unavailable |
UnknownNetworkError | Unrecognized networking exception |
DownloadFailed | Download transfer or preparation failed with full cause retained in __cause__ |
from base_api import MediaLoadError
from tnaflix_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.0 — 2026-10-17
- Initial production release of the unofficial TNAFlix asynchronous Python API wrapper.
- Full extraction of Video metadata from HTML5 Plyr configurations, JSON-LD schemas, and video listing cards.
- Direct progressive MP4 stream extraction and multi-threaded range downloading via
DownloadConfigRAW. - Channel scraper implementation supporting official studio / publisher channel metadata and video streaming.
- Profile and Pornstar scraper implementations supporting member statistics and video listing streaming.
- Search engine integration with
SortandSortDatefilters. - Complete CLI tool supporting direct and batch URL downloads.
- Full compatibility with
eaf-base-api>=4.2.2networking engine.
CLI Usage
TNAFlix API includes a command-line interface accessible via the tnaflix_api binary or python -m tnaflix_api:
tnaflix_api --download "https://www.tnaflix.com/hd-videos/example-video-12345" --quality best --output ./downloads
python -m tnaflix_api --download "https://www.tnaflix.com/hd-videos/example-video-12345" --quality 720 --output ./downloads
tnaflix_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 containing video URLs (newline-separated) |
--quality QUALITY | Desired resolution quality (best, half, worst, or height integer) |
--output DIR | Destination folder or 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 / Debian / Ubuntu) | x86_64 | ✅ Tested |
| Android (Termux) | aarch64 | ✅ Tested |