chore: updated

This commit is contained in:
protokey committed 2026-09-10 20:51:16 +04:00
1 parent 859a2a0e43
commit d9c74227bd
5 files changed
+98 -18

No files matched your search

+86 -17
View File
@@ -1,12 +1,36 @@
import uuid
from datetime import datetime
from pathlib import Path
from typing import Annotated
from urllib.parse import urlsplit
from browserforge.fingerprints import Screen
from camoufox.async_api import AsyncCamoufox
from camoufox.utils import determine_ua_os
from fastapi import Cookie
from fastapi import FastAPI
from fastapi import Request
from fastapi import Response
from playwright.async_api import ViewportSize, ProxySettings
from ua_parser import user_agent_parser
from engine.schemas import SolveRequest
from engine import actions
from engine.schemas import SolveRequest
BROWSER_SLOTS = 10
IDENTITY_FILE = Path("identity.json")
def parse_proxy(proxy_url: str) -> ProxySettings:
parts = urlsplit(proxy_url)
server = f"{parts.scheme}://{parts.hostname}:{parts.port}"
settings: ProxySettings = {"server": server}
if parts.username:
settings["username"] = parts.username
if parts.password:
settings["password"] = parts.password
return settings
app = FastAPI()
@@ -17,28 +41,71 @@ async def root():
return {"message": "Hello World"}
_OS_MAP = {'win': 'windows', 'mac': 'macos', 'lin': 'linux'}
def parse_os_and_ff(user_agent):
os_name = _OS_MAP[determine_ua_os(user_agent)]
parsed = user_agent_parser.ParseUserAgent(user_agent)
ff_version = int(parsed["major"]) if(
parsed.get("family") == "Firefox" and parsed.get("major") )else None
return os_name, ff_version
@app.post("/v1/solve")
async def solve(request: Request, payload: SolveRequest):
async def solve(
request: Request,
payload: SolveRequest,
response: Response,
session_id: Annotated[str | None, Cookie()] = None
):
global BROWSER_SLOTS
if BROWSER_SLOTS <= 0:
return {
"ok": False,
"error": "No slots available",
}
else:
BROWSER_SLOTS -= 1
api_key = request.headers.get('X-API-Key')
async with AsyncCamoufox() as camoufo:
# TODO: настройка контекста
scr_w, scr_h = payload.screen.split("x")
scr_size = ViewportSize(width=int(scr_w), height=int(scr_h))
# TODO: распарс proxy-урл и заполнение объекта
# proxy = ProxySettings(socks5://host:port, username, password)
proxy = None
page = await camoufo.new_page(
user_agent=payload.user_agent,
proxy=proxy,
viewport=scr_size,
screen=scr_size,
)
if not session_id:
session_id = str(uuid.uuid4())
response.set_cookie("session_id", session_id)
scr_w, scr_h = payload.screen.split("x")
scr_size = int(scr_w), int(scr_h)
# TODO: распарс proxy-урл и заполнение объекта
# proxy = ProxySettings(socks5://host:port, username, password)
proxy = None
browser_options = {}
if payload.user_agent:
os, ff_version = parse_os_and_ff(payload.user_agent)
browser_options["os"] = os
browser_options["ff_version"] = ff_version
browser_options["config"] = {'navigator.UserAgent': payload.user_agent}
user_data_dir = Path(__file__).parent / f"../extra/user_data_dir/{session_id}"
if not user_data_dir.exists():
user_data_dir.mkdir(parents=True)
async with AsyncCamoufox(
persistent_context=True,
user_data_dir=user_data_dir,
proxy=proxy,
window=scr_size,
**browser_options,
) as camoufo:
page = camoufo.pages[0] if camoufo.pages else await camoufo.new_page()
page.set_default_timeout(30_000)
await page.goto(url=payload.url)
actions_result = await actions.execute(page, payload.actions)
status = not "error" in actions_result[-1]
error = ["Something error", None][status]
# cookies = await camoufo.cookies()
cookies = await camoufo.cookies()
html = await page.inner_html('html')
await page.screenshot(
path=(
@@ -46,10 +113,12 @@ async def solve(request: Request, payload: SolveRequest):
f"{datetime.timestamp(datetime.now())}.png"
)
)
BROWSER_SLOTS += 1
return {
"status": ["err", "ok"][status],
"html": html,
# "cookies": cookies,
"cookies": cookies,
"actions": actions_result,
"error": error,
}