Skip to content

User-Agent API Reference

Auto-generated API documentation for the User-Agent generator module.

useragent

Lightweight User-Agent generator for Chrome/Edge with Client Hints.

Part of zerodep: https://github.com/Oaklight/zerodep Copyright (c) 2026 Peng Ding. MIT License.

Generates realistic browser UA strings and matching Sec-CH-UA-* headers. Covers Windows, macOS, Linux (desktop) and Android (mobile) platforms with Chrome and Edge browsers only -- this is intentionally minimal.

Inspired by ua-generator <https://github.com/iamdual/ua-generator>_ (Apache-2.0).

Zero external dependencies -- stdlib random only.

Basic usage::

from useragent import generate

ua = generate(browser="chrome", device="desktop")
print(ua.text)        # full User-Agent string
print(ua.headers.get())  # dict with UA + Client Hints headers

UserAgent

A generated user-agent with matching Client Hints headers.

Attributes:

Name Type Description
browser

Browser name ("chrome" or "edge").

platform

Platform name ("windows", "macos", "linux", or "android").

version

4-tuple (major, minor, build, patch).

text

The full User-Agent string.

headers

A :class:_Headers instance for Client Hints.

Example::

ua = generate(browser=["chrome", "edge"])
ua.headers.accept_ch("Sec-CH-UA-Platform-Version")
headers = ua.headers.get()
Source code in useragent/useragent.py
class UserAgent:
    """A generated user-agent with matching Client Hints headers.

    Attributes:
        browser: Browser name (``"chrome"`` or ``"edge"``).
        platform: Platform name (``"windows"``, ``"macos"``, ``"linux"``,
            or ``"android"``).
        version: 4-tuple ``(major, minor, build, patch)``.
        text: The full User-Agent string.
        headers: A :class:`_Headers` instance for Client Hints.

    Example::

        ua = generate(browser=["chrome", "edge"])
        ua.headers.accept_ch("Sec-CH-UA-Platform-Version")
        headers = ua.headers.get()
    """

    def __init__(
        self,
        *,
        browser: str,
        platform: str,
        version: tuple[int, int, int, int],
        ua_string: str,
    ) -> None:
        self.browser = browser
        self.platform = platform
        self.version = version
        self.text = ua_string
        self.headers = _Headers(self)

    # -- Client Hints data methods --

    def _is_mobile(self) -> bool:
        return self.platform in _MOBILE_PLATFORMS

    def _ch_platform_name(self) -> str:
        mapping = {
            "windows": "Windows",
            "macos": "macOS",
            "linux": "Linux",
            "android": "Android",
        }
        return mapping.get(self.platform, self.platform.title())

    def _ch_platform_version(self) -> str:
        if self.platform == "windows":
            lo, hi = random.choice(_WINDOWS_VERSIONS)[1]
            return f"{random.randint(lo, hi)}.0.0"
        if self.platform == "macos":
            mv = random.choice(_MACOS_VERSIONS)
            return f"{mv[0]}.{mv[1]}.{random.randint(0, max(mv[2], 1))}"
        if self.platform == "android":
            return f"{random.randint(12, 16)}.0.0"
        # Linux
        return ""

    def _ch_brands(self, full_version: bool = False) -> list[dict[str, str]]:
        ver_str = _fmt_ver(self.version) if full_version else str(self.version[0])
        filler_ver = "99.0.0.0" if full_version else "99"
        brands: list[dict[str, str]] = [{"brand": "Not A(Brand", "version": filler_ver}]
        if self.browser == "chrome":
            brands.append({"brand": "Chromium", "version": ver_str})
            brands.append({"brand": "Google Chrome", "version": ver_str})
        elif self.browser == "edge":
            brands.append({"brand": "Chromium", "version": ver_str})
            brands.append({"brand": "Microsoft Edge", "version": ver_str})
        return brands

    def _ch_architecture(self) -> str:
        if self.platform in ("android",):
            return "arm"
        if self.platform == "macos":
            return random.choice(("arm", "x86", "arm", "arm"))
        return "x86"

    def _ch_bitness(self) -> str:
        if self.platform == "android":
            return random.choice(("32", "64", "32", "32"))
        return "64"

    def _ch_model(self) -> str:
        if self.platform == "android":
            return random.choice(_ANDROID_MODELS)
        return ""

    def __str__(self) -> str:
        return self.text

    def __repr__(self) -> str:
        return f"UserAgent(browser={self.browser!r}, platform={self.platform!r})"

generate(*, browser=None, device=None)

Generate a random User-Agent with matching Client Hints.

Parameters:

Name Type Description Default
browser Union[str, Sequence[str]] | None

Browser name or list of names to pick from. Supported: "chrome", "edge". Defaults to both.

None
device str | None

Device type -- "desktop" or "mobile". Defaults to random selection across all platforms.

None

Returns:

Name Type Description
A UserAgent

class:UserAgent instance.

Raises:

Type Description
ValueError

If browser is not "chrome" or "edge".

Source code in useragent/useragent.py
def generate(
    *,
    browser: Union[str, Sequence[str]] | None = None,
    device: str | None = None,
) -> UserAgent:
    """Generate a random User-Agent with matching Client Hints.

    Args:
        browser: Browser name or list of names to pick from.
            Supported: ``"chrome"``, ``"edge"``. Defaults to both.
        device: Device type -- ``"desktop"`` or ``"mobile"``.
            Defaults to random selection across all platforms.

    Returns:
        A :class:`UserAgent` instance.

    Raises:
        ValueError: If *browser* is not ``"chrome"`` or ``"edge"``.
    """
    # Resolve browser
    if browser is None:
        chosen_browser = random.choice(("chrome", "edge"))
    elif isinstance(browser, str):
        chosen_browser = browser
    else:
        chosen_browser = random.choice(list(browser))

    if chosen_browser not in ("chrome", "edge"):
        raise ValueError(f"Unsupported browser: {chosen_browser!r}")

    # Resolve platform
    platform = _pick_platform(device)

    # Pick version
    if chosen_browser == "chrome":
        ver = _pick_chrome_version()
    else:
        ver = _pick_edge_version()

    ua_string = _build_ua_string(chosen_browser, platform, ver)
    return UserAgent(
        browser=chosen_browser, platform=platform, version=ver, ua_string=ua_string
    )