Spaces:
Sleeping
Sleeping
Update app.py
#1
by luckytec - opened
app.py
CHANGED
|
@@ -14,34 +14,41 @@ class GeminiBot:
|
|
| 14 |
|
| 15 |
async def start(self):
|
| 16 |
self.playwright = await async_playwright().start()
|
| 17 |
-
# Launch browser
|
| 18 |
-
self.browser = await self.playwright.chromium.launch(
|
|
|
|
|
|
|
|
|
|
| 19 |
print("--- Gemini Bot (Stateless) Ready ---")
|
| 20 |
|
| 21 |
async def process_chat(self, message: str):
|
| 22 |
-
#
|
| 23 |
-
context = await self.browser.new_context(
|
|
|
|
|
|
|
| 24 |
page = await context.new_page()
|
| 25 |
|
| 26 |
try:
|
| 27 |
-
# BLOCK assets to
|
| 28 |
await page.route("**/*", lambda route: route.abort() if route.request.resource_type in
|
| 29 |
["image", "font", "media", "stylesheet"] else route.continue_())
|
| 30 |
|
| 31 |
-
|
|
|
|
| 32 |
|
| 33 |
-
# Interact
|
| 34 |
-
chat_box = page.locator("div[contenteditable='true']")
|
|
|
|
| 35 |
await chat_box.fill(message)
|
| 36 |
await page.keyboard.press("Enter")
|
| 37 |
|
| 38 |
-
# Wait for response
|
| 39 |
await page.wait_for_selector("message-content", timeout=45000)
|
| 40 |
|
| 41 |
# Extract Text
|
| 42 |
current_text = await page.evaluate("""() => {
|
| 43 |
const msgs = document.querySelectorAll('message-content');
|
| 44 |
-
return msgs.length > 0 ? msgs[msgs.length - 1].innerText : "";
|
| 45 |
}""")
|
| 46 |
|
| 47 |
return {"text": current_text}
|
|
@@ -75,6 +82,7 @@ def health_check():
|
|
| 75 |
|
| 76 |
@app.post("/chat")
|
| 77 |
async def chat_api(request: ChatRequest):
|
|
|
|
| 78 |
return await bot.process_chat(request.message)
|
| 79 |
|
| 80 |
if __name__ == "__main__":
|
|
|
|
| 14 |
|
| 15 |
async def start(self):
|
| 16 |
self.playwright = await async_playwright().start()
|
| 17 |
+
# Launch browser with flags to help avoid detection
|
| 18 |
+
self.browser = await self.playwright.chromium.launch(
|
| 19 |
+
headless=True,
|
| 20 |
+
args=["--no-sandbox", "--disable-blink-features=AutomationControlled"]
|
| 21 |
+
)
|
| 22 |
print("--- Gemini Bot (Stateless) Ready ---")
|
| 23 |
|
| 24 |
async def process_chat(self, message: str):
|
| 25 |
+
# Create context with a realistic User Agent
|
| 26 |
+
context = await self.browser.new_context(
|
| 27 |
+
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
| 28 |
+
)
|
| 29 |
page = await context.new_page()
|
| 30 |
|
| 31 |
try:
|
| 32 |
+
# BLOCK unnecessary assets to speed up loading
|
| 33 |
await page.route("**/*", lambda route: route.abort() if route.request.resource_type in
|
| 34 |
["image", "font", "media", "stylesheet"] else route.continue_())
|
| 35 |
|
| 36 |
+
# Navigate and wait for network idle to ensure JS loads
|
| 37 |
+
await page.goto("https://gemini.google.com", wait_until="networkidle")
|
| 38 |
|
| 39 |
+
# Interact with the chat box
|
| 40 |
+
chat_box = page.locator("div[contenteditable='true']")
|
| 41 |
+
await chat_box.wait_for(timeout=20000)
|
| 42 |
await chat_box.fill(message)
|
| 43 |
await page.keyboard.press("Enter")
|
| 44 |
|
| 45 |
+
# Wait for the response container
|
| 46 |
await page.wait_for_selector("message-content", timeout=45000)
|
| 47 |
|
| 48 |
# Extract Text
|
| 49 |
current_text = await page.evaluate("""() => {
|
| 50 |
const msgs = document.querySelectorAll('message-content');
|
| 51 |
+
return msgs.length > 0 ? msgs[msgs.length - 1].innerText : "Error: No message content found";
|
| 52 |
}""")
|
| 53 |
|
| 54 |
return {"text": current_text}
|
|
|
|
| 82 |
|
| 83 |
@app.post("/chat")
|
| 84 |
async def chat_api(request: ChatRequest):
|
| 85 |
+
# This now handles the Pydantic model correctly, resolving 422 errors
|
| 86 |
return await bot.process_chat(request.message)
|
| 87 |
|
| 88 |
if __name__ == "__main__":
|