Python client for Browser-Use Fetch HTTP service
Project description
fetch-use
Python client for the Browser-Use Fetch HTTP service. Routes HTTP requests through Browser-Use's proxy infrastructure with Chrome TLS fingerprinting, session-based IP persistence, and server-side cookie management.
Installation
pip install fetch-use
Quick Start
import os
from fetch_use import fetch_sync
os.environ["PROJECT_ID"] = "your-project-id"
response = fetch_sync("https://httpbin.org/get")
print(response.status_code) # 200
print(response.json())
Or async:
import asyncio
from fetch_use import fetch
async def main():
response = await fetch("https://httpbin.org/get")
print(response.json())
asyncio.run(main())
Configuration
| Variable | Required | Description |
|---|---|---|
PROJECT_ID |
Yes | Your Browser-Use project ID (used for authentication) |
SESSION_ID |
No | Session ID for IP/cookie persistence. If not set, a random UUID is generated per request (ephemeral, no persistence). |
FETCH_USE_URL |
No | Override service URL (for testing/self-hosting) |
Session Persistence
By default, each request gets a random session ID — meaning a fresh IP, fresh fingerprint, and no cookie persistence between calls.
To maintain the same IP, fingerprint, and cookies across consecutive requests, provide a consistent session ID. You can do this two ways:
Option 1: Environment variable (applies to all requests in the process):
import os
import uuid
os.environ["SESSION_ID"] = str(uuid.uuid4())
# All fetch_sync calls now share the same session automatically
page1 = fetch_sync("https://example.com/page1")
page2 = fetch_sync("https://example.com/page2") # same IP, cookies carry over
Option 2: Per-request parameter (for fine-grained control):
from fetch_use import fetch_sync
session = "my-scraping-session-1"
page1 = fetch_sync("https://example.com/page1", session_id=session)
page2 = fetch_sync("https://example.com/page2", session_id=session)
This is important when:
- A site sets cookies on the first request that subsequent requests need
- You need a consistent IP to avoid being flagged as a new visitor
- Login flows where cookies from the auth request must carry over
If you don't need persistence (independent one-off requests), you can omit SESSION_ID entirely.
Usage
Basic GET Request
from fetch_use import fetch_sync
response = fetch_sync("https://example.com")
if response.ok:
print(response.text)
POST with JSON
response = fetch_sync(
"https://api.example.com/data",
method="POST",
json_body={"name": "John", "email": "john@example.com"},
)
data = response.json()
Custom Headers and Cookies
response = fetch_sync(
"https://example.com/api",
headers={
"Authorization": "Bearer token123",
"Accept": "application/json",
},
cookies={
"session": "abc123",
},
)
Proxy Country
# Route through German proxy
response = fetch_sync("https://example.com", proxy_country="DE")
Retry Configuration
from fetch_use import fetch_sync, RetryConfig
response = fetch_sync(
"https://example.com",
retry=RetryConfig(
count=5,
on_status=[500, 502, 503, 504, 429],
backoff_ms=200,
),
)
Server-Side Cookies
Cookies are persisted server-side per session. Use the cookies parameter to add or override cookies for a specific request:
response = fetch_sync(
"https://example.com/dashboard",
cookies={"session": "my-session-cookie"},
)
Cookies set by the server (via Set-Cookie headers) are automatically persisted for subsequent requests within the same session.
Response Object
| Property | Type | Description |
|---|---|---|
status_code |
int |
HTTP status code |
status |
str |
Full status string (e.g., "200 OK") |
headers |
dict |
Response headers |
body / text |
str |
Response body as text |
content |
bytes |
Response body as bytes (handles binary) |
ok |
bool |
True if status is 2xx |
final_url |
str |
Final URL after redirects |
redirect_count |
int |
Number of redirects followed |
protocol |
str |
HTTP protocol (e.g., "HTTP/2.0") |
Methods:
json()— Parse body as JSONraise_for_status()— RaiseFetchErrorif status >= 400
Error Handling
from fetch_use import fetch_sync, FetchError
try:
response = fetch_sync("https://example.com")
response.raise_for_status()
data = response.json()
except FetchError as e:
print(f"Error: {e}")
print(f"Code: {e.code}")
print(f"Details: {e.details}")
License
MIT
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fetch_use-0.3.2.tar.gz.
File metadata
- Download URL: fetch_use-0.3.2.tar.gz
- Upload date:
- Size: 8.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64a9f00caf807d60e9ff12e3f56bec84a0839e245931e1da5c3d49655f6183d2
|
|
| MD5 |
a6c8f0a40c1e1fb4fe0f88dc16040f28
|
|
| BLAKE2b-256 |
399a45118d46b43f4fa1024dc555cdbf92a55508c395dfb39811605f36123e66
|
File details
Details for the file fetch_use-0.3.2-py3-none-any.whl.
File metadata
- Download URL: fetch_use-0.3.2-py3-none-any.whl
- Upload date:
- Size: 8.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e53f07e0d8bbdcd069f39d3babc09f8b966264f7919e2dcc3cdf77d6e741a90
|
|
| MD5 |
e6c79552c7d8f3eeb7b77d5212f12d91
|
|
| BLAKE2b-256 |
ec0fa8e2a33ca060e602b78fa314d2c61aae931026d784735a76e6b546d32d85
|