Headers¶
Browser profile definitions for pyfetcher.
- Purpose:
Define complete browser identity profiles that bundle User-Agent strings with matching Client Hints (Sec-CH-UA-), Sec-Fetch- metadata, and Accept headers into coherent, realistic browser identities. Profiles ensure that all identity-related headers are internally consistent, which is critical for avoiding detection by anti-bot systems.
- Design:
Each profile represents a specific browser + version + platform combination.
Headers within a profile are guaranteed to be mutually consistent (e.g. a Chrome UA will have matching Sec-CH-UA and platform values).
Profiles are immutable dataclass instances for safety and hashability.
The
get_profilefunction selects profiles by name;list_profilesenumerates all available profile names.
Examples
>>> profile = get_profile("chrome_win")
>>> "Chrome" in profile.user_agent
True
>>> profile.platform
'Windows'
- class pyfetcher.headers.profiles.BrowserProfile(name, browser, platform, mobile=False, user_agent='', sec_ch_ua='', sec_ch_ua_full_version_list='', sec_ch_ua_mobile='?0', sec_ch_ua_platform='""', sec_ch_ua_platform_version='""', sec_ch_ua_model='""', accept='text/html, application/xhtml+xml, application/xml;q=0.9, image/avif, image/webp, image/apng, */*;q=0.8', accept_language_options=('en-US, en;q=0.9', 'en-US, en;q=0.8', 'en-GB, en;q=0.9', 'en-CA, en;q=0.9', 'en-AU, en;q=0.9'), accept_encoding='gzip, deflate, br, zstd', sec_fetch_dest='document', sec_fetch_mode='navigate', sec_fetch_site='none', sec_fetch_user='?1', upgrade_insecure_requests='1', extra_headers=<factory>)[source]¶
A complete browser identity profile.
Bundles all headers that form a browser’s identity fingerprint into a single coherent object. Anti-bot systems check for consistency across these headers, so they must all agree on browser type, version, and platform.
- Parameters:
name (str) – Unique profile identifier (e.g.
'chrome_win').browser (str) – Browser family name (e.g.
'chrome','firefox','safari').platform (str) – Operating system name (e.g.
'Windows','macOS','Linux').mobile (bool) – Whether this is a mobile browser profile.
user_agent (str) – The User-Agent header string.
sec_ch_ua (str) – The
Sec-CH-UAclient hint header value.sec_ch_ua_full_version_list (str) – The
Sec-CH-UA-Full-Version-Listheader.sec_ch_ua_mobile (str) – The
Sec-CH-UA-Mobileheader ('?0'or'?1').sec_ch_ua_platform (str) – The
Sec-CH-UA-Platformheader (quoted string).sec_ch_ua_platform_version (str) – The
Sec-CH-UA-Platform-Versionheader.sec_ch_ua_model (str) – The
Sec-CH-UA-Modelheader (empty for desktop).accept (str) – The
Acceptheader for document requests.accept_language_options (tuple[str, ...]) – Pool of
Accept-Languagevalues for randomization.accept_encoding (str) – The
Accept-Encodingheader value.sec_fetch_dest (str) – Default
Sec-Fetch-Destvalue.sec_fetch_mode (str) – Default
Sec-Fetch-Modevalue.sec_fetch_site (str) – Default
Sec-Fetch-Sitevalue.sec_fetch_user (str) – Default
Sec-Fetch-Uservalue.upgrade_insecure_requests (str) – The
Upgrade-Insecure-Requestsheader.extra_headers (dict[str, str]) – Additional browser-specific headers.
Examples
>>> profile = BrowserProfile( ... name="test", browser="chrome", platform="Windows", ... user_agent="Mozilla/5.0", sec_ch_ua='"Chrome";v="133"', ... sec_ch_ua_full_version_list='"Chrome";v="133.0"', ... sec_ch_ua_mobile="?0", sec_ch_ua_platform='"Windows"', ... sec_ch_ua_platform_version='"10.0.0"', ... ) >>> profile.browser 'chrome'
- to_headers()[source]¶
Convert this profile to a complete headers dictionary.
Returns a dictionary containing all identity-related headers appropriate for a top-level navigation request. The
Accept-Encodingheader is intentionally omitted because transport libraries (httpx, aiohttp) handle content negotiation and decompression automatically.Examples
>>> profile = get_profile("chrome_win") >>> headers = profile.to_headers() >>> "user-agent" in headers True
- pyfetcher.headers.profiles.get_profile(name)[source]¶
Get a browser profile by name.
- Parameters:
name (str) – Profile name (e.g.
'chrome_win','firefox_mac').- Returns:
The matching
BrowserProfileinstance.- Raises:
KeyError – If no profile matches the given name.
- Return type:
Examples
>>> get_profile("chrome_win").browser 'chrome'
- pyfetcher.headers.profiles.list_profiles()[source]¶
List all available profile names.
Examples
>>> "chrome_win" in list_profiles() True
Browser-like header providers for pyfetcher.
- Purpose:
Provide header providers that generate realistic browser-like headers using the profile system. Supports both fixed-profile and randomized header generation with small per-request variations.
- Design:
Browser profiles are sourced from
pyfetcher.headers.profiles.Small randomized fields (Accept-Language, color scheme preference) are applied at build time to add realistic variation.
Providers remain separate from transport and retry concerns.
Examples
>>> provider = BrowserHeaderProvider("chrome_win")
>>> headers = provider.build(request=FetchRequest(url="https://example.com"))
>>> "user-agent" in headers
True
- pyfetcher.headers.browser.get_best_browser_headers(impersonate='chrome_win')[source]¶
Return browser-like headers with small randomized fields.
Generates a complete set of browser headers from the named profile, then adds randomized
Accept-LanguageandSec-CH-Prefers-Color-Schemevalues for realistic per-request variation.- Parameters:
impersonate (str) – Profile name or legacy alias.
- Returns:
A browser-like headers dictionary suitable for HTTP requests.
- Return type:
Examples
>>> headers = get_best_browser_headers("chrome_win") >>> "accept-language" in headers True
- class pyfetcher.headers.browser.BrowserHeaderProvider(impersonate='chrome_win')[source]¶
Provide browser-like headers for fetch requests.
Wraps a browser profile and generates consistent, realistic headers for every request. Per-request headers from the
FetchRequesttake precedence over profile headers when both are present.- Parameters:
impersonate (str) – Profile name or legacy alias (default
'chrome_win').
Examples
>>> provider = BrowserHeaderProvider("chrome_win") >>> headers = provider.build(request=FetchRequest(url="https://example.com")) >>> "user-agent" in headers True
- property profile: BrowserProfile¶
Return the resolved browser profile.
- Returns:
The
BrowserProfileused by this provider.
- build(*, request)[source]¶
Build browser-like headers for the given request.
Generates headers from the profile, adds randomized variation, then merges with any per-request headers (request headers win on conflict).
- Parameters:
request (FetchRequest) – The fetch request for which to build headers.
- Returns:
A complete headers dictionary.
- Return type:
Examples
>>> provider = BrowserHeaderProvider() >>> headers = provider.build(request=FetchRequest(url="https://example.com")) >>> "accept" in headers True
Rotating header provider for pyfetcher.
- Purpose:
Provide a header provider that rotates through browser profiles to distribute requests across multiple browser identities, reducing the likelihood of fingerprint-based blocking.
- Design:
Rotation happens at the session level: a profile is selected per call and all headers for that request are internally consistent.
Profile selection uses market-share weights by default but can be configured with an explicit profile list.
The provider maintains no mutable state beyond the configuration, so it is safe to share across threads/tasks.
Examples
>>> provider = RotatingHeaderProvider()
>>> headers = provider.build(request=FetchRequest(url="https://example.com"))
>>> "user-agent" in headers
True
- class pyfetcher.headers.rotating.RotatingHeaderProvider(profiles=None, weights=None)[source]¶
Header provider that rotates through browser profiles.
Each call to
build()selects a random profile from the configured pool (weighted by market share) and returns a complete, internally consistent set of headers for that browser identity.- Parameters:
profiles (list[BrowserProfile] | None) – Optional list of profiles to rotate through. Defaults to all desktop profiles.
weights (list[float] | None) – Optional list of weights for profile selection. Must have the same length as
profiles. Defaults to market-share weights.
Examples
>>> provider = RotatingHeaderProvider() >>> headers = provider.build(request=FetchRequest(url="https://example.com")) >>> "user-agent" in headers True
- property profiles: list[BrowserProfile]¶
Return the configured profile pool.
- Returns:
The list of profiles available for rotation.
- build(*, request)[source]¶
Build headers using a randomly selected browser profile.
Selects a profile, generates its full header set with randomized variation, then merges per-request headers on top.
- Parameters:
request (FetchRequest) – The fetch request for which to build headers.
- Returns:
A complete headers dictionary from the selected profile.
- Return type:
Examples
>>> provider = RotatingHeaderProvider() >>> headers = provider.build(request=FetchRequest(url="https://example.com")) >>> "accept" in headers True
Static header providers for pyfetcher.
- Purpose:
Provide the simplest possible provider that always returns the same header set regardless of the request.
Examples
>>> provider = StaticHeaderProvider({"user-agent": "ua"})
>>> provider.build(request=FetchRequest(url="https://example.com"))["user-agent"]
'ua'
- class pyfetcher.headers.static.StaticHeaderProvider(headers)[source]¶
Always return the same header set.
Useful for testing or when a fixed set of headers is required for all requests (e.g. an API token header).
Examples
>>> provider = StaticHeaderProvider({"x-demo": "1"}) >>> provider.build(request=FetchRequest(url="https://example.com"))["x-demo"] '1'
User-Agent generation utilities for pyfetcher.
- Purpose:
Provide functions for generating realistic User-Agent strings and selecting random profiles weighted by real-world browser market share.
- Design:
User-Agent generation leverages the profile system for consistency.
Random selection uses market-share weights to produce realistic distributions of browser identities.
All randomization is done at the function call level, so each call may produce a different result.
Examples
>>> ua = random_user_agent()
>>> "Mozilla" in ua
True
- pyfetcher.headers.ua.random_user_agent(*, browser=None, platform=None, mobile=None)[source]¶
Generate a random realistic User-Agent string.
Optionally filter by browser family, platform, or mobile/desktop. When no filters are specified, profiles are selected using real-world market share weights.
- Parameters:
browser (str | None) – Filter to a specific browser family (e.g.
'chrome','firefox','safari','edge'). Case-insensitive.platform (str | None) – Filter to a specific platform (e.g.
'Windows','macOS','Linux','Android','iOS'). Case-insensitive.mobile (bool | None) – If
True, only mobile profiles. IfFalse, only desktop profiles. IfNone, any profile.
- Returns:
A realistic User-Agent string.
- Raises:
ValueError – If no profiles match the given filters.
- Return type:
Examples
>>> ua = random_user_agent(browser="chrome") >>> "Chrome" in ua True >>> ua = random_user_agent(mobile=True) >>> "Mobile" in ua or "iPhone" in ua True
- pyfetcher.headers.ua.random_profile(*, browser=None, platform=None, mobile=None)[source]¶
Select a random browser profile, optionally filtered.
Profiles are selected using market-share weights when no filters are applied. When filters narrow the candidate set, weights are renormalized across matching profiles.
- Parameters:
- Returns:
A randomly selected
BrowserProfile.- Raises:
ValueError – If no profiles match the given filters.
- Return type:
Examples
>>> profile = random_profile(browser="firefox") >>> profile.browser 'firefox'
- pyfetcher.headers.ua.user_agents_for_browser(browser)[source]¶
Return all User-Agent strings for a given browser family.
- Parameters:
browser (str) – Browser family name (case-insensitive).
- Returns:
A list of User-Agent strings.
- Return type:
Examples
>>> uas = user_agents_for_browser("chrome") >>> all("Chrome" in ua for ua in uas) True
Base header-provider protocols for pyfetcher.
- Purpose:
Define the small protocol surface used by fetch services to obtain headers for a request. Any object with a
buildmethod accepting aFetchRequestand returning adict[str, str]satisfies the protocol.
Examples
>>> from pyfetcher.headers.static import StaticHeaderProvider
>>> provider = StaticHeaderProvider({"x-test": "1"})
>>> hasattr(provider, "build")
True
- class pyfetcher.headers.base.HeaderProvider(*args, **kwargs)[source]¶
Protocol for header-provider strategies.
Any object that implements
build(*, request: FetchRequest) -> dict[str, str]satisfies this protocol and can be used withFetchService.Examples
>>> from pyfetcher.headers.static import StaticHeaderProvider >>> provider = StaticHeaderProvider({"user-agent": "test"}) >>> provider.build(request=FetchRequest(url="https://example.com"))["user-agent"] 'test'