gpt4free/g4f/Provider/Phind.py

111 lines
3.7 KiB
Python
Raw Normal View History

from __future__ import annotations
import time
from urllib.parse import quote
from ..typing import CreateResult, Messages
from .base_provider import BaseProvider
2023-11-16 17:35:22 +00:00
from .helper import WebDriver, format_prompt, get_browser
class Phind(BaseProvider):
url = "https://www.phind.com"
working = True
supports_gpt_4 = True
supports_stream = True
@classmethod
def create_completion(
cls,
model: str,
2023-10-10 07:49:29 +00:00
messages: Messages,
stream: bool,
proxy: str = None,
2023-10-09 08:22:17 +00:00
timeout: int = 120,
browser: WebDriver = None,
creative_mode: bool = None,
headless: bool = True,
**kwargs
) -> CreateResult:
driver = browser if browser else get_browser("", headless, proxy)
2023-11-16 18:02:53 +00:00
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
prompt = quote(format_prompt(messages))
driver.get(f"{cls.url}/search?q={prompt}&source=searchbox")
2023-11-16 18:24:15 +00:00
# Need to change settinge
if model.startswith("gpt-4") or creative_mode:
wait = WebDriverWait(driver, timeout)
2023-11-16 18:24:15 +00:00
# Open settings dropdown
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "button.text-dark.dropdown-toggle")))
driver.find_element(By.CSS_SELECTOR, "button.text-dark.dropdown-toggle").click()
2023-11-16 18:24:15 +00:00
# Wait for dropdown toggle
wait.until(EC.visibility_of_element_located((By.XPATH, "//button[text()='GPT-4']")))
2023-11-16 18:24:15 +00:00
# Enable GPT-4
if model.startswith("gpt-4"):
driver.find_element(By.XPATH, "//button[text()='GPT-4']").click()
# Enable creative mode
if creative_mode or creative_mode == None:
driver.find_element(By.ID, "Creative Mode").click()
2023-11-16 18:24:15 +00:00
# Submit changes
driver.find_element(By.CSS_SELECTOR, ".search-bar-input-group button[type='submit']").click()
2023-11-16 18:24:15 +00:00
# Wait for page reload
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".search-container")))
try:
2023-11-16 18:24:15 +00:00
# Add fetch hook
script = """
window._fetch = window.fetch;
window.fetch = (url, options) => {
2023-11-16 18:24:15 +00:00
// Call parent fetch method
const result = window._fetch(url, options);
if (url != "/api/infer/answer") return result;
2023-11-16 18:24:15 +00:00
// Load response reader
result.then((response) => {
if (!response.body.locked) {
window.reader = response.body.getReader();
}
});
2023-11-16 18:24:15 +00:00
// Return dummy response
return new Promise((resolve, reject) => {
resolve(new Response(new ReadableStream()))
});
}
"""
2023-11-16 18:24:15 +00:00
# Read response from reader
driver.execute_script(script)
script = """
if(window.reader) {
chunk = await window.reader.read();
if (chunk['done']) return null;
2023-11-16 18:02:53 +00:00
text = (new TextDecoder()).decode(chunk['value']);
content = '';
text.split('\\r\\n').forEach((line, index) => {
if (line.startsWith('data: ')) {
line = line.substring('data: '.length);
if (!line.startsWith('<PHIND_METADATA>')) {
if (line) content += line;
else content += '\\n';
}
}
});
return content.replace('\\n\\n', '\\n');
} else {
return ''
}
"""
while True:
chunk = driver.execute_script(script)
if chunk:
yield chunk
elif chunk != "":
break
else:
time.sleep(0.1)
finally:
if not browser:
driver.close()
time.sleep(0.1)
driver.quit()