robot-wrapper-sdk 0.2.22__tar.gz → 0.2.23__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/PKG-INFO +1 -1
  2. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/pyproject.toml +1 -1
  3. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_sdk/__init__.py +7 -7
  4. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_sdk/application/usecases.py +15 -8
  5. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_sdk/domain/entities.py +8 -1
  6. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_sdk/domain/repositories.py +11 -4
  7. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_sdk/infrastructure/robot_api_repository.py +56 -42
  8. robot_wrapper_sdk-0.2.23/robot_sdk/infrastructure/tests.py +2 -0
  9. robot_wrapper_sdk-0.2.23/robot_sdk/tests.py +24 -0
  10. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_wrapper_sdk.egg-info/PKG-INFO +1 -1
  11. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_wrapper_sdk.egg-info/SOURCES.txt +2 -0
  12. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/README.md +0 -0
  13. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/examples/main.py +0 -0
  14. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_sdk/application/__init__.py +0 -0
  15. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_sdk/domain/__init__.py +0 -0
  16. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_sdk/infrastructure/__init__.py +0 -0
  17. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_sdk/infrastructure/api_client.py +0 -0
  18. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_wrapper_sdk.egg-info/dependency_links.txt +0 -0
  19. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_wrapper_sdk.egg-info/requires.txt +0 -0
  20. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/robot_wrapper_sdk.egg-info/top_level.txt +0 -0
  21. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/setup.cfg +0 -0
  22. {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.23}/tests/main.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robot-wrapper-sdk
3
- Version: 0.2.22
3
+ Version: 0.2.23
4
4
  Summary: Robot Platform API SDK
5
5
  Author-email: GH Robot Platform Team <team@ghrobot.com>
6
6
  License: MIT
@@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
8
8
 
9
9
  [project]
10
10
  name = "robot-wrapper-sdk"
11
- version = "0.2.22"
11
+ version = "0.2.23"
12
12
  description = "Robot Platform API SDK"
13
13
  readme = "README.md"
14
14
  requires-python = ">=3.10"
@@ -1,15 +1,15 @@
1
1
  from typing import Any, Dict, List, Optional, Tuple
2
2
 
3
3
  from .application.usecases import AsyncRobotUsecase, RobotUsecase
4
- from .domain.entities import (BrowserCapture, BrowserCookies, BrowserHTML,
5
- BrowserSession, BrowserText, Robot,
6
- RobotAuthStatus, RobotSecrets, RobotStatus,
7
- UpdateRobotRequest)
4
+ from .domain.entities import (AcquireRobotsMetadataFilter, BrowserCapture,
5
+ BrowserCookies, BrowserHTML, BrowserSession,
6
+ BrowserText, Robot, RobotAuthStatus,
7
+ RobotSecrets, RobotStatus, UpdateRobotRequest)
8
8
  from .infrastructure.api_client import AsyncHTTPClient, HTTPClient
9
9
  from .infrastructure.robot_api_repository import (AsyncRobotAPIRepository,
10
10
  RobotAPIRepository)
11
11
 
12
- __version__ = "0.2.22"
12
+ __version__ = "0.2.23"
13
13
  class RobotPlatformModule:
14
14
  """Synchronous Facade for the Robot Platform SDK."""
15
15
 
@@ -42,7 +42,7 @@ class RobotPlatformModule:
42
42
  def acquire_unhardened(self, limit: int = 20, lock_minutes: int = 30, min_age_days: int = 0, platforms: Optional[List[str]] = None):
43
43
  return self.robot_usecase.acquire_unhardened(limit, lock_minutes, min_age_days, platforms)
44
44
 
45
- def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None):
45
+ def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: List[AcquireRobotsMetadataFilter] = []):
46
46
  return self.robot_usecase.acquire_robots(limit, lock_minutes, project_name, platform, environment, metadata)
47
47
 
48
48
  def unlock_login_tasks(self, robot_ids: List[str]) -> None:
@@ -118,7 +118,7 @@ class AsyncRobotPlatformModule:
118
118
  async def acquire_unhardened(self, limit: int = 20, lock_minutes: int = 30, min_age_days: int = 0, platforms: Optional[List[str]] = None):
119
119
  return await self.robot_usecase.acquire_unhardened(limit, lock_minutes, min_age_days, platforms)
120
120
 
121
- async def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None):
121
+ async def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: List[AcquireRobotsMetadataFilter] = []):
122
122
  return await self.robot_usecase.acquire_robots(limit, lock_minutes, project_name, platform, environment, metadata)
123
123
 
124
124
  async def unlock_login_tasks(self, robot_ids: List[str]) -> None:
@@ -1,6 +1,12 @@
1
- from typing import Optional, List, Tuple, Any, Dict
2
- from ..domain.repositories import RobotRepository, AsyncRobotRepository
3
- from ..domain.entities import Robot, RobotSecrets, RobotStatus, RobotAuthStatus, BrowserSession, BrowserCookies, BrowserText, BrowserHTML, BrowserCapture, UpdateRobotRequest
1
+ from typing import Any, Dict, List, Optional, Tuple
2
+
3
+ from ..domain.entities import (AcquireRobotsMetadataFilter, BrowserCapture,
4
+ BrowserCookies, BrowserHTML, BrowserSession,
5
+ BrowserText, Robot, RobotAuthStatus,
6
+ RobotSecrets, RobotStatus, UpdateRobotRequest)
7
+ from ..domain.repositories import AsyncRobotRepository, RobotRepository
8
+
9
+
4
10
  class RobotUsecase:
5
11
  def __init__(self, repo: RobotRepository):
6
12
  self.repo = repo
@@ -10,7 +16,7 @@ class RobotUsecase:
10
16
 
11
17
  def delete_robot(self, robot_id: str) -> None:
12
18
  self.repo.delete_robot(robot_id)
13
-
19
+
14
20
  def get_secrets(self, robot_id: str) -> Optional[RobotSecrets]:
15
21
  return self.repo.get_secrets(robot_id)
16
22
 
@@ -18,7 +24,8 @@ class RobotUsecase:
18
24
  self.repo.update_status(robot_id, status)
19
25
 
20
26
  def list_robots(self, platform: Optional[str] = None, status: Optional[str] = None, auth_status: Optional[str] = None, project_id: Optional[int] = None, page: int = 1, limit: int = 20) -> Dict[str, Any]:
21
- items, total = self.repo.list_robots(platform, status, auth_status, project_id, page, limit)
27
+ items, total = self.repo.list_robots(
28
+ platform, status, auth_status, project_id, page, limit)
22
29
  return {
23
30
  "data": [r.__dict__ for r in items],
24
31
  "total": total,
@@ -32,7 +39,7 @@ class RobotUsecase:
32
39
  def acquire_unhardened(self, limit: int = 20, lock_minutes: int = 30, min_age_days: int = 0, platforms: Optional[List[str]] = None) -> List[Robot]:
33
40
  return self.repo.acquire_unhardened(limit, lock_minutes, min_age_days, platforms)
34
41
 
35
- def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None) -> List[Robot]:
42
+ def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: List[AcquireRobotsMetadataFilter] = []) -> List[Robot]:
36
43
  return self.repo.acquire_robots(limit, lock_minutes, project_name, platform, environment, metadata)
37
44
 
38
45
  def unlock_login_tasks(self, robot_ids: List[str]) -> None:
@@ -84,7 +91,7 @@ class AsyncRobotUsecase:
84
91
 
85
92
  async def delete_robot(self, robot_id: str) -> None:
86
93
  await self.repo.delete_robot(robot_id)
87
-
94
+
88
95
  async def get_secrets(self, robot_id: str) -> Optional[RobotSecrets]:
89
96
  return await self.repo.get_secrets(robot_id)
90
97
 
@@ -106,7 +113,7 @@ class AsyncRobotUsecase:
106
113
  async def acquire_unhardened(self, limit: int = 20, lock_minutes: int = 30, min_age_days: int = 0, platforms: Optional[List[str]] = None) -> List[Robot]:
107
114
  return await self.repo.acquire_unhardened(limit, lock_minutes, min_age_days, platforms)
108
115
 
109
- async def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None) -> List[Robot]:
116
+ async def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: List[AcquireRobotsMetadataFilter] = []) -> List[Robot]:
110
117
  return await self.repo.acquire_robots(limit, lock_minutes, project_name, platform, environment, metadata)
111
118
 
112
119
  async def unlock_login_tasks(self, robot_ids: List[str]) -> None:
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass, field
2
2
  from enum import Enum
3
- from typing import Optional, Any, Dict, List
3
+ from typing import Any, Dict, List, Optional
4
4
 
5
5
 
6
6
  class RobotStatus(str, Enum):
@@ -79,6 +79,13 @@ class Robot:
79
79
  created_at: Optional[str] = None
80
80
 
81
81
 
82
+ @dataclass
83
+ class AcquireRobotsMetadataFilter:
84
+ key: str
85
+ op: str
86
+ value: Any
87
+
88
+
82
89
  @dataclass
83
90
  class RobotSecrets:
84
91
  password: str
@@ -1,6 +1,12 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Optional, List, Tuple
3
- from .entities import Robot, RobotSecrets, RobotStatus, RobotAuthStatus, BrowserSession, BrowserCookies, BrowserText, BrowserHTML, BrowserCapture, UpdateRobotRequest
2
+ from typing import List, Optional, Tuple
3
+
4
+ from .entities import (AcquireRobotsMetadataFilter, BrowserCapture,
5
+ BrowserCookies, BrowserHTML, BrowserSession,
6
+ BrowserText, Robot, RobotAuthStatus, RobotSecrets,
7
+ RobotStatus, UpdateRobotRequest)
8
+
9
+
4
10
  class RobotRepository(ABC):
5
11
  @abstractmethod
6
12
  def find_by_id(self, robot_id: str) -> Optional[Robot]:
@@ -31,7 +37,7 @@ class RobotRepository(ABC):
31
37
  pass
32
38
 
33
39
  @abstractmethod
34
- def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: Optional[dict] = None) -> List[Robot]:
40
+ def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: List[AcquireRobotsMetadataFilter] = []) -> List[Robot]:
35
41
  pass
36
42
 
37
43
  @abstractmethod
@@ -86,6 +92,7 @@ class RobotRepository(ABC):
86
92
  def capture_browser(self, pod_name: str, extra_data: Optional[dict] = None) -> BrowserCapture:
87
93
  pass
88
94
 
95
+
89
96
  class AsyncRobotRepository(ABC):
90
97
  @abstractmethod
91
98
  async def find_by_id(self, robot_id: str) -> Optional[Robot]:
@@ -116,7 +123,7 @@ class AsyncRobotRepository(ABC):
116
123
  pass
117
124
 
118
125
  @abstractmethod
119
- async def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: Optional[dict] = None) -> List[Robot]:
126
+ async def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: List[AcquireRobotsMetadataFilter] = []) -> List[Robot]:
120
127
  pass
121
128
 
122
129
  @abstractmethod
@@ -1,23 +1,16 @@
1
1
  from dataclasses import asdict
2
- from typing import Optional, List, Tuple, Dict, Any
3
- from .api_client import HTTPClient, AsyncHTTPClient
4
- from ..domain.repositories import RobotRepository, AsyncRobotRepository
5
- from ..domain.entities import (
6
- Robot,
7
- RobotSecrets,
8
- RobotStatus,
9
- RobotAuthStatus,
10
- UpdateRobotRequest,
11
- BrowserSession,
12
- BrowserCookies,
13
- BrowserText,
14
- BrowserHTML,
15
- BrowserCapture,
16
- normalize_robot_status,
17
- normalize_robot_auth_status,
18
- ensure_valid_worker_robot_status,
19
- ensure_valid_worker_robot_auth_status,
20
- )
2
+ from typing import Any, Dict, List, Optional, Tuple
3
+
4
+ from ..domain.entities import (AcquireRobotsMetadataFilter, BrowserCapture,
5
+ BrowserCookies, BrowserHTML, BrowserSession,
6
+ BrowserText, Robot, RobotAuthStatus,
7
+ RobotSecrets, RobotStatus, UpdateRobotRequest,
8
+ ensure_valid_worker_robot_auth_status,
9
+ ensure_valid_worker_robot_status,
10
+ normalize_robot_auth_status,
11
+ normalize_robot_status)
12
+ from ..domain.repositories import AsyncRobotRepository, RobotRepository
13
+ from .api_client import AsyncHTTPClient, HTTPClient
21
14
 
22
15
 
23
16
  def _extract_list_payload(resp: Dict[str, Any]) -> Tuple[List[Dict[str, Any]], int]:
@@ -145,7 +138,8 @@ def _to_browser_session(resp: Dict[str, Any]) -> BrowserSession:
145
138
  if not isinstance(data, dict):
146
139
  return BrowserSession(pod_name="", session_id="", status="")
147
140
  raw_extra_data = data.get("extra_data")
148
- extra_data: Dict[str, Any] = raw_extra_data if isinstance(raw_extra_data, dict) else {}
141
+ extra_data: Dict[str, Any] = raw_extra_data if isinstance(
142
+ raw_extra_data, dict) else {}
149
143
  return BrowserSession(
150
144
  pod_name=str(data.get("pod_name", "")),
151
145
  session_id=str(data.get("session_id", "")),
@@ -160,9 +154,11 @@ def _to_browser_cookies(resp: Dict[str, Any]) -> BrowserCookies:
160
154
  if not isinstance(data, dict):
161
155
  return BrowserCookies(pod_name="", cookie_count=0, cookies=[])
162
156
  raw_cookies = data.get("cookies")
163
- cookies: List[Dict[str, Any]] = [cookie for cookie in raw_cookies if isinstance(cookie, dict)] if isinstance(raw_cookies, list) else []
157
+ cookies: List[Dict[str, Any]] = [cookie for cookie in raw_cookies if isinstance(
158
+ cookie, dict)] if isinstance(raw_cookies, list) else []
164
159
  raw_extra_data = data.get("extra_data")
165
- extra_data: Dict[str, Any] = raw_extra_data if isinstance(raw_extra_data, dict) else {}
160
+ extra_data: Dict[str, Any] = raw_extra_data if isinstance(
161
+ raw_extra_data, dict) else {}
166
162
  return BrowserCookies(
167
163
  pod_name=str(data.get("pod_name", "")),
168
164
  cookie_count=int(data.get("cookie_count", len(cookies)) or 0),
@@ -180,7 +176,7 @@ def _acquire_payload(limit: int, lock_minutes: int, platforms: Optional[List[str
180
176
  return payload
181
177
 
182
178
 
183
- def _acquire_robots_payload(limit: int, lock_minutes: int, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
179
+ def _acquire_robots_payload(limit: int, lock_minutes: int, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: List[AcquireRobotsMetadataFilter] = []) -> Dict[str, Any]:
184
180
  payload: Dict[str, Any] = {"limit": limit, "lock_minutes": lock_minutes}
185
181
  if project_name:
186
182
  payload["project_name"] = project_name
@@ -189,9 +185,10 @@ def _acquire_robots_payload(limit: int, lock_minutes: int, project_name: Optiona
189
185
  if environment:
190
186
  payload["environment"] = environment
191
187
  if metadata:
192
- payload["metadata"] = metadata
188
+ payload["metadata"] = [asdict(m) for m in metadata]
193
189
  return payload
194
190
 
191
+
195
192
  class RobotAPIRepository(RobotRepository):
196
193
  def __init__(self, client: HTTPClient):
197
194
  self.client = client
@@ -205,7 +202,8 @@ class RobotAPIRepository(RobotRepository):
205
202
  def update_status(self, robot_id: str, status: str | RobotStatus) -> None:
206
203
  normalized_status = normalize_robot_status(status)
207
204
  ensure_valid_worker_robot_status(normalized_status)
208
- self.client.request("PATCH", f"/robots/{robot_id}/status", json={"status": normalized_status})
205
+ self.client.request(
206
+ "PATCH", f"/robots/{robot_id}/status", json={"status": normalized_status})
209
207
 
210
208
  def delete_robot(self, robot_id: str) -> None:
211
209
  self.client.request("DELETE", f"/robots/{robot_id}")
@@ -220,10 +218,14 @@ class RobotAPIRepository(RobotRepository):
220
218
 
221
219
  def list_robots(self, platform: Optional[str] = None, status: Optional[str] = None, auth_status: Optional[str] = None, project_id: Optional[int] = None, page: int = 1, limit: int = 20) -> Tuple[List[Robot], int]:
222
220
  params: Dict[str, Any] = {"page": page, "limit": limit}
223
- if platform: params["platform"] = platform
224
- if status: params["status"] = status
225
- if auth_status: params["auth_status"] = auth_status
226
- if project_id: params["project_id"] = project_id
221
+ if platform:
222
+ params["platform"] = platform
223
+ if status:
224
+ params["status"] = status
225
+ if auth_status:
226
+ params["auth_status"] = auth_status
227
+ if project_id:
228
+ params["project_id"] = project_id
227
229
 
228
230
  resp = self.client.request("GET", "/robots", params=params)
229
231
  data, total = _extract_list_payload(resp)
@@ -242,16 +244,18 @@ class RobotAPIRepository(RobotRepository):
242
244
  resp = self.client.request(
243
245
  "POST",
244
246
  "/robots/security-hardened/acquire",
245
- json=_acquire_payload(limit, lock_minutes, platforms, min_age_days),
247
+ json=_acquire_payload(limit, lock_minutes,
248
+ platforms, min_age_days),
246
249
  )
247
250
  data = _extract_items(resp)
248
251
  return _to_robots(data)
249
252
 
250
- def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None) -> List[Robot]:
253
+ def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: List[AcquireRobotsMetadataFilter] = []) -> List[Robot]:
251
254
  resp = self.client.request(
252
255
  "POST",
253
256
  "/robots/acquire",
254
- json=_acquire_robots_payload(limit, lock_minutes, project_name, platform, environment, metadata),
257
+ json=_acquire_robots_payload(
258
+ limit, lock_minutes, project_name, platform, environment, metadata),
255
259
  )
256
260
  data = _extract_items(resp)
257
261
  return _to_robots(data)
@@ -294,13 +298,15 @@ class RobotAPIRepository(RobotRepository):
294
298
  )
295
299
 
296
300
  def update_robot(self, robot_id: str, payload: UpdateRobotRequest) -> None:
297
- self.client.request("PUT", f"/robots/{robot_id}", json=_compact_update_payload(payload))
301
+ self.client.request(
302
+ "PUT", f"/robots/{robot_id}", json=_compact_update_payload(payload))
298
303
 
299
304
  def open_browser(self, robot_id: Optional[str] = None, username: str = "", proxy: str = "", country_code: str = "", extra_data: Optional[Dict[str, Any]] = None) -> BrowserSession:
300
305
  resp = self.client.request(
301
306
  "POST",
302
307
  "/browser/open",
303
- json=_browser_open_payload(robot_id, username, proxy, country_code, extra_data),
308
+ json=_browser_open_payload(
309
+ robot_id, username, proxy, country_code, extra_data),
304
310
  )
305
311
  return _to_browser_session(resp)
306
312
 
@@ -350,6 +356,7 @@ class RobotAPIRepository(RobotRepository):
350
356
  )
351
357
  return _to_browser_capture(resp)
352
358
 
359
+
353
360
  class AsyncRobotAPIRepository(AsyncRobotRepository):
354
361
  def __init__(self, client: AsyncHTTPClient):
355
362
  self.client = client
@@ -378,10 +385,14 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
378
385
 
379
386
  async def list_robots(self, platform: Optional[str] = None, status: Optional[str] = None, auth_status: Optional[str] = None, project_id: Optional[int] = None, page: int = 1, limit: int = 20) -> Tuple[List[Robot], int]:
380
387
  params: Dict[str, Any] = {"page": page, "limit": limit}
381
- if platform: params["platform"] = platform
382
- if status: params["status"] = status
383
- if auth_status: params["auth_status"] = auth_status
384
- if project_id: params["project_id"] = project_id
388
+ if platform:
389
+ params["platform"] = platform
390
+ if status:
391
+ params["status"] = status
392
+ if auth_status:
393
+ params["auth_status"] = auth_status
394
+ if project_id:
395
+ params["project_id"] = project_id
385
396
 
386
397
  resp = await self.client.request("GET", "/robots", params=params)
387
398
  data, total = _extract_list_payload(resp)
@@ -400,16 +411,18 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
400
411
  resp = await self.client.request(
401
412
  "POST",
402
413
  "/robots/security-hardened/acquire",
403
- json=_acquire_payload(limit, lock_minutes, platforms, min_age_days),
414
+ json=_acquire_payload(limit, lock_minutes,
415
+ platforms, min_age_days),
404
416
  )
405
417
  data = _extract_items(resp)
406
418
  return _to_robots(data)
407
419
 
408
- async def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None) -> List[Robot]:
420
+ async def acquire_robots(self, limit: int = 20, lock_minutes: int = 30, project_name: Optional[str] = None, platform: Optional[str] = None, environment: Optional[str] = None, metadata: List[AcquireRobotsMetadataFilter] = []) -> List[Robot]:
409
421
  resp = await self.client.request(
410
422
  "POST",
411
423
  "/robots/acquire",
412
- json=_acquire_robots_payload(limit, lock_minutes, project_name, platform, environment, metadata),
424
+ json=_acquire_robots_payload(
425
+ limit, lock_minutes, project_name, platform, environment, metadata),
413
426
  )
414
427
  data = _extract_items(resp)
415
428
  return _to_robots(data)
@@ -458,7 +471,8 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
458
471
  resp = await self.client.request(
459
472
  "POST",
460
473
  "/browser/open",
461
- json=_browser_open_payload(robot_id, username, proxy, country_code, extra_data),
474
+ json=_browser_open_payload(
475
+ robot_id, username, proxy, country_code, extra_data),
462
476
  )
463
477
  return _to_browser_session(resp)
464
478
 
@@ -0,0 +1,2 @@
1
+ def test_acquire_robots():
2
+ assert True
@@ -0,0 +1,24 @@
1
+ from . import RobotPlatformModule
2
+ from .domain.entities import AcquireRobotsMetadataFilter
3
+
4
+
5
+ def test_robot_sdk_acquire_robots():
6
+ base_url = "http://localhost:8085"
7
+ app_id = "b550c067c9750de1acc08fbd2009e6d9"
8
+ app_secret = "c3a3b0ab136a4739dc839dcf3e4f6e93b9b176125ec4b2d47170a6b074debc86"
9
+ sdk = RobotPlatformModule(
10
+ base_url=base_url,
11
+ app_id=app_id,
12
+ app_secret=app_secret
13
+ )
14
+ robots = sdk.acquire_robots(
15
+ limit=20, lock_minutes=30, platform="facebook", environment="chrome", metadata=[
16
+ AcquireRobotsMetadataFilter(
17
+ **{"key": "robot_type", "op": "eq", "value": "fastcheck"},
18
+ ),
19
+ AcquireRobotsMetadataFilter(
20
+ **{"key": "country_code", "op": "eq", "value": "VN"}
21
+ )
22
+ ])
23
+ print(len(robots))
24
+ assert isinstance(robots, list)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robot-wrapper-sdk
3
- Version: 0.2.22
3
+ Version: 0.2.23
4
4
  Summary: Robot Platform API SDK
5
5
  Author-email: GH Robot Platform Team <team@ghrobot.com>
6
6
  License: MIT
@@ -2,6 +2,7 @@ README.md
2
2
  pyproject.toml
3
3
  examples/main.py
4
4
  robot_sdk/__init__.py
5
+ robot_sdk/tests.py
5
6
  robot_sdk/application/__init__.py
6
7
  robot_sdk/application/usecases.py
7
8
  robot_sdk/domain/__init__.py
@@ -10,6 +11,7 @@ robot_sdk/domain/repositories.py
10
11
  robot_sdk/infrastructure/__init__.py
11
12
  robot_sdk/infrastructure/api_client.py
12
13
  robot_sdk/infrastructure/robot_api_repository.py
14
+ robot_sdk/infrastructure/tests.py
13
15
  robot_wrapper_sdk.egg-info/PKG-INFO
14
16
  robot_wrapper_sdk.egg-info/SOURCES.txt
15
17
  robot_wrapper_sdk.egg-info/dependency_links.txt