User Guide¶
Sync client¶
from gakido import Client
with Client(impersonate="chrome_120") as c:
r = c.get("https://httpbin.org/get", headers={"Accept-Encoding": "identity"})
print(r.status_code, r.json())
POST / multipart upload¶
files = {"file": ("test.txt", b"hello", "text/plain")}
data = {"foo": "bar"}
with Client() as c:
r = c.post("https://httpbin.org/post", data=data, files=files)
print(r.json())
Async client¶
import asyncio
from gakido.aio import AsyncClient
async def main():
async with AsyncClient(impersonate="chrome_120") as c:
r = await c.get("https://httpbin.org/get")
print(r.status_code)
asyncio.run(main())
Profiles & impersonation¶
from gakido import Client
c = Client(impersonate="firefox_133")
r = c.get("https://tls.browserleaks.com/json")
print(r.json().get("ja3_hash"))
Client Hints & Fingerprints¶
Chrome and Edge profiles automatically include Sec-CH-UA client hints for better impersonation:
from gakido import Client
from gakido.impersonation import get_profile, get_client_hints_headers
# Client hints are sent automatically
with Client(impersonate="chrome_120") as c:
r = c.get("https://httpbin.org/headers")
# Headers include: Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform
# Access client hints and fingerprint data
profile = get_profile("chrome_120")
hints = get_client_hints_headers(profile, include_high_entropy=True)
print(hints)
# {'Sec-CH-UA': '"Not_A Brand";v="8", ...', 'Sec-CH-UA-Platform': '"macOS"', ...}
# Access Canvas/WebGL fingerprint
from gakido.impersonation import get_canvas_webgl_fingerprint
fp = get_canvas_webgl_fingerprint(profile)
print(fp["webgl_renderer"]) # "ANGLE (Apple, ANGLE Metal Renderer: ...)"
See Client Hints & Browser Fingerprints for full documentation.
TLS overrides (JA3/Akamai style)¶
from gakido import Client, ExtraFingerprints
ja3_str = "771,4866-4867-4865-49196,0-11-10,29,0"
extra_fp = ExtraFingerprints(alpn=["http/1.1"])
with Client(
tls_configuration_options={
"ja3_str": ja3_str,
"extra_fp": extra_fp,
},
ja3={"alpn": ["http/1.1"]},
) as c:
r = c.get("https://tls.browserleaks.com/json", headers={"Accept-Encoding": "identity"})
print(r.json())
WebSocket¶
from gakido.websocket import WebSocket
ws = WebSocket.connect("echo.websocket.events", 443, "/", headers=[], tls=True)
ws.send_text("hello")
opcode, payload = ws.recv()
print(payload.decode())
ws.close()
Compression¶
Gakido automatically handles response compression using profile-based content negotiation.
Default Behavior (auto_decompress=True)¶
from gakido import Client
# Uses profile's Accept-Encoding: "gzip, deflate, br"
# Automatically decompresses responses
with Client(impersonate="chrome_120") as c:
r = c.get("https://httpbin.org/gzip")
print(r.json()) # Already decompressed
Disable Compression¶
from gakido import Client
# Sends Accept-Encoding: identity
# Returns raw, uncompressed responses
with Client(auto_decompress=False) as c:
r = c.get("https://example.com")
print(r.content) # Raw bytes
Custom Accept-Encoding¶
from gakido import Client
# Override Accept-Encoding per request
with Client() as c:
r = c.get("https://example.com", headers={"Accept-Encoding": "gzip"})
Supported Encodings¶
- gzip - GNU zip compression
- deflate - zlib/deflate compression
- br - Brotli compression (included via
brotlipackage)
HTTP/3 (QUIC)¶
HTTP/3 uses QUIC as the transport layer, providing improved performance for Cloudflare and CDN targets through 0-RTT connection establishment and multiplexed streams.
Installation¶
Basic Usage¶
import asyncio
from gakido import AsyncClient, is_http3_available
async def main():
# Check if HTTP/3 is available
if not is_http3_available():
print("Install HTTP/3 support: pip install gakido[h3]")
return
async with AsyncClient(
impersonate="chrome_120",
http3=True, # Enable HTTP/3
http3_fallback=True, # Fall back to H1/H2 if H3 fails
force_http1=False, # Allow H2 as fallback
) as client:
response = await client.get("https://cloudflare.com/cdn-cgi/trace")
print(f"HTTP/{response.http_version}: {response.status_code}")
print(response.text)
asyncio.run(main())
Force HTTP/3 for Specific Requests¶
async with AsyncClient(http3=True) as client:
# Use client default (HTTP/3 with fallback)
r1 = await client.get("https://example.com")
# Force HTTP/3 for this specific request (no fallback)
r2 = await client.request("GET", "https://cloudflare.com", force_http3=True)
HTTP/3 Benefits¶
- 0-RTT Connection: Faster initial requests with QUIC's zero round-trip handshake
- No Head-of-Line Blocking: Multiplexed streams don't block each other
- Connection Migration: Survives network changes (WiFi to cellular)
- Built-in Encryption: TLS 1.3 integrated into the protocol