Spaces:
Sleeping
Sleeping
Update main.py
Browse files
main.py
CHANGED
|
@@ -5,34 +5,24 @@ from typing import Optional
|
|
| 5 |
from playwright.async_api import async_playwright
|
| 6 |
from playwright_stealth import stealth_async
|
| 7 |
|
| 8 |
-
# ১. অ্যাপ্লিকেশন ইনিশিয়ালাইজেশন
|
| 9 |
app = FastAPI(title="Advanced Cloud Browser API", version="2.0")
|
|
|
|
| 10 |
|
| 11 |
-
# ২. সিকিউরিটি: আপনার মাস্টার API Key (Hugging Face Secrets থেকে লোড হবে)
|
| 12 |
-
# ডিফল্ট হিসেবে 'CSE_MASTER_KEY_2026' দেওয়া আছে, তবে হাগিং ফেসে এটি ওভাররাইড করা যায়।
|
| 13 |
-
MASTER_API_KEY = os.getenv("API_KEY", "rh5152..")
|
| 14 |
-
|
| 15 |
-
# ৩. ডেটা মডেল ভ্যালিডেশন (কেউ ভুল ডেটা পাঠালে সার্ভার ক্র্যাশ করবে না)
|
| 16 |
class CommandPayload(BaseModel):
|
| 17 |
url: str
|
| 18 |
-
js_code: Optional[str] = None
|
| 19 |
-
extract_html: bool = False
|
| 20 |
-
wait_time_ms: int = 0
|
| 21 |
|
| 22 |
-
# ৪. হেলথ চেক (Hugging Face Space-এর স্ট্যাটাস 'Running' দেখানোর জন্য এটি মাস্ট)
|
| 23 |
@app.get("/")
|
| 24 |
async def health_check():
|
| 25 |
return {"status": "System Online", "message": "Cloud Browser API is running securely."}
|
| 26 |
|
| 27 |
-
# ৫. মেইন API এন্ডপয়েন্ট (POST রিকোয়েস্ট)
|
| 28 |
@app.post("/api/v1/execute")
|
| 29 |
async def execute_browser_task(payload: CommandPayload, x_api_key: str = Header(None)):
|
| 30 |
-
|
| 31 |
-
# ৬. API Key ভেরিফিকেশন (ভুল কি দিলে সরাসরি রিজেক্ট করে দেবে)
|
| 32 |
if x_api_key != MASTER_API_KEY:
|
| 33 |
raise HTTPException(status_code=403, detail="Access Denied: Invalid Master API Key")
|
| 34 |
|
| 35 |
-
# ৭. অ্যাসিনক্রোনাস ব্রাউজার কন্ট্রোল
|
| 36 |
async with async_playwright() as p:
|
| 37 |
browser = await p.chromium.launch(
|
| 38 |
headless=True,
|
|
@@ -42,50 +32,37 @@ async def execute_browser_task(payload: CommandPayload, x_api_key: str = Header(
|
|
| 42 |
"--disable-dev-shm-usage",
|
| 43 |
"--disable-blink-features=AutomationControlled",
|
| 44 |
"--window-size=1920,1080",
|
| 45 |
-
"--disable-web-security"
|
| 46 |
]
|
| 47 |
)
|
| 48 |
|
| 49 |
-
# ৮. হিউম্যান-লাইক কনটেক্সট এবং ফিঙ্গারপ্রিন্ট সেটআপ
|
| 50 |
context = await browser.new_context(
|
| 51 |
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
| 52 |
viewport={"width": 1920, "height": 1080},
|
| 53 |
java_script_enabled=True
|
| 54 |
)
|
| 55 |
|
| 56 |
-
|
|
|
|
| 57 |
|
| 58 |
-
|
| 59 |
await stealth_async(page)
|
| 60 |
|
| 61 |
try:
|
| 62 |
-
# ১০. কাঙ্ক্ষিত ইউআরএল-এ যাওয়া এবং নেটওয়ার্ক শান্ত হওয়া পর্যন্ত অপেক্ষা করা
|
| 63 |
await page.goto(payload.url, wait_until="networkidle", timeout=60000)
|
| 64 |
-
|
| 65 |
-
# ১১. কাস্টম ওয়েট টাইম (যদি ওয়েবসাইট খুব ভারী হয় বা অ্যানিমেশন থাকে)
|
| 66 |
if payload.wait_time_ms > 0:
|
| 67 |
await page.wait_for_timeout(payload.wait_time_ms)
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
script_result = None
|
| 71 |
-
if payload.js_code:
|
| 72 |
-
script_result = await page.evaluate(payload.js_code)
|
| 73 |
-
|
| 74 |
-
# ১৩. পেজের এইচটিএমএল এক্সট্রাক্ট করা (যদি রিকোয়েস্ট করা হয়)
|
| 75 |
html_content = await page.content() if payload.extract_html else None
|
| 76 |
|
| 77 |
-
# ১৪. সাকসেস রেসপন্স রিটার্ন করা
|
| 78 |
return {
|
| 79 |
"status": "success",
|
| 80 |
"current_url": page.url,
|
| 81 |
"js_output": script_result,
|
| 82 |
"html_extracted": bool(html_content)
|
| 83 |
}
|
| 84 |
-
|
| 85 |
except Exception as e:
|
| 86 |
-
# কোনো এরর হলে সার্ভার ক্র্যাশ না করে সুন্দরভাবে এরর মেসেজ দেবে
|
| 87 |
return {"status": "error", "message": str(e)}
|
| 88 |
-
|
| 89 |
finally:
|
| 90 |
-
# কাজ শেষ হলে বা এরর হলেও মেমরি লিক ঠেকাতে ব্রাউজার ক্লোজ করা মাস্ট
|
| 91 |
await browser.close()
|
|
|
|
| 5 |
from playwright.async_api import async_playwright
|
| 6 |
from playwright_stealth import stealth_async
|
| 7 |
|
|
|
|
| 8 |
app = FastAPI(title="Advanced Cloud Browser API", version="2.0")
|
| 9 |
+
MASTER_API_KEY = os.getenv("API_KEY", "CSE_MASTER_KEY_2026")
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
class CommandPayload(BaseModel):
|
| 12 |
url: str
|
| 13 |
+
js_code: Optional[str] = None
|
| 14 |
+
extract_html: bool = False
|
| 15 |
+
wait_time_ms: int = 0
|
| 16 |
|
|
|
|
| 17 |
@app.get("/")
|
| 18 |
async def health_check():
|
| 19 |
return {"status": "System Online", "message": "Cloud Browser API is running securely."}
|
| 20 |
|
|
|
|
| 21 |
@app.post("/api/v1/execute")
|
| 22 |
async def execute_browser_task(payload: CommandPayload, x_api_key: str = Header(None)):
|
|
|
|
|
|
|
| 23 |
if x_api_key != MASTER_API_KEY:
|
| 24 |
raise HTTPException(status_code=403, detail="Access Denied: Invalid Master API Key")
|
| 25 |
|
|
|
|
| 26 |
async with async_playwright() as p:
|
| 27 |
browser = await p.chromium.launch(
|
| 28 |
headless=True,
|
|
|
|
| 32 |
"--disable-dev-shm-usage",
|
| 33 |
"--disable-blink-features=AutomationControlled",
|
| 34 |
"--window-size=1920,1080",
|
| 35 |
+
"--disable-web-security"
|
| 36 |
]
|
| 37 |
)
|
| 38 |
|
|
|
|
| 39 |
context = await browser.new_context(
|
| 40 |
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
| 41 |
viewport={"width": 1920, "height": 1080},
|
| 42 |
java_script_enabled=True
|
| 43 |
)
|
| 44 |
|
| 45 |
+
# 🔥 দ্য আল্টিমেট অ্যান্টি-বট ইনজেকশন (This fixes the warning!) 🔥
|
| 46 |
+
await context.add_init_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
|
| 47 |
|
| 48 |
+
page = await context.new_page()
|
| 49 |
await stealth_async(page)
|
| 50 |
|
| 51 |
try:
|
|
|
|
| 52 |
await page.goto(payload.url, wait_until="networkidle", timeout=60000)
|
|
|
|
|
|
|
| 53 |
if payload.wait_time_ms > 0:
|
| 54 |
await page.wait_for_timeout(payload.wait_time_ms)
|
| 55 |
+
|
| 56 |
+
script_result = await page.evaluate(payload.js_code) if payload.js_code else None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
html_content = await page.content() if payload.extract_html else None
|
| 58 |
|
|
|
|
| 59 |
return {
|
| 60 |
"status": "success",
|
| 61 |
"current_url": page.url,
|
| 62 |
"js_output": script_result,
|
| 63 |
"html_extracted": bool(html_content)
|
| 64 |
}
|
|
|
|
| 65 |
except Exception as e:
|
|
|
|
| 66 |
return {"status": "error", "message": str(e)}
|
|
|
|
| 67 |
finally:
|
|
|
|
| 68 |
await browser.close()
|