robot-wrapper-sdk 0.2.22__tar.gz → 0.2.24__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.
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/PKG-INFO +1 -1
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/pyproject.toml +1 -1
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_sdk/__init__.py +7 -7
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_sdk/application/usecases.py +15 -8
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_sdk/domain/entities.py +8 -1
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_sdk/domain/repositories.py +11 -4
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_sdk/infrastructure/robot_api_repository.py +63 -42
- robot_wrapper_sdk-0.2.24/robot_sdk/infrastructure/tests.py +2 -0
- robot_wrapper_sdk-0.2.24/robot_sdk/tests.py +24 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_wrapper_sdk.egg-info/PKG-INFO +1 -1
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_wrapper_sdk.egg-info/SOURCES.txt +2 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/README.md +0 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/examples/main.py +0 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_sdk/application/__init__.py +0 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_sdk/domain/__init__.py +0 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_sdk/infrastructure/__init__.py +0 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_sdk/infrastructure/api_client.py +0 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_wrapper_sdk.egg-info/dependency_links.txt +0 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_wrapper_sdk.egg-info/requires.txt +0 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_wrapper_sdk.egg-info/top_level.txt +0 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/setup.cfg +0 -0
- {robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/tests/main.py +0 -0
|
@@ -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 (
|
|
5
|
-
|
|
6
|
-
|
|
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.
|
|
12
|
+
__version__ = "0.2.24"
|
|
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:
|
|
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:
|
|
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
|
|
2
|
-
|
|
3
|
-
from ..domain.entities import
|
|
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(
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
3
|
-
|
|
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:
|
|
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:
|
|
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
|
|
3
|
-
|
|
4
|
-
from ..domain.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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:
|
|
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(
|
|
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:
|
|
224
|
-
|
|
225
|
-
if
|
|
226
|
-
|
|
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,
|
|
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:
|
|
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(
|
|
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)
|
|
@@ -263,6 +267,13 @@ class RobotAPIRepository(RobotRepository):
|
|
|
263
267
|
json={"robot_ids": robot_ids},
|
|
264
268
|
)
|
|
265
269
|
|
|
270
|
+
def unlock_acquire_tasks(self, robot_ids: List[str]) -> None:
|
|
271
|
+
self.client.request(
|
|
272
|
+
"POST",
|
|
273
|
+
"/robots/acquire/unlock",
|
|
274
|
+
json={"robot_ids": robot_ids},
|
|
275
|
+
)
|
|
276
|
+
|
|
266
277
|
def unlock_hardening_tasks(self, robot_ids: List[str]) -> None:
|
|
267
278
|
self.client.request(
|
|
268
279
|
"POST",
|
|
@@ -294,13 +305,15 @@ class RobotAPIRepository(RobotRepository):
|
|
|
294
305
|
)
|
|
295
306
|
|
|
296
307
|
def update_robot(self, robot_id: str, payload: UpdateRobotRequest) -> None:
|
|
297
|
-
self.client.request(
|
|
308
|
+
self.client.request(
|
|
309
|
+
"PUT", f"/robots/{robot_id}", json=_compact_update_payload(payload))
|
|
298
310
|
|
|
299
311
|
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
312
|
resp = self.client.request(
|
|
301
313
|
"POST",
|
|
302
314
|
"/browser/open",
|
|
303
|
-
json=_browser_open_payload(
|
|
315
|
+
json=_browser_open_payload(
|
|
316
|
+
robot_id, username, proxy, country_code, extra_data),
|
|
304
317
|
)
|
|
305
318
|
return _to_browser_session(resp)
|
|
306
319
|
|
|
@@ -350,6 +363,7 @@ class RobotAPIRepository(RobotRepository):
|
|
|
350
363
|
)
|
|
351
364
|
return _to_browser_capture(resp)
|
|
352
365
|
|
|
366
|
+
|
|
353
367
|
class AsyncRobotAPIRepository(AsyncRobotRepository):
|
|
354
368
|
def __init__(self, client: AsyncHTTPClient):
|
|
355
369
|
self.client = client
|
|
@@ -378,10 +392,14 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
|
|
|
378
392
|
|
|
379
393
|
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
394
|
params: Dict[str, Any] = {"page": page, "limit": limit}
|
|
381
|
-
if platform:
|
|
382
|
-
|
|
383
|
-
if
|
|
384
|
-
|
|
395
|
+
if platform:
|
|
396
|
+
params["platform"] = platform
|
|
397
|
+
if status:
|
|
398
|
+
params["status"] = status
|
|
399
|
+
if auth_status:
|
|
400
|
+
params["auth_status"] = auth_status
|
|
401
|
+
if project_id:
|
|
402
|
+
params["project_id"] = project_id
|
|
385
403
|
|
|
386
404
|
resp = await self.client.request("GET", "/robots", params=params)
|
|
387
405
|
data, total = _extract_list_payload(resp)
|
|
@@ -400,16 +418,18 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
|
|
|
400
418
|
resp = await self.client.request(
|
|
401
419
|
"POST",
|
|
402
420
|
"/robots/security-hardened/acquire",
|
|
403
|
-
json=_acquire_payload(limit, lock_minutes,
|
|
421
|
+
json=_acquire_payload(limit, lock_minutes,
|
|
422
|
+
platforms, min_age_days),
|
|
404
423
|
)
|
|
405
424
|
data = _extract_items(resp)
|
|
406
425
|
return _to_robots(data)
|
|
407
426
|
|
|
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:
|
|
427
|
+
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
428
|
resp = await self.client.request(
|
|
410
429
|
"POST",
|
|
411
430
|
"/robots/acquire",
|
|
412
|
-
json=_acquire_robots_payload(
|
|
431
|
+
json=_acquire_robots_payload(
|
|
432
|
+
limit, lock_minutes, project_name, platform, environment, metadata),
|
|
413
433
|
)
|
|
414
434
|
data = _extract_items(resp)
|
|
415
435
|
return _to_robots(data)
|
|
@@ -458,7 +478,8 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
|
|
|
458
478
|
resp = await self.client.request(
|
|
459
479
|
"POST",
|
|
460
480
|
"/browser/open",
|
|
461
|
-
json=_browser_open_payload(
|
|
481
|
+
json=_browser_open_payload(
|
|
482
|
+
robot_id, username, proxy, country_code, extra_data),
|
|
462
483
|
)
|
|
463
484
|
return _to_browser_session(resp)
|
|
464
485
|
|
|
@@ -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)
|
{robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_wrapper_sdk.egg-info/SOURCES.txt
RENAMED
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_sdk/infrastructure/api_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_wrapper_sdk.egg-info/requires.txt
RENAMED
|
File without changes
|
{robot_wrapper_sdk-0.2.22 → robot_wrapper_sdk-0.2.24}/robot_wrapper_sdk.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|