add new tool: to_captcha
This commit is contained in:
parent
8f86dbbdac
commit
4852345bf6
12 changed files with 716 additions and 35 deletions
105
api/routes/captcha.py
Normal file
105
api/routes/captcha.py
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import asyncio
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
|
||||
from api.contracts.captcha_schemas import (
|
||||
CaptchaAbortRequest,
|
||||
CaptchaActionResponse,
|
||||
CaptchaExtendRequest,
|
||||
CaptchaNotifyRequest,
|
||||
CaptchaSolvedRequest,
|
||||
CaptchaStatusResponse,
|
||||
)
|
||||
from api.mappers.captcha_mapper import CaptchaMapper
|
||||
from api.routes.dependencies import get_task_service
|
||||
from api.services.protocols import TaskServiceProtocol
|
||||
|
||||
router = APIRouter(prefix="/api/browser", tags=["browser-captcha"])
|
||||
|
||||
|
||||
@router.post("/tasks/{task_id}/captcha/notify", response_model=CaptchaActionResponse, status_code=202)
|
||||
async def captcha_notify(
|
||||
task_id: str,
|
||||
payload: CaptchaNotifyRequest,
|
||||
service: TaskServiceProtocol = Depends(get_task_service),
|
||||
) -> CaptchaActionResponse:
|
||||
rec = await service.notify_captcha(
|
||||
task_id=task_id,
|
||||
kind=payload.captcha_kind,
|
||||
reason=payload.reason,
|
||||
view_url=payload.browser_view_url,
|
||||
timeout_seconds=payload.timeout_seconds,
|
||||
)
|
||||
if rec is None:
|
||||
raise HTTPException(status_code=404, detail="Task not found")
|
||||
return CaptchaMapper.to_action(rec, message="captcha awaiting solution")
|
||||
|
||||
|
||||
@router.get("/tasks/{task_id}/captcha", response_model=CaptchaStatusResponse)
|
||||
async def captcha_status(
|
||||
task_id: str,
|
||||
service: TaskServiceProtocol = Depends(get_task_service),
|
||||
) -> CaptchaStatusResponse:
|
||||
rec = await service.get_task(task_id)
|
||||
if rec is None:
|
||||
raise HTTPException(status_code=404, detail="Task not found")
|
||||
return CaptchaMapper.to_status(rec)
|
||||
|
||||
|
||||
@router.get("/tasks/{task_id}/captcha/wait", response_model=CaptchaStatusResponse)
|
||||
async def captcha_wait(
|
||||
task_id: str,
|
||||
timeout: float = Query(default=30.0, ge=0.1, le=600.0, description="long-poll cap, seconds"),
|
||||
service: TaskServiceProtocol = Depends(get_task_service),
|
||||
) -> CaptchaStatusResponse:
|
||||
rec = await service.wait_captcha(task_id=task_id, timeout=timeout)
|
||||
if rec is None:
|
||||
raise HTTPException(status_code=404, detail="Task not found")
|
||||
return CaptchaMapper.to_status(rec)
|
||||
|
||||
|
||||
@router.post("/tasks/{task_id}/captcha/solved", response_model=CaptchaActionResponse)
|
||||
async def captcha_solved(
|
||||
task_id: str,
|
||||
payload: CaptchaSolvedRequest | None = None,
|
||||
service: TaskServiceProtocol = Depends(get_task_service),
|
||||
) -> CaptchaActionResponse:
|
||||
rec = await service.mark_captcha_solved(task_id=task_id, detector=(payload.detector if payload else None))
|
||||
if rec is None:
|
||||
raise HTTPException(status_code=404, detail="Task not found")
|
||||
return CaptchaMapper.to_action(rec, message="captcha marked as solved")
|
||||
|
||||
|
||||
@router.post("/tasks/{task_id}/captcha/timeout-prompt", response_model=CaptchaActionResponse)
|
||||
async def captcha_timeout_prompt(
|
||||
task_id: str,
|
||||
service: TaskServiceProtocol = Depends(get_task_service),
|
||||
) -> CaptchaActionResponse:
|
||||
rec = await service.prompt_captcha_timeout(task_id=task_id)
|
||||
if rec is None:
|
||||
raise HTTPException(status_code=404, detail="Task not found")
|
||||
return CaptchaMapper.to_action(rec, message="user must choose: extend or abort")
|
||||
|
||||
|
||||
@router.post("/tasks/{task_id}/captcha/extend", response_model=CaptchaActionResponse)
|
||||
async def captcha_extend(
|
||||
task_id: str,
|
||||
payload: CaptchaExtendRequest,
|
||||
service: TaskServiceProtocol = Depends(get_task_service),
|
||||
) -> CaptchaActionResponse:
|
||||
rec = await service.extend_captcha(task_id=task_id, extra_seconds=payload.extra_seconds)
|
||||
if rec is None:
|
||||
raise HTTPException(status_code=404, detail="Task not found")
|
||||
return CaptchaMapper.to_action(rec, message=f"captcha extended by {payload.extra_seconds}s")
|
||||
|
||||
|
||||
@router.post("/tasks/{task_id}/captcha/abort", response_model=CaptchaActionResponse)
|
||||
async def captcha_abort(
|
||||
task_id: str,
|
||||
payload: CaptchaAbortRequest | None = None,
|
||||
service: TaskServiceProtocol = Depends(get_task_service),
|
||||
) -> CaptchaActionResponse:
|
||||
rec = await service.abort_captcha(task_id=task_id, reason=(payload.reason if payload else None))
|
||||
if rec is None:
|
||||
raise HTTPException(status_code=404, detail="Task not found")
|
||||
return CaptchaMapper.to_action(rec, message="captcha aborted by user")
|
||||
Loading…
Add table
Add a link
Reference in a new issue