Skip to main content

HTTP client that can impersonate web browsers, mimicking their headers and `TLS/JA3/JA4/HTTP2` fingerprints

Project description

Python >= 3.8 Downloads CI

🪞PRIMP

🪞PRIMP = Python Requests IMPersonate

The fastest python HTTP client that can impersonate web browsers.
Provides precompiled wheels:

  • 🐧 linux: amd64, aarch64, armv7 (⚠️aarch64 and armv7 builds are manylinux_2_34 compatible - ubuntu>=22.04, debian>=12);
  • 🐧 musllinux: amd64, aarch64;
  • 🪟 windows: amd64;
  • 🍏 macos: amd64, aarch64.

Table of Contents

Installation

pip install -U primp

Benchmark

Usage

I. Client

HTTP client that can impersonate web browsers.

class Client:
    """Initializes an HTTP client that can impersonate web browsers.

    Args:
        auth (tuple[str, str| None] | None): Username and password for basic authentication. Default is None.
        auth_bearer (str | None): Bearer token for authentication. Default is None.
        params (dict[str, str] | None): Default query parameters to include in all requests. Default is None.
        headers (dict[str, str] | None): Default headers to send with requests. If `impersonate` is set, this will be ignored.
        timeout (float | None): HTTP request timeout in seconds. Default is 30.
        cookie_store (bool | None): Enable a persistent cookie store. Received cookies will be preserved and included
            in additional requests. Default is True.
        referer (bool | None): Enable or disable automatic setting of the `Referer` header. Default is True.
        proxy (str | None): Proxy URL for HTTP requests. Example: "socks5://127.0.0.1:9150". Default is None.
        impersonate (str | None): Entity to impersonate. Example: "chrome_124". Default is None.
            Chrome: "chrome_100","chrome_101","chrome_104","chrome_105","chrome_106","chrome_107","chrome_108",
                "chrome_109","chrome_114","chrome_116","chrome_117","chrome_118","chrome_119","chrome_120",
                "chrome_123","chrome_124","chrome_126","chrome_127","chrome_128","chrome_129","chrome_130",
                "chrome_131","chrome_133"
            Safari: "safari_ios_16.5","safari_ios_17.2","safari_ios_17.4.1","safari_ios_18.1.1",
                "safari_15.3","safari_15.5","safari_15.6.1","safari_16","safari_16.5","safari_17.0",
                "safari_17.2.1","safari_17.4.1","safari_17.5","safari_18","safari_18.2","safari_ipad_18"
            OkHttp: "okhttp_3.9","okhttp_3.11","okhttp_3.13","okhttp_3.14","okhttp_4.9","okhttp_4.10","okhttp_5"
            Edge: "edge_101","edge_122","edge_127","edge_131"
            Firefox: "firefox_109","firefox_117","firefox_128","firefox_133","firefox_135"
        impersonate_os (str | None): impersonate OS. Example: "windows". Default is "linux".
            Android: "android", iOS: "ios", Linux: "linux", Mac OS: "macos", Windows: "windows"
        follow_redirects (bool | None): Whether to follow redirects. Default is True.
        max_redirects (int | None): Maximum redirects to follow. Default 20. Applies if `follow_redirects` is True.
        verify (bool | None): Verify SSL certificates. Default is True.
        ca_cert_file (str | None): Path to CA certificate store. Default is None.
        https_only` (bool | None): Restrict the Client to be used with HTTPS only requests. Default is `false`.
        http2_only` (bool | None): If true - use only HTTP/2; if false - use only HTTP/1. Default is `false`.

    """

Client methods

The Client class provides a set of methods for making HTTP requests: get, head, options, delete, post, put, patch, each of which internally utilizes the request() method for execution. The parameters for these methods closely resemble those in httpx.

def get(
    url: str,
    params: dict[str, str] | None = None,
    headers: dict[str, str] | None = None,
    cookies: dict[str, str] | None = None,
    auth: tuple[str, str| None] | None = None,
    auth_bearer: str | None = None,
    timeout: float | None = 30,
):
    """Performs a GET request to the specified URL.

    Args:
        url (str): The URL to which the request will be made.
        params (dict[str, str] | None): A map of query parameters to append to the URL. Default is None.
        headers (dict[str, str] | None): A map of HTTP headers to send with the request. Default is None.
        cookies (dict[str, str] | None): - An optional map of cookies to send with requests as the `Cookie` header.
        auth (tuple[str, str| None] | None): A tuple containing the username and an optional password
            for basic authentication. Default is None.
        auth_bearer (str | None): A string representing the bearer token for bearer token authentication. Default is None.
        timeout (float | None): The timeout for the request in seconds. Default is 30.

    """
def post(
    url: str,
    params: dict[str, str] | None = None,
    headers: dict[str, str] | None = None,
    cookies: dict[str, str] | None = None,
    content: bytes | None = None,
    data: dict[str, Any] | None = None,
    json: Any | None = None,
    files: dict[str, str] | None = None,
    auth: tuple[str, str| None] | None = None,
    auth_bearer: str | None = None,
    timeout: float | None = 30,
):
    """Performs a POST request to the specified URL.

    Args:
        url (str): The URL to which the request will be made.
        params (dict[str, str] | None): A map of query parameters to append to the URL. Default is None.
        headers (dict[str, str] | None): A map of HTTP headers to send with the request. Default is None.
        cookies (dict[str, str] | None): - An optional map of cookies to send with requests as the `Cookie` header.
        content (bytes | None): The content to send in the request body as bytes. Default is None.
        data (dict[str, Any] | None): The form data to send in the request body. Default is None.
        json (Any | None): A JSON serializable object to send in the request body. Default is None.
        files (dict[str, str] | None): A map of file fields to file paths to be sent as multipart/form-data. Default is None.
        auth (tuple[str, str| None] | None): A tuple containing the username and an optional password
            for basic authentication. Default is None.
        auth_bearer (str | None): A string representing the bearer token for bearer token authentication. Default is None.
        timeout (float | None): The timeout for the request in seconds. Default is 30.

    """

Response object

resp.content
resp.stream()  # stream the response body in chunks of bytes
resp.cookies
resp.encoding
resp.headers
resp.json()
resp.status_code
resp.text
resp.text_markdown  # html is converted to markdown text
resp.text_plain  # html is converted to plain text
resp.text_rich  # html is converted to rich text
resp.url

Devices

Impersonate
  • Chrome: chrome_100chrome_101chrome_104chrome_105chrome_106chrome_107chrome_108chrome_109chrome_114chrome_116chrome_117chrome_118chrome_119chrome_120chrome_123chrome_124chrome_126chrome_127chrome_128chrome_129chrome_130chrome_131, chrome_133

  • Edge: edge_101edge_122edge_127, edge_131

  • Safari: safari_ios_17.2safari_ios_17.4.1safari_ios_16.5safari_ios_18.1.1, safari_15.3safari_15.5safari_15.6.1safari_16safari_16.5safari_17.0safari_17.2.1safari_17.4.1safari_17.5safari_18safari_18.2, safari_ipad_18

  • OkHttp: okhttp_3.9okhttp_3.11okhttp_3.13okhttp_3.14okhttp_4.9okhttp_4.10okhttp_5

  • Firefox: firefox_109, firefox_117, firefox_128, firefox_133, firefox_135

Impersonate OS
  • android, ios, linux, macos, windows

Examples

import primp

# Impersonate
client = primp.Client(impersonate="chrome_131", impersonate_os="windows")

# GET request
resp = client.get("https://tls.peet.ws/api/all")

# GET request with passing params and setting timeout
params = {"param1": "value1", "param2": "value2"}
resp = client.post(url="https://httpbin.org/anything", params=params, timeout=10)

# Stream response
resp = client.get("https://nytimes")
for chunk in resp.stream():
    print(chunk)

# Cookies set
cookies = {"c1_n": "c1_value", "c2_n": "c2_value"}
client.set_cookies(url="https://nytimes.com", cookies) # set cookies for a specific domain
client.get("https://nytimes.com/", cookies=cookies)  # set cookies in request

# Cookies get
cookies = client.get_cookies(url="https://nytimes.com")  # get cookies for a specific domain
cookies = resp.cookies  # get cookies from response

# POST Binary Request Data
content = b"some_data"
resp = client.post(url="https://httpbin.org/anything", content=content)

# POST Form Encoded Data
data = {"key1": "value1", "key2": "value2"}
resp = client.post(url="https://httpbin.org/anything", data=data)

# POST JSON Encoded Data
json = {"key1": "value1", "key2": "value2"}
resp = client.post(url="https://httpbin.org/anything", json=json)

# POST Multipart-Encoded Files
files = {'file1': '/home/root/file1.txt', 'file2': 'home/root/file2.txt'}
resp = client.post("https://httpbin.org/post", files=files)

# Authentication using user/password
resp = client.post(url="https://httpbin.org/anything", auth=("user", "password"))

# Authentication using auth bearer
resp = client.post(url="https://httpbin.org/anything", auth_bearer="bearerXXXXXXXXXXXXXXXXXXXX")

# Using proxy or env var PRIMP_PROXY
resp = primp.Client(proxy="http://127.0.0.1:8080")  # set proxy in Client
export PRIMP_PROXY="socks5://127.0.0.1:1080"  # set proxy as environment variable

# Using custom CA certificate store:
#(!!!Primp already built with the Mozilla's latest trusted root certificates)
resp = primp.Client(ca_cert_file="/cert/cacert.pem")
resp = primp.Client(ca_cert_file=certifi.where())
export PRIMP_CA_BUNDLE="/home/user/Downloads/cert.pem"  # set as environment variable

# You can also use convenience functions that use a default Client instance under the hood:
# primp.get() | primp.head() | primp.options() | primp.delete() | primp.post() | primp.patch() | primp.put()
# These functions can accept the `impersonate` parameter:
resp = primp.get("https://httpbin.org/anything", impersonate="chrome_131", impersonate_os="android")

II. AsyncClient

primp.AsyncClient() is an asynchronous wrapper around the primp.Client class, offering the same functions, behavior, and input arguments.

import asyncio
import logging

import primp

async def aget_text(url):
    async with primp.AsyncClient(impersonate="chrome_131") as client:
        resp = await client.get(url)
        return resp.text

async def main():
    urls = ["https://nytimes.com/", "https://cnn.com/", "https://abcnews.go.com/"]
    tasks = [aget_text(u) for u in urls]
    results = await asyncio.gather(*tasks)

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.run(main())

Disclaimer

This tool is for educational purposes only. Use it at your own risk.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

primp-0.14.0.tar.gz (112.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

primp-0.14.0-cp38-abi3-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.8+Windows x86-64

primp-0.14.0-cp38-abi3-musllinux_1_2_x86_64.whl (3.6 MB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ x86-64

primp-0.14.0-cp38-abi3-musllinux_1_2_aarch64.whl (3.4 MB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ ARM64

primp-0.14.0-cp38-abi3-manylinux_2_34_armv7l.whl (3.0 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.34+ ARMv7l

primp-0.14.0-cp38-abi3-manylinux_2_34_aarch64.whl (3.2 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.34+ ARM64

primp-0.14.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.3 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

primp-0.14.0-cp38-abi3-macosx_11_0_arm64.whl (2.9 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

primp-0.14.0-cp38-abi3-macosx_10_12_x86_64.whl (3.2 MB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file primp-0.14.0.tar.gz.

File metadata

  • Download URL: primp-0.14.0.tar.gz
  • Upload date:
  • Size: 112.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.8.2

File hashes

Hashes for primp-0.14.0.tar.gz
Algorithm Hash digest
SHA256 b6f23b2b694118a9d0443b3760698b90afb6f867f8447e71972530f48297992e
MD5 82591e3f2b74ad76f4a0dfa848ccced2
BLAKE2b-256 951ea063129aed2320b463fd35c5d918d5754e59011698aaf7cf297a610b3380

See more details on using hashes here.

File details

Details for the file primp-0.14.0-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: primp-0.14.0-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 3.1 MB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.8.2

File hashes

Hashes for primp-0.14.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 d3ae1ba954ec8d07abb527ccce7bb36633525c86496950ba0178e44a0ea5c891
MD5 8c84d79ff458256d16cdc27b743de8c9
BLAKE2b-256 6a20042c8ae21d185f2efe61780dfbc01464c982f59626b746d5436c2e4c1e08

See more details on using hashes here.

File details

Details for the file primp-0.14.0-cp38-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for primp-0.14.0-cp38-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 6549766ece3c7be19e1c16fa9029d3e50fa73628149d88601fcd964af8b44a8d
MD5 0add4b98b430ab1f5111540d50a54964
BLAKE2b-256 d7d33bee499b4594fce1f8ccede785e517162407fbea1d452c4fb55fe3fb5e81

See more details on using hashes here.

File details

Details for the file primp-0.14.0-cp38-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for primp-0.14.0-cp38-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 b0b21e6a599f580137774623009c7f895afab49d6c3d6c9a28344fd2586ebe8a
MD5 4963f0266e0524dac29088994cb50d70
BLAKE2b-256 dcba07b04b9d404f20ec78449c5974c988a5adf7d4d245a605466486f70d35c3

See more details on using hashes here.

File details

Details for the file primp-0.14.0-cp38-abi3-manylinux_2_34_armv7l.whl.

File metadata

File hashes

Hashes for primp-0.14.0-cp38-abi3-manylinux_2_34_armv7l.whl
Algorithm Hash digest
SHA256 3fb204f67a4b58dc53f3452143121317b474437812662ac0149d332a77ecbe1a
MD5 5c78239ef867b5429dd832aa7ff7f3b0
BLAKE2b-256 31d9632a70c80dcdd0bb9293cdc7e7543d35e5912325631c3e9f3b7c7d842941

See more details on using hashes here.

File details

Details for the file primp-0.14.0-cp38-abi3-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for primp-0.14.0-cp38-abi3-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 8f56ca2cd63f9ac75b33bf48129b7e79ade29cf280bc253b17b052afb27d2b9e
MD5 ca83be96a123c72d0f914217a403be9c
BLAKE2b-256 4436bc95049264ee668a5cdaadf77ef711aaa9cb0c4c0a246b27bba9a2f0114c

See more details on using hashes here.

File details

Details for the file primp-0.14.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for primp-0.14.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 11229e65aa5755fdfb535cc03fd64259a06764ad7c22e650fb3bea51400f1d09
MD5 41b178174042152902826938d1d777be
BLAKE2b-256 1377f85bc3e31befa9b9bac54bab61beb34ff84a70d20f02b7dcd8abc120120a

See more details on using hashes here.

File details

Details for the file primp-0.14.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for primp-0.14.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 31eecb5316f9bd732a7994530b85eb698bf6500d2f6c5c3382dac0353f77084e
MD5 46842f7728091f5c4b7c237536381b89
BLAKE2b-256 77653cd25b4f4d0cd9de4f1d95858dcddd7ed082587524294c179c847de18951

See more details on using hashes here.

File details

Details for the file primp-0.14.0-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for primp-0.14.0-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 bd2dfb57feeba21a77a1128b6c6f17856605c4e73edcc05764fb134de4ff014f
MD5 ae1000e9c39fd8870265675b5fe8df06
BLAKE2b-256 7f12eba13ddbeb5c6df6cf7511aedb5fa4bcb99c0754e88056260dd44aa53929

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page