1+ import httpx
2+ from typing import Any , Dict , Optional
3+ from .types import Config , MaxunError
4+
5+
6+ class Client :
7+ def __init__ (self , config : Config ):
8+ self .api_key = config .api_key
9+
10+ headers = {
11+ "x-api-key" : self .api_key ,
12+ "Content-Type" : "application/json" ,
13+ }
14+
15+ if config .team_id :
16+ headers ["x-team-id" ] = config .team_id
17+
18+ self .base_url = config .base_url or "http://localhost:8080/api/sdk"
19+
20+ self .client = httpx .AsyncClient (
21+ base_url = self .base_url ,
22+ headers = headers ,
23+ timeout = 30.0 ,
24+ )
25+
26+ async def _handle (self , request ):
27+ try :
28+ response = await request
29+ response .raise_for_status ()
30+ data = response .json ()
31+ return data .get ("data" )
32+ except httpx .HTTPStatusError as e :
33+ try :
34+ payload = e .response .json ()
35+ except Exception :
36+ payload = None
37+ raise MaxunError (
38+ payload .get ("error" ) if payload else str (e ),
39+ status_code = e .response .status_code ,
40+ details = payload ,
41+ )
42+ except httpx .RequestError as e :
43+ raise MaxunError ("No response from server" , details = str (e ))
44+
45+ async def get_robots (self ):
46+ return await self ._handle (self .client .get ("/robots" ))
47+
48+ async def get_robot (self , robot_id : str ):
49+ data = await self ._handle (self .client .get (f"/robots/{ robot_id } " ))
50+ if not data :
51+ raise MaxunError (f"Robot { robot_id } not found" , 404 )
52+ return data
53+
54+ async def create_robot (self , workflow_file : dict ):
55+ return await self ._handle (
56+ self .client .post ("/robots" , json = workflow_file , timeout = 120 )
57+ )
58+
59+ async def update_robot (self , robot_id : str , updates : dict ):
60+ return await self ._handle (
61+ self .client .put (f"/robots/{ robot_id } " , json = updates )
62+ )
63+
64+ async def delete_robot (self , robot_id : str ):
65+ await self ._handle (self .client .delete (f"/robots/{ robot_id } " ))
66+
67+ async def execute_robot (self , robot_id : str , options : Optional [dict ] = None ):
68+ return await self ._handle (
69+ self .client .post (
70+ f"/robots/{ robot_id } /execute" ,
71+ json = {
72+ "params" : options .get ("params" ) if options else None ,
73+ "webhook" : options .get ("webhook" ) if options else None ,
74+ },
75+ timeout = options .get ("timeout" , 300 ) if options else 300 ,
76+ )
77+ )
78+
79+ async def get_runs (self , robot_id : str ):
80+ return await self ._handle (self .client .get (f"/robots/{ robot_id } /runs" ))
81+
82+ async def get_run (self , robot_id : str , run_id : str ):
83+ return await self ._handle (
84+ self .client .get (f"/robots/{ robot_id } /runs/{ run_id } " )
85+ )
86+
87+ async def abort_run (self , robot_id : str , run_id : str ):
88+ await self ._handle (
89+ self .client .post (f"/robots/{ robot_id } /runs/{ run_id } /abort" )
90+ )
91+
92+ async def extract_with_llm (self , options : dict ):
93+ return await self ._handle (
94+ self .client .post ("/extract/llm" , json = options , timeout = 300 )
95+ )
96+
97+ async def create_crawl_robot (self , url : str , options : dict ):
98+ return await self ._handle (
99+ self .client .post ("/crawl" , json = {"url" : url , ** options })
100+ )
101+
102+ async def create_search_robot (self , options : dict ):
103+ return await self ._handle (
104+ self .client .post ("/search" , json = options )
105+ )
0 commit comments