Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Readme / Headless Mode #1262

Merged
merged 2 commits into from
Nov 17, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -243,6 +243,41 @@ for message in response:
print(message)
```

##### Using Browser

Some providers using a browser to bypass the bot protection.
They using the selenium webdriver to control the browser.
The browser settings and the login data are saved in a custom directory.
If the headless mode is enabled, the browser windows are loaded invisibly.
For performance reasons, it is recommended to reuse the browser instances
and close them yourself at the end:

```python
import g4f
from undetected_chromedriver import Chrome, ChromeOptions
from g4f.Provider import (
Bard,
Poe,
AItianhuSpace,
MyShell,
Phind,
PerplexityAi,
)

options = ChromeOptions()
options.add_argument("--incognito");
browser = Chrome(options=options, headless=True)
for idx in range(10):
response = g4f.ChatCompletion.create(
model=g4f.models.default,
provider=g4f.Provider.Phind,
messages=[{"role": "user", "content": "Suggest me a name."}],
browser=browser
)
print(f"{idx}:", response)
browser.quit()
```

##### Cookies Required

Cookies are essential for the proper functioning of some service providers. It is imperative to maintain an active session, typically achieved by logging into your account.
@@ -253,18 +288,16 @@ When running the g4f package locally, the package automatically retrieves cookie
import g4f

from g4f.Provider import (
Bard,
Bing,
HuggingChat,
OpenAssistant,
OpenaiChat,
)

# Usage
response = g4f.ChatCompletion.create(
model=g4f.models.default,
messages=[{"role": "user", "content": "Hello"}],
provider=Bard,
provider=Bing,
#cookies=g4f.get_cookies(".google.com"),
cookies={"cookie_name": "value", "cookie_name2": "value2"},
auth=True
17 changes: 5 additions & 12 deletions g4f/Provider/AItianhuSpace.py
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ def create_completion(
proxy: str = None,
timeout: int = 120,
browser: WebDriver = None,
hidden_display: bool = True,
headless: bool = True,
**kwargs
) -> CreateResult:
if not model:
@@ -38,13 +38,7 @@ def create_completion(
print(f"AItianhuSpace | using domain: {domain}")
url = f"https://{domain}"
prompt = format_prompt(messages)
if browser:
driver = browser
else:
if hidden_display:
driver, display = get_browser("", True, proxy)
else:
driver = get_browser("", False, proxy)
driver = browser if browser else get_browser("", headless, proxy)

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
@@ -66,6 +60,7 @@ def create_completion(
original_window = driver.current_window_handle
for window_handle in driver.window_handles:
if window_handle != original_window:
driver.close()
driver.switch_to.window(window_handle)
break

@@ -120,9 +115,7 @@ def create_completion(
else:
time.sleep(0.1)
finally:
driver.close()
if not browser:
driver.close()
time.sleep(0.1)
driver.quit()
if hidden_display:
display.stop()
driver.quit()
16 changes: 4 additions & 12 deletions g4f/Provider/MyShell.py
Original file line number Diff line number Diff line change
@@ -21,16 +21,10 @@ def create_completion(
proxy: str = None,
timeout: int = 120,
browser: WebDriver = None,
hidden_display: bool = True,
headless: bool = True,
**kwargs
) -> CreateResult:
if browser:
driver = browser
else:
if hidden_display:
driver, display = get_browser("", True, proxy)
else:
driver = get_browser("", False, proxy)
driver = browser if browser else get_browser("", headless, proxy)

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
@@ -87,9 +81,7 @@ def create_completion(
elif chunk != "":
break
finally:
driver.close()
if not browser:
driver.close()
time.sleep(0.1)
driver.quit()
if hidden_display:
display.stop()
driver.quit()
16 changes: 4 additions & 12 deletions g4f/Provider/PerplexityAi.py
Original file line number Diff line number Diff line change
@@ -22,16 +22,10 @@ def create_completion(
timeout: int = 120,
browser: WebDriver = None,
copilot: bool = False,
hidden_display: bool = True,
headless: bool = True,
**kwargs
) -> CreateResult:
if browser:
driver = browser
else:
if hidden_display:
driver, display = get_browser("", True, proxy)
else:
driver = get_browser("", False, proxy)
driver = browser if browser else get_browser("", headless, proxy)

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
@@ -112,9 +106,7 @@ def create_completion(
else:
time.sleep(0.1)
finally:
driver.close()
if not browser:
driver.close()
time.sleep(0.1)
driver.quit()
if hidden_display:
display.stop()
driver.quit()
16 changes: 4 additions & 12 deletions g4f/Provider/Phind.py
Original file line number Diff line number Diff line change
@@ -23,16 +23,10 @@ def create_completion(
timeout: int = 120,
browser: WebDriver = None,
creative_mode: bool = None,
hidden_display: bool = True,
headless: bool = True,
**kwargs
) -> CreateResult:
if browser:
driver = browser
else:
if hidden_display:
driver, display = get_browser("", True, proxy)
else:
driver = get_browser("", False, proxy)
driver = browser if browser else get_browser("", headless, proxy)

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
@@ -111,9 +105,7 @@ def create_completion(
else:
time.sleep(0.1)
finally:
driver.close()
if not browser:
driver.close()
time.sleep(0.1)
driver.quit()
if hidden_display:
display.stop()
driver.quit()
22 changes: 3 additions & 19 deletions g4f/Provider/helper.py
Original file line number Diff line number Diff line change
@@ -31,14 +31,6 @@ def __init__():
class ChromeOptions():
def add_argument():
pass
try:
from pyvirtualdisplay import Display
except ImportError:
class Display():
def start():
pass
def stop():
pass

from ..typing import Dict, Messages, Union, Tuple
from .. import debug
@@ -139,24 +131,16 @@ def format_prompt(messages: Messages, add_special_tokens=False) -> str:

def get_browser(
user_data_dir: str = None,
hidden_display: bool = False,
headless: bool = False,
proxy: str = None,
options: ChromeOptions = None
) -> Union[Chrome, Tuple[Chrome, Display]] :
) -> Chrome:
if user_data_dir == None:
user_data_dir = user_config_dir("g4f")

if hidden_display:
display = Display(visible=0, size=(1920, 1080))
display.start()

if proxy:
if not options:
options = ChromeOptions()
options.add_argument(f'--proxy-server={proxy}')

browser = Chrome(user_data_dir=user_data_dir, options=options)
if hidden_display:
return browser, display

return browser
return Chrome(user_data_dir=user_data_dir, options=options, headless=headless)
20 changes: 5 additions & 15 deletions g4f/Provider/needs_auth/Bard.py
Original file line number Diff line number Diff line change
@@ -19,17 +19,12 @@ def create_completion(
stream: bool,
proxy: str = None,
browser: WebDriver = None,
hidden_display: bool = True,
user_data_dir: str = None,
headless: bool = True,
**kwargs
) -> CreateResult:
prompt = format_prompt(messages)
if browser:
driver = browser
else:
if hidden_display:
driver, display = get_browser(None, True, proxy)
else:
driver = get_browser(None, False, proxy)
driver = browser if browser else get_browser(user_data_dir, headless, proxy)

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
@@ -43,9 +38,6 @@ def create_completion(
# Reopen browser for login
if not browser:
driver.quit()
# New browser should be visible
if hidden_display:
display.stop()
driver = get_browser(None, False, proxy)
driver.get(f"{cls.url}/chat")
wait = WebDriverWait(driver, 240)
@@ -83,9 +75,7 @@ def create_completion(
else:
time.sleep(0.1)
finally:
driver.close()
if not browser:
driver.close()
time.sleep(0.1)
driver.quit()
if hidden_display:
display.stop()
driver.quit()
22 changes: 7 additions & 15 deletions g4f/Provider/needs_auth/Poe.py
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
class Poe(BaseProvider):
url = "https://poe.com"
working = True
needs_auth = True
supports_gpt_35_turbo = True
supports_stream = True

@@ -33,21 +34,16 @@ def create_completion(
stream: bool,
proxy: str = None,
browser: WebDriver = None,
hidden_display: bool = True,
user_data_dir: str = None,
headless: bool = True,
**kwargs
) -> CreateResult:
if not model:
model = "gpt-3.5-turbo"
elif model not in models:
raise ValueError(f"Model are not supported: {model}")
prompt = format_prompt(messages)
if browser:
driver = browser
else:
if hidden_display:
driver, display = get_browser(None, True, proxy)
else:
driver = get_browser(None, False, proxy)
driver = browser if browser else get_browser(user_data_dir, headless, proxy)

script = """
window._message = window._last_message = "";
@@ -80,14 +76,12 @@ class ProxiedWebSocket extends WebSocket {

try:
driver.get(f"{cls.url}/{models[model]['name']}")
wait = WebDriverWait(driver, 10 if hidden_display else 240)
wait = WebDriverWait(driver, 10 if headless else 240)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "textarea[class^='GrowingTextArea']")))
except:
# Reopen browser for login
if not browser:
driver.quit()
if hidden_display:
display.stop()
driver = get_browser(None, False, proxy)
driver.get(f"{cls.url}/{models[model]['name']}")
wait = WebDriverWait(driver, 240)
@@ -121,9 +115,7 @@ class ProxiedWebSocket extends WebSocket {
else:
time.sleep(0.1)
finally:
driver.close()
if not browser:
driver.close()
time.sleep(0.1)
driver.quit()
if hidden_display:
display.stop()
driver.quit()