pythonlib: Release to PyPi, Update README

This commit is contained in:
daijro 2024-09-19 04:52:18 -05:00
parent 581cb5ce3f
commit 3488008311
9 changed files with 65 additions and 24 deletions

View file

@ -21,8 +21,8 @@ Camoufox aims to be a minimalistic browser for robust fingerprint injection & an
- Custom Playwright Juggler implementation for the latest Firefox ✅ - Custom Playwright Juggler implementation for the latest Firefox ✅
- Font spoofing & anti-fingerprinting ✅ - Font spoofing & anti-fingerprinting ✅
- WebRTC IP spoofing ✅ - WebRTC IP spoofing ✅
- Patches from LibreWolf & Ghostery to remove Mozilla services - Debloated & optimized for memory and speed
- Optimized for memory and speed ✅ - [PyPi package](https://pypi.org/project/camoufox/) for updates & unique fingerprint injection 📦
- Stays up to date with the latest Firefox version 🕓 - Stays up to date with the latest Firefox version 🕓
## Sponsors ## Sponsors
@ -64,8 +64,8 @@ Camoufox is built on top of Firefox/Juggler instead of Chromium because:
### What's planned? ### What's planned?
- Continue research on potential leaks - Continue research on potential leaks
- Create a PyPi package for downloading & updating Camoufox - ~~Create a PyPi package for downloading & updating Camoufox~~
- Integrate [BrowserForge](https://github.com/daijro/browserforge) for fingerprint generation - ~~Integrate [BrowserForge](https://github.com/daijro/browserforge) for fingerprint generation~~ ✅
- Built in TLS fingerprinting protection using [Hazetunnel](https://github.com/daijro/hazetunnel) - Built in TLS fingerprinting protection using [Hazetunnel](https://github.com/daijro/hazetunnel)
- Create integration tests - Create integration tests
- Chromium port (long term) - Chromium port (long term)
@ -82,6 +82,12 @@ To spoof fingerprint properties, pass a JSON containing properties to spoof:
$ ./launch --config '{"property": "value"}' [...other Firefox arguments] $ ./launch --config '{"property": "value"}' [...other Firefox arguments]
``` ```
Or, using the Camoufox Python interface ([see here](https://github.com/daijro/camoufox/tree/main/pythonlib#camoufox-python-interface)):
```py
>>> with Camoufox(config={"property": "value"}) as browser:
```
The following attributes can be spoofed: The following attributes can be spoofed:
<details> <details>
@ -355,8 +361,9 @@ Miscellaneous (WebGl spoofing, battery status, etc)
#### Debloat/Optimizations #### Debloat/Optimizations
- Stripped out/disabled _many, many_ Mozilla services. Runs faster than the original Mozilla Firefox, and uses less memory (200mb) - Stripped out/disabled _many, many_ Mozilla services. Runs faster than the original Mozilla Firefox, and uses less memory (200mb)
- Includes the debloat config from PeskyFox & LibreWolf, and others - Patches from LibreWolf & Ghostery to help remove telemetry & bloat
- Speed optimizations from FastFox, and other network optimizations - Debloat config from PeskyFox, LibreWolf, and others
- Speed & network optimizations from FastFox
- Removed all CSS animations - Removed all CSS animations
- Minimalistic theming - Minimalistic theming
- etc. - etc.
@ -369,6 +376,7 @@ Miscellaneous (WebGl spoofing, battery status, etc)
- Addons are not allowed to open tabs - Addons are not allowed to open tabs
- Addons are automatically enabled in Private Browsing mode - Addons are automatically enabled in Private Browsing mode
- Addons are automatically pinned to the toolbar - Addons are automatically pinned to the toolbar
- Fixes DNS leaks with uBO prefetching
## Stealth Performance ## Stealth Performance
@ -409,6 +417,9 @@ Camoufox does **not** fully support injecting Chromium fingerprints. Some WAFs (
## Playwright Usage ## Playwright Usage
> [!NOTE]
> It is recommended to use Camoufox's Python interface instead. See [here](https://github.com/daijro/camoufox/tree/main/pythonlib#camoufox-python-interface) for more information.
Camoufox is fully compatible with your existing Playwright code. You only have to change your browser initialization: Camoufox is fully compatible with your existing Playwright code. You only have to change your browser initialization:
```py ```py
@ -500,7 +511,7 @@ graph TD
end end
``` ```
This was originally forked from the LibreWolf build system. This was originally based on the LibreWolf build system.
## Build CLI ## Build CLI

View file

@ -1,6 +1,6 @@
# Camoufox Python Interface # Camoufox Python Interface
#### This is the Python library for Camoufox. #### Lightweight wrapper around the Playwright API to help launch Camoufox.
> [!WARNING] > [!WARNING]
> This is still experimental and in active development! > This is still experimental and in active development!
@ -10,17 +10,23 @@
First, install the `camoufox` package: First, install the `camoufox` package:
```bash ```bash
git clone --depth 1 https://github.com/camoufox pip install -U camoufox
cd camoufox/pythonlib
pip install .
``` ```
Then, download the Camoufox browser: Then, download the Camoufox browser:
**Windows**
```bash ```bash
camoufox fetch camoufox fetch
``` ```
**MacOS & Linux**
```bash
python3 -m camoufox fetch
```
To uninstall, run `camoufox remove`. To uninstall, run `camoufox remove`.
<hr width=50> <hr width=50>
@ -34,9 +40,9 @@ Camoufox is fully compatible with your existing Playwright code. You only have t
```python ```python
from camoufox.sync_api import Camoufox from camoufox.sync_api import Camoufox
with Camoufox() as browser: with Camoufox(headless=False) as browser:
page = browser.new_page() page = browser.new_page()
page.goto("https://www.browserscan.net/") page.goto("https://example.com/")
``` ```
#### Async API #### Async API
@ -44,15 +50,17 @@ with Camoufox() as browser:
```python ```python
from camoufox.async_api import AsyncCamoufox from camoufox.async_api import AsyncCamoufox
async with AsyncCamoufox() as browser: async with AsyncCamoufox(headless=False) as browser:
page = await browser.new_page() page = await browser.new_page()
await page.goto("https://www.browserscan.net/") await page.goto("https://example.com")
``` ```
<details> <details>
<summary>Parameters</summary> <summary>Parameters</summary>
``` ```
Launches a new browser instance for Camoufox. Launches a new browser instance for Camoufox.
Accepts all Playwright Firefox launch options, along with the following:
Parameters: Parameters:
playwright (Playwright): playwright (Playwright):
@ -80,6 +88,7 @@ Parameters:
**launch_options (Dict[str, Any]): **launch_options (Dict[str, Any]):
Additional Firefox launch options. Additional Firefox launch options.
``` ```
</details> </details>
--- ---
@ -98,7 +107,7 @@ with Camoufox(
} }
) as browser: ) as browser:
page = browser.new_page() page = browser.new_page()
page.goto("https://www.browserscan.net/") page.goto("https://www.browserscan.net/webrtc")
``` ```
<hr width=50> <hr width=50>
@ -118,7 +127,11 @@ fg = FingerprintGenerator(browser='firefox')
# Launch Camoufox with a random Firefox fingerprint # Launch Camoufox with a random Firefox fingerprint
with Camoufox(fingerprint=fg.generate()) as browser: with Camoufox(fingerprint=fg.generate()) as browser:
page = browser.new_page() page = browser.new_page()
page.goto("https://www.browserscan.net/") page.goto("https://example.com/")
``` ```
--- <hr width=50>
**Note:** As of now, some properties from BrowserForge fingerprints will not be passed to Camoufox. This is due to the outdated fingerprint dataset from Apify's fingerprint-suite (see [here](https://github.com/apify/fingerprint-suite/discussions/308)). Properties will be re-enabled as soon as an updated dataset is available.
---

View file

@ -1,4 +1,4 @@
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional, Union
from browserforge.fingerprints import Fingerprint, Screen from browserforge.fingerprints import Fingerprint, Screen
from playwright.async_api import Browser, Playwright, PlaywrightContextManager from playwright.async_api import Browser, Playwright, PlaywrightContextManager
@ -42,6 +42,7 @@ async def AsyncNewBrowser(
fonts: Optional[List[str]] = None, fonts: Optional[List[str]] = None,
args: Optional[List[str]] = None, args: Optional[List[str]] = None,
executable_path: Optional[str] = None, executable_path: Optional[str] = None,
env: Optional[Dict[str, Union[str, float, bool]]] = None,
**launch_options: Dict[str, Any] **launch_options: Dict[str, Any]
) -> Browser: ) -> Browser:
""" """
@ -70,6 +71,8 @@ async def AsyncNewBrowser(
The arguments to pass to the browser. The arguments to pass to the browser.
executable_path (Optional[str]): executable_path (Optional[str]):
The path to the Camoufox browser executable. The path to the Camoufox browser executable.
env (Optional[Dict[str, Union[str, float, bool]]]):
The environment variables to set.
**launch_options (Dict[str, Any]): **launch_options (Dict[str, Any]):
Additional Firefox launch options. Additional Firefox launch options.
""" """
@ -84,5 +87,6 @@ async def AsyncNewBrowser(
fonts=fonts, fonts=fonts,
args=args, args=args,
executable_path=executable_path, executable_path=executable_path,
env=env,
) )
return await playwright.firefox.launch(**opt, **launch_options) return await playwright.firefox.launch(**opt, **launch_options)

View file

@ -279,7 +279,7 @@ def get_path(file: str) -> str:
Get the path to the camoufox executable. Get the path to the camoufox executable.
""" """
if OS_NAME == 'mac': if OS_NAME == 'mac':
return str(camoufox_path() / 'Camoufox.app' / 'Contents' / 'Resources' / file) return os.path.abspath(camoufox_path() / 'Camoufox.app' / 'Contents' / 'Resources' / file)
return str(camoufox_path() / file) return str(camoufox_path() / file)

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,3 @@
[vermin]
verbose = 1
processes = 4

View file

@ -1,4 +1,4 @@
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional, Union
from browserforge.fingerprints import Fingerprint, Screen from browserforge.fingerprints import Fingerprint, Screen
from playwright.sync_api import Browser, Playwright, PlaywrightContextManager from playwright.sync_api import Browser, Playwright, PlaywrightContextManager
@ -42,6 +42,7 @@ def NewBrowser(
fonts: Optional[List[str]] = None, fonts: Optional[List[str]] = None,
args: Optional[List[str]] = None, args: Optional[List[str]] = None,
executable_path: Optional[str] = None, executable_path: Optional[str] = None,
env: Optional[Dict[str, Union[str, float, bool]]] = None,
**launch_options: Dict[str, Any] **launch_options: Dict[str, Any]
) -> Browser: ) -> Browser:
""" """
@ -70,6 +71,8 @@ def NewBrowser(
The arguments to pass to the browser. The arguments to pass to the browser.
executable_path (Optional[str]): executable_path (Optional[str]):
The path to the Camoufox browser executable. The path to the Camoufox browser executable.
env (Optional[Dict[str, Union[str, float, bool]]]):
The environment variables to set.
**launch_options (Dict[str, Any]): **launch_options (Dict[str, Any]):
Additional Firefox launch options. Additional Firefox launch options.
""" """
@ -84,5 +87,6 @@ def NewBrowser(
fonts=fonts, fonts=fonts,
args=args, args=args,
executable_path=executable_path, executable_path=executable_path,
env=env,
) )
return playwright.firefox.launch(**opt, **launch_options) return playwright.firefox.launch(**opt, **launch_options)

View file

@ -2,11 +2,12 @@ import os
import sys import sys
from os import environ from os import environ
from random import randrange from random import randrange
from typing import Any, Dict, List, Optional, Tuple, TypeAlias, Union from typing import Any, Dict, List, Optional, Tuple, Union, cast
import numpy as np import numpy as np
import orjson import orjson
from browserforge.fingerprints import Fingerprint, Screen from browserforge.fingerprints import Fingerprint, Screen
from typing_extensions import TypeAlias
from ua_parser import user_agent_parser from ua_parser import user_agent_parser
from .addons import ( from .addons import (
@ -162,6 +163,7 @@ def get_launch_options(
fonts: Optional[List[str]] = None, fonts: Optional[List[str]] = None,
args: Optional[List[str]] = None, args: Optional[List[str]] = None,
executable_path: Optional[str] = None, executable_path: Optional[str] = None,
env: Optional[Dict[str, Union[str, float, bool]]] = None,
) -> Dict[str, Any]: ) -> Dict[str, Any]:
""" """
Builds the launch options for the Camoufox browser. Builds the launch options for the Camoufox browser.
@ -212,7 +214,10 @@ def get_launch_options(
# Launch # Launch
threaded_try_load_addons(get_debug_port(args), addons) threaded_try_load_addons(get_debug_port(args), addons)
env_vars = {**get_env_vars(config, target_os), **environ} env_vars = {
**get_env_vars(config, target_os),
**(cast(Dict[str, Union[str, float, bool]], environ) if env is None else env),
}
return { return {
"executable_path": executable_path or get_path(LAUNCH_FILE[OS_NAME]), "executable_path": executable_path or get_path(LAUNCH_FILE[OS_NAME]),
"args": args, "args": args,

View file

@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry] [tool.poetry]
name = "camoufox" name = "camoufox"
version = "1.0.0" version = "0.1.0b3"
description = "Wrapper around Playwright to help launch Camoufox" description = "Wrapper around Playwright to help launch Camoufox"
authors = ["daijro <daijro.dev@gmail.com>"] authors = ["daijro <daijro.dev@gmail.com>"]
license = "MIT" license = "MIT"