Python Async v1.0

TNAFlix API

A fully asynchronous Python API wrapper and scraper for tnaflix.com. Extract full video metadata, publisher channels, user profiles, and pornstars, run search queries, and download high-definition progressive MP4 media. Powered by the eaf_base_api networking engine.

GitHub
⚡ Recommended AI Workflow Official MCP Server: https://mcp.echteralsfake.me/mcp

Supercharge your development by connecting your AI coding assistant (Cursor, VS Code / Copilot, Claude Desktop, Windsurf, Zed, Antigravity). No authentication required · No strict rate limits · Covers all 16 APIs · Always up to date · Completely anonymous (0 logs, no profiling). Connecting this MCP server to your AI assistant is absolutely the recommended way to work on and build with these APIs.

⚠️ Legal Disclaimer
This tool is an unofficial, independent project and is not affiliated with, endorsed by, or sponsored by the target website. This software is provided "as is" for educational and personal purposes only. The developer assumes no responsibility for any consequences arising from the use of this tool, including but not limited to account suspension, IP blocking, or any violation of the target website's Terms of Service. Users are solely responsible for ensuring their use complies with all applicable laws and policies. Use at your own risk.
💚 Support & Commercial Licensing
If you find this project helpful, please consider donating to support its continued development!

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:

bash
pip install unofficial-api-for-tnaflix
Note
Requires Python ≥ 3.12 and 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:

python
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.

python
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.

python
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.

python
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()

async
Fetches video metadata for a TNAFlix video URL and returns a populated Video object.
await client.get_video( url: str, load_html: bool = True ) -> Video

Parameters

  • url str — The full TNAFlix video page URL
  • load_html bool — If True (default), fetches and extracts metadata immediately

Returns

→ Video

Fetch Channel get_channel()

async
Fetches publisher studio or creator channel page metadata and returns a populated Channel object.
await client.get_channel( url: str, load_html: bool = True ) -> Channel

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

→ Channel

Fetch Profile get_profile()

async
Fetches metadata for a TNAFlix user profile page and returns a populated Profile object.
await client.get_profile( url: str, load_html: bool = True ) -> Profile

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

→ Profile

Fetch Pornstar get_pornstar()

async
Fetches metadata for a recognized pornstar profile page and returns a populated Pornstar object.
await client.get_pornstar( url: str, load_html: bool = True ) -> Pornstar

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

→ Pornstar

Search Videos search()

async
Queries TNAFlix video search and yields results as an asynchronous generator.
async for result in client.search( query: str, sorting_sort: str | Sort = Sort.RECENT, sorting_date: str | SortDate = SortDate.ALL_TIME, pages: int | str = 2, iterator_config: IteratorConfig | None = None ) -> AsyncGenerator[ScrapeResult[Video], None]

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 html source.

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

AttributeTypeDescription
urlstrThe video page URL
video_idstr | NoneUnique video identifier key
titlestr | NoneVideo title
descriptionstr | NoneVideo description
thumbnail_urlstr | NonePrimary video cover image thumbnail URL
mosaic_url_templatestr | NoneTimeline storyboard mosaic image template URL
preview_video_urlstr | NoneShort teaser preview video clip URL
publish_datestr | NoneUpload date (ISO string)
publish_date_relativestr | NoneRelative upload time string
durationint | NoneDuration in integer seconds
lengthstr | NoneFormatted duration string (e.g. 12:34)
author_namestr | NoneUsername of the uploader
author_linkstr | NoneProfile URL of the author
author_verifiedbool | NoneWhether the author has a verified badge
pornstarslist[dict[str, str]] | NoneFeatured pornstars with name and URL
pornstars_urlslist[str] | NoneProfile URLs of featured performers
categorieslist[dict[str, str]] | NoneList of category labels and URLs
tagslist[str] | NoneList of video tags
viewsstr | NoneFormatted view count
likesstr | NoneLike count
dislikesstr | NoneDislike count
ratingstr | NoneRating score value
rating_percentstr | NoneRating percentage string
rating_votesstr | NoneTotal rating votes count
embed_urlstr | NoneEmbeddable iframe player URL
direct_download_urlsdict[int, str] | NoneMapping of resolution height (e.g. 720, 1080) to direct signed progressive MP4 CDN URLs
video_qualitieslist[int] | NoneAvailable progressive video resolutions sorted ascending (e.g. [360, 480, 720, 1080])

Methods

Download Video download()

async
Downloads the video directly from CDN server using progressive multi-threaded range requests via DownloadConfigRAW.
await video.download( configuration: DownloadConfigRAW ) -> bool

Parameters

Returns

→ bool

📺 Channel

dataclass Inherits from BaseMedia. Represents an official publisher studio or content creator channel on TNAFlix (e.g. /channel/team-skeet).

Attributes

AttributeTypeDescription
urlstrChannel page URL
slugstr | NoneChannel URL slug identifier
titlestr | NoneStudio or channel name
descriptionstr | NoneOfficial channel description text
avatar_urlstr | NoneChannel logo avatar picture URL
cover_urlstr | NoneChannel header banner cover image URL
verifiedboolWhether the channel is an officially verified partner
subscribers_countstr | NoneTotal channel subscribers count
total_videos_countstr | NoneTotal videos uploaded to this channel
video_viewsstr | NoneCumulative video views across all channel videos

Methods

Get Channel Videos videos()

async
Asynchronously yields video scrape results uploaded by this studio channel across listing pages.
async for result in channel.videos( pages: int | str = 2, iterator_config: IteratorConfig | None = None ) -> AsyncGenerator[ScrapeResult[Video], None]

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

AttributeTypeDescription
urlstrProfile page URL
usernamestr | NoneProfile username
slugstr | NoneProfile URL slug identifier
display_namestr | NoneDisplay name or page title
avatar_urlstr | NoneProfile avatar image URL
cover_urlstr | NoneProfile header cover banner URL
biostr | NoneBiography or description text
rankstr | NoneSite ranking position
profile_viewsstr | NoneTotal profile views count
subscribers_countstr | NoneTotal subscriber count
video_viewsstr | NoneCumulative views across all uploaded videos
total_videos_countstr | NoneTotal uploaded videos count
genderstr | NoneStated gender identity
interested_instr | NoneSexual orientation preference
locationstr | NoneGeographical location
agestr | NoneAge of the user
relationship_statusstr | NoneRelationship status
is_pornstarboolWhether this profile represents a recognized adult performer

Methods

Get Profile Videos videos()

async
Asynchronously yields video scrape results uploaded by this user profile across listing pages.
async for result in profile.videos( pages: int | str = 2, iterator_config: IteratorConfig | None = None ) -> AsyncGenerator[ScrapeResult[Video], None]

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

AttributeTypeDescription
urlstrPornstar profile page URL
display_namestr | NonePerformer stage name
slugstr | NonePerformer URL slug identifier
avatar_urlstr | NonePerformer portrait avatar picture URL
cover_urlstr | NonePerformer cover banner image URL
biostr | NoneBiography or introduction text
rankstr | NoneSite ranking position among pornstars
profile_viewsstr | NoneAccumulated views on this pornstar profile
subscribers_countstr | NoneTotal followers and subscribers count
video_viewsstr | NoneCumulative video views across all starring videos
total_videos_countstr | NoneTotal count of videos featuring this performer
genderstr | NonePerformer gender
interested_instr | NoneSexual orientation preference
locationstr | NoneCountry or city of origin
agestr | NoneAge of the performer
relationship_statusstr | NoneRelationship status indicator
is_pornstarboolAlways True for Pornstar instances

Methods

Get Performer Videos videos()

async
Asynchronously yields video scrape results featuring or uploaded by this performer.
async for result in pornstar.videos( pages: int | str = 2, iterator_config: IteratorConfig | None = None ) -> AsyncGenerator[ScrapeResult[Video], None]

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:

python
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 MemberAPI String ValueDescription
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 MemberAPI String ValueDescription
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:

python
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:

python
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

AttributeTypeDescription
succeededboolWhether the scraping task succeeded
unwrap()VideoReturns the parsed item or raises the underlying exception
itemVideo | NoneParsed video object on success
errorScrapeOperationError | NoneTyped failure when unsuccessful
stageScrapeStageStage 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.

ExceptionTrigger Cause
NotFoundServer returned HTTP 404 (e.g. video or profile removed)
NetworkErrorRequest failed due to connection error, exhausted retries, or HTTP status error
BotDetectionCloudflare or anti-bot challenge block encountered
ProxyErrorProxy configuration error or proxy endpoint unavailable
UnknownNetworkErrorUnrecognized networking exception
DownloadFailedDownload transfer or preparation failed with full cause retained in __cause__
python
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 Sort and SortDate filters.
  • Complete CLI tool supporting direct and batch URL downloads.
  • Full compatibility with eaf-base-api>=4.2.2 networking engine.

💻 CLI Usage

TNAFlix API includes a command-line interface accessible via the tnaflix_api binary or python -m tnaflix_api:

bash
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

FlagDescription
--download URLVideo URL to download
--file FILEText file containing video URLs (newline-separated)
--quality QUALITYDesired resolution quality (best, half, worst, or height integer)
--output DIRDestination folder or file path
--no-title True/FalseSkip auto-appending video title to output filename (default: False)

🖥️ Supported Platforms

PlatformArchitectureStatus
Windows 11x64✅ Tested
macOS Sequoiax86_64 / arm64✅ Tested
Linux (Arch / Debian / Ubuntu)x86_64✅ Tested
Android (Termux)aarch64✅ Tested