robot-wrapper-sdk 0.2.6__tar.gz → 0.2.8__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.6 → robot_wrapper_sdk-0.2.8}/PKG-INFO +19 -8
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/README.md +18 -7
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/pyproject.toml +1 -1
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_sdk/__init__.py +19 -6
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_sdk/application/usecases.py +11 -5
- robot_wrapper_sdk-0.2.8/robot_sdk/domain/entities.py +118 -0
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_sdk/domain/repositories.py +13 -5
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_sdk/infrastructure/api_client.py +25 -1
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_sdk/infrastructure/robot_api_repository.py +73 -17
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_wrapper_sdk.egg-info/PKG-INFO +19 -8
- robot_wrapper_sdk-0.2.6/robot_sdk/domain/entities.py +0 -51
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/examples/main.py +0 -0
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_sdk/application/__init__.py +0 -0
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_sdk/domain/__init__.py +0 -0
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_sdk/infrastructure/__init__.py +0 -0
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_wrapper_sdk.egg-info/SOURCES.txt +0 -0
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_wrapper_sdk.egg-info/dependency_links.txt +0 -0
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_wrapper_sdk.egg-info/requires.txt +0 -0
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_wrapper_sdk.egg-info/top_level.txt +0 -0
- {robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: robot-wrapper-sdk
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Robot Platform API SDK
|
|
5
5
|
Author-email: GH Robot Platform Team <team@ghrobot.com>
|
|
6
6
|
License: MIT
|
|
@@ -38,7 +38,7 @@ Or pass values directly when creating the module.
|
|
|
38
38
|
## Quick Start (Sync)
|
|
39
39
|
|
|
40
40
|
```python
|
|
41
|
-
from robot_sdk import RobotPlatformModule
|
|
41
|
+
from robot_sdk import RobotPlatformModule, RobotStatus, RobotAuthStatus
|
|
42
42
|
|
|
43
43
|
sdk = RobotPlatformModule(
|
|
44
44
|
base_url="http://localhost:8085",
|
|
@@ -51,14 +51,14 @@ sdk = RobotPlatformModule(
|
|
|
51
51
|
robot = sdk.get_robot("2047631542552334336")
|
|
52
52
|
print(robot.platform if robot else "not found")
|
|
53
53
|
|
|
54
|
-
# Update lifecycle status
|
|
55
|
-
sdk.update_status("2047631542552334336",
|
|
54
|
+
# Update lifecycle status (prefer enum)
|
|
55
|
+
sdk.update_status("2047631542552334336", RobotStatus.LIVE)
|
|
56
56
|
|
|
57
57
|
# Acquire login tasks
|
|
58
58
|
login_tasks = sdk.acquire_need_login(limit=20, lock_minutes=30)
|
|
59
59
|
|
|
60
|
-
# Update auth status after worker result
|
|
61
|
-
sdk.update_auth_status("2047631542552334336",
|
|
60
|
+
# Update auth status after worker result (prefer enum)
|
|
61
|
+
sdk.update_auth_status("2047631542552334336", RobotAuthStatus.AUTHORIZED)
|
|
62
62
|
# allowed values: authorized | unauthorized | logged_out
|
|
63
63
|
|
|
64
64
|
# Acquire hardening tasks
|
|
@@ -67,6 +67,12 @@ hardening_tasks = sdk.acquire_unhardened(limit=20, lock_minutes=30, min_age_days
|
|
|
67
67
|
# Update hardening status after worker result
|
|
68
68
|
sdk.update_security_hardened("2047631542552334336", True)
|
|
69
69
|
|
|
70
|
+
# Update metadata (partial patch)
|
|
71
|
+
sdk.update_metadata("2047631542552334336", {
|
|
72
|
+
"country_code": "VN",
|
|
73
|
+
"note": "updated by sdk"
|
|
74
|
+
})
|
|
75
|
+
|
|
70
76
|
sdk.close()
|
|
71
77
|
```
|
|
72
78
|
|
|
@@ -74,7 +80,7 @@ sdk.close()
|
|
|
74
80
|
|
|
75
81
|
```python
|
|
76
82
|
import asyncio
|
|
77
|
-
from robot_sdk import AsyncRobotPlatformModule
|
|
83
|
+
from robot_sdk import AsyncRobotPlatformModule, RobotAuthStatus
|
|
78
84
|
|
|
79
85
|
async def main():
|
|
80
86
|
sdk = AsyncRobotPlatformModule(
|
|
@@ -86,8 +92,12 @@ async def main():
|
|
|
86
92
|
robot = await sdk.get_robot("2047631542552334336")
|
|
87
93
|
print(robot.platform if robot else "not found")
|
|
88
94
|
|
|
89
|
-
await sdk.update_auth_status("2047631542552334336",
|
|
95
|
+
await sdk.update_auth_status("2047631542552334336", RobotAuthStatus.AUTHORIZED)
|
|
90
96
|
await sdk.update_security_hardened("2047631542552334336", True)
|
|
97
|
+
await sdk.update_metadata("2047631542552334336", {
|
|
98
|
+
"country_code": "VN",
|
|
99
|
+
"note": "updated by async sdk"
|
|
100
|
+
})
|
|
91
101
|
|
|
92
102
|
await sdk.close()
|
|
93
103
|
|
|
@@ -145,6 +155,7 @@ Update endpoints return:
|
|
|
145
155
|
- `acquire_unhardened(limit=20, lock_minutes=30, min_age_days=0)`
|
|
146
156
|
- `update_auth_status(robot_id, auth_status)`
|
|
147
157
|
- `update_security_hardened(robot_id, security_hardened)`
|
|
158
|
+
- `update_metadata(robot_id, metadata)`
|
|
148
159
|
- `close()`
|
|
149
160
|
|
|
150
161
|
### `AsyncRobotPlatformModule` (async)
|
|
@@ -28,7 +28,7 @@ Or pass values directly when creating the module.
|
|
|
28
28
|
## Quick Start (Sync)
|
|
29
29
|
|
|
30
30
|
```python
|
|
31
|
-
from robot_sdk import RobotPlatformModule
|
|
31
|
+
from robot_sdk import RobotPlatformModule, RobotStatus, RobotAuthStatus
|
|
32
32
|
|
|
33
33
|
sdk = RobotPlatformModule(
|
|
34
34
|
base_url="http://localhost:8085",
|
|
@@ -41,14 +41,14 @@ sdk = RobotPlatformModule(
|
|
|
41
41
|
robot = sdk.get_robot("2047631542552334336")
|
|
42
42
|
print(robot.platform if robot else "not found")
|
|
43
43
|
|
|
44
|
-
# Update lifecycle status
|
|
45
|
-
sdk.update_status("2047631542552334336",
|
|
44
|
+
# Update lifecycle status (prefer enum)
|
|
45
|
+
sdk.update_status("2047631542552334336", RobotStatus.LIVE)
|
|
46
46
|
|
|
47
47
|
# Acquire login tasks
|
|
48
48
|
login_tasks = sdk.acquire_need_login(limit=20, lock_minutes=30)
|
|
49
49
|
|
|
50
|
-
# Update auth status after worker result
|
|
51
|
-
sdk.update_auth_status("2047631542552334336",
|
|
50
|
+
# Update auth status after worker result (prefer enum)
|
|
51
|
+
sdk.update_auth_status("2047631542552334336", RobotAuthStatus.AUTHORIZED)
|
|
52
52
|
# allowed values: authorized | unauthorized | logged_out
|
|
53
53
|
|
|
54
54
|
# Acquire hardening tasks
|
|
@@ -57,6 +57,12 @@ hardening_tasks = sdk.acquire_unhardened(limit=20, lock_minutes=30, min_age_days
|
|
|
57
57
|
# Update hardening status after worker result
|
|
58
58
|
sdk.update_security_hardened("2047631542552334336", True)
|
|
59
59
|
|
|
60
|
+
# Update metadata (partial patch)
|
|
61
|
+
sdk.update_metadata("2047631542552334336", {
|
|
62
|
+
"country_code": "VN",
|
|
63
|
+
"note": "updated by sdk"
|
|
64
|
+
})
|
|
65
|
+
|
|
60
66
|
sdk.close()
|
|
61
67
|
```
|
|
62
68
|
|
|
@@ -64,7 +70,7 @@ sdk.close()
|
|
|
64
70
|
|
|
65
71
|
```python
|
|
66
72
|
import asyncio
|
|
67
|
-
from robot_sdk import AsyncRobotPlatformModule
|
|
73
|
+
from robot_sdk import AsyncRobotPlatformModule, RobotAuthStatus
|
|
68
74
|
|
|
69
75
|
async def main():
|
|
70
76
|
sdk = AsyncRobotPlatformModule(
|
|
@@ -76,8 +82,12 @@ async def main():
|
|
|
76
82
|
robot = await sdk.get_robot("2047631542552334336")
|
|
77
83
|
print(robot.platform if robot else "not found")
|
|
78
84
|
|
|
79
|
-
await sdk.update_auth_status("2047631542552334336",
|
|
85
|
+
await sdk.update_auth_status("2047631542552334336", RobotAuthStatus.AUTHORIZED)
|
|
80
86
|
await sdk.update_security_hardened("2047631542552334336", True)
|
|
87
|
+
await sdk.update_metadata("2047631542552334336", {
|
|
88
|
+
"country_code": "VN",
|
|
89
|
+
"note": "updated by async sdk"
|
|
90
|
+
})
|
|
81
91
|
|
|
82
92
|
await sdk.close()
|
|
83
93
|
|
|
@@ -135,6 +145,7 @@ Update endpoints return:
|
|
|
135
145
|
- `acquire_unhardened(limit=20, lock_minutes=30, min_age_days=0)`
|
|
136
146
|
- `update_auth_status(robot_id, auth_status)`
|
|
137
147
|
- `update_security_hardened(robot_id, security_hardened)`
|
|
148
|
+
- `update_metadata(robot_id, metadata)`
|
|
138
149
|
- `close()`
|
|
139
150
|
|
|
140
151
|
### `AsyncRobotPlatformModule` (async)
|
|
@@ -2,7 +2,7 @@ from typing import Optional, List, Dict, Any, Tuple
|
|
|
2
2
|
from .infrastructure.api_client import HTTPClient, AsyncHTTPClient
|
|
3
3
|
from .infrastructure.robot_api_repository import RobotAPIRepository, AsyncRobotAPIRepository
|
|
4
4
|
from .application.usecases import RobotUsecase, AsyncRobotUsecase
|
|
5
|
-
from .domain.entities import Robot, RobotSecrets
|
|
5
|
+
from .domain.entities import Robot, RobotSecrets, RobotStatus, RobotAuthStatus
|
|
6
6
|
|
|
7
7
|
__version__ = "0.2.1"
|
|
8
8
|
|
|
@@ -28,7 +28,7 @@ class RobotPlatformModule:
|
|
|
28
28
|
def get_secrets(self, robot_id: str) -> Optional[RobotSecrets]:
|
|
29
29
|
return self.robot_usecase.get_secrets(robot_id)
|
|
30
30
|
|
|
31
|
-
def update_status(self, robot_id: str, status: str) -> None:
|
|
31
|
+
def update_status(self, robot_id: str, status: str | RobotStatus) -> None:
|
|
32
32
|
self.robot_usecase.update_status(robot_id, status)
|
|
33
33
|
|
|
34
34
|
def acquire_need_login(self, limit: int = 20, lock_minutes: int = 30):
|
|
@@ -37,12 +37,15 @@ class RobotPlatformModule:
|
|
|
37
37
|
def acquire_unhardened(self, limit: int = 20, lock_minutes: int = 30, min_age_days: int = 0):
|
|
38
38
|
return self.robot_usecase.acquire_unhardened(limit, lock_minutes, min_age_days)
|
|
39
39
|
|
|
40
|
-
def update_auth_status(self, robot_id: str, auth_status: str) -> None:
|
|
40
|
+
def update_auth_status(self, robot_id: str, auth_status: str | RobotAuthStatus) -> None:
|
|
41
41
|
self.robot_usecase.update_auth_status(robot_id, auth_status)
|
|
42
42
|
|
|
43
43
|
def update_security_hardened(self, robot_id: str, security_hardened: bool) -> None:
|
|
44
44
|
self.robot_usecase.update_security_hardened(robot_id, security_hardened)
|
|
45
45
|
|
|
46
|
+
def update_metadata(self, robot_id: str, metadata: Dict[str, Any]) -> None:
|
|
47
|
+
self.robot_usecase.update_metadata(robot_id, metadata)
|
|
48
|
+
|
|
46
49
|
|
|
47
50
|
class AsyncRobotPlatformModule:
|
|
48
51
|
"""Asynchronous Facade for the Robot Platform SDK."""
|
|
@@ -66,7 +69,7 @@ class AsyncRobotPlatformModule:
|
|
|
66
69
|
async def get_secrets(self, robot_id: str) -> Optional[RobotSecrets]:
|
|
67
70
|
return await self.robot_usecase.get_secrets(robot_id)
|
|
68
71
|
|
|
69
|
-
async def update_status(self, robot_id: str, status: str) -> None:
|
|
72
|
+
async def update_status(self, robot_id: str, status: str | RobotStatus) -> None:
|
|
70
73
|
await self.robot_usecase.update_status(robot_id, status)
|
|
71
74
|
|
|
72
75
|
async def acquire_need_login(self, limit: int = 20, lock_minutes: int = 30):
|
|
@@ -75,10 +78,20 @@ class AsyncRobotPlatformModule:
|
|
|
75
78
|
async def acquire_unhardened(self, limit: int = 20, lock_minutes: int = 30, min_age_days: int = 0):
|
|
76
79
|
return await self.robot_usecase.acquire_unhardened(limit, lock_minutes, min_age_days)
|
|
77
80
|
|
|
78
|
-
async def update_auth_status(self, robot_id: str, auth_status: str) -> None:
|
|
81
|
+
async def update_auth_status(self, robot_id: str, auth_status: str | RobotAuthStatus) -> None:
|
|
79
82
|
await self.robot_usecase.update_auth_status(robot_id, auth_status)
|
|
80
83
|
|
|
81
84
|
async def update_security_hardened(self, robot_id: str, security_hardened: bool) -> None:
|
|
82
85
|
await self.robot_usecase.update_security_hardened(robot_id, security_hardened)
|
|
83
86
|
|
|
84
|
-
|
|
87
|
+
async def update_metadata(self, robot_id: str, metadata: Dict[str, Any]) -> None:
|
|
88
|
+
await self.robot_usecase.update_metadata(robot_id, metadata)
|
|
89
|
+
|
|
90
|
+
__all__ = [
|
|
91
|
+
"RobotPlatformModule",
|
|
92
|
+
"AsyncRobotPlatformModule",
|
|
93
|
+
"Robot",
|
|
94
|
+
"RobotSecrets",
|
|
95
|
+
"RobotStatus",
|
|
96
|
+
"RobotAuthStatus",
|
|
97
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Optional, List, Tuple, Any, Dict
|
|
2
2
|
from ..domain.repositories import RobotRepository, AsyncRobotRepository
|
|
3
|
-
from ..domain.entities import Robot, RobotSecrets
|
|
3
|
+
from ..domain.entities import Robot, RobotSecrets, RobotStatus, RobotAuthStatus
|
|
4
4
|
|
|
5
5
|
class RobotUsecase:
|
|
6
6
|
def __init__(self, repo: RobotRepository):
|
|
@@ -15,7 +15,7 @@ class RobotUsecase:
|
|
|
15
15
|
def get_secrets(self, robot_id: str) -> Optional[RobotSecrets]:
|
|
16
16
|
return self.repo.get_secrets(robot_id)
|
|
17
17
|
|
|
18
|
-
def update_status(self, robot_id: str, status: str) -> None:
|
|
18
|
+
def update_status(self, robot_id: str, status: str | RobotStatus) -> None:
|
|
19
19
|
self.repo.update_status(robot_id, status)
|
|
20
20
|
|
|
21
21
|
def list_robots(self, platform: Optional[str] = None, status: Optional[str] = None, project_id: Optional[int] = None, page: int = 1, limit: int = 20) -> Dict[str, Any]:
|
|
@@ -33,12 +33,15 @@ class RobotUsecase:
|
|
|
33
33
|
def acquire_unhardened(self, limit: int = 20, lock_minutes: int = 30, min_age_days: int = 0) -> List[Robot]:
|
|
34
34
|
return self.repo.acquire_unhardened(limit, lock_minutes, min_age_days)
|
|
35
35
|
|
|
36
|
-
def update_auth_status(self, robot_id: str, auth_status: str) -> None:
|
|
36
|
+
def update_auth_status(self, robot_id: str, auth_status: str | RobotAuthStatus) -> None:
|
|
37
37
|
self.repo.update_auth_status(robot_id, auth_status)
|
|
38
38
|
|
|
39
39
|
def update_security_hardened(self, robot_id: str, security_hardened: bool) -> None:
|
|
40
40
|
self.repo.update_security_hardened(robot_id, security_hardened)
|
|
41
41
|
|
|
42
|
+
def update_metadata(self, robot_id: str, metadata: Dict[str, Any]) -> None:
|
|
43
|
+
self.repo.update_metadata(robot_id, metadata)
|
|
44
|
+
|
|
42
45
|
|
|
43
46
|
class AsyncRobotUsecase:
|
|
44
47
|
def __init__(self, repo: AsyncRobotRepository):
|
|
@@ -53,7 +56,7 @@ class AsyncRobotUsecase:
|
|
|
53
56
|
async def get_secrets(self, robot_id: str) -> Optional[RobotSecrets]:
|
|
54
57
|
return await self.repo.get_secrets(robot_id)
|
|
55
58
|
|
|
56
|
-
async def update_status(self, robot_id: str, status: str) -> None:
|
|
59
|
+
async def update_status(self, robot_id: str, status: str | RobotStatus) -> None:
|
|
57
60
|
await self.repo.update_status(robot_id, status)
|
|
58
61
|
|
|
59
62
|
async def list_robots(self, platform: Optional[str] = None, status: Optional[str] = None, project_id: Optional[int] = None, page: int = 1, limit: int = 20) -> Dict[str, Any]:
|
|
@@ -71,8 +74,11 @@ class AsyncRobotUsecase:
|
|
|
71
74
|
async def acquire_unhardened(self, limit: int = 20, lock_minutes: int = 30, min_age_days: int = 0) -> List[Robot]:
|
|
72
75
|
return await self.repo.acquire_unhardened(limit, lock_minutes, min_age_days)
|
|
73
76
|
|
|
74
|
-
async def update_auth_status(self, robot_id: str, auth_status: str) -> None:
|
|
77
|
+
async def update_auth_status(self, robot_id: str, auth_status: str | RobotAuthStatus) -> None:
|
|
75
78
|
await self.repo.update_auth_status(robot_id, auth_status)
|
|
76
79
|
|
|
77
80
|
async def update_security_hardened(self, robot_id: str, security_hardened: bool) -> None:
|
|
78
81
|
await self.repo.update_security_hardened(robot_id, security_hardened)
|
|
82
|
+
|
|
83
|
+
async def update_metadata(self, robot_id: str, metadata: Dict[str, Any]) -> None:
|
|
84
|
+
await self.repo.update_metadata(robot_id, metadata)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Optional, Any, Dict
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class RobotStatus(str, Enum):
|
|
7
|
+
LIVE = "live"
|
|
8
|
+
DEAD = "dead"
|
|
9
|
+
RUNNING = "running"
|
|
10
|
+
CHECKPOINT = "checkpoint"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class RobotAuthStatus(str, Enum):
|
|
14
|
+
AUTHORIZED = "authorized"
|
|
15
|
+
UNAUTHORIZED = "unauthorized"
|
|
16
|
+
LOGGED_OUT = "logged_out"
|
|
17
|
+
LOGIN_ERROR = "login_error"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def normalize_robot_status(status: str | RobotStatus) -> str:
|
|
21
|
+
if isinstance(status, RobotStatus):
|
|
22
|
+
return status.value
|
|
23
|
+
return str(status).strip().lower()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def normalize_robot_auth_status(status: str | RobotAuthStatus) -> str:
|
|
27
|
+
if isinstance(status, RobotAuthStatus):
|
|
28
|
+
return status.value
|
|
29
|
+
return str(status).strip().lower()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def ensure_valid_robot_status(status: str) -> None:
|
|
33
|
+
allowed = {s.value for s in RobotStatus}
|
|
34
|
+
if status not in allowed:
|
|
35
|
+
raise ValueError(f"invalid status: {status}. allowed={sorted(allowed)}")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def ensure_valid_robot_auth_status(status: str) -> None:
|
|
39
|
+
allowed = {s.value for s in RobotAuthStatus}
|
|
40
|
+
if status not in allowed:
|
|
41
|
+
raise ValueError(f"invalid auth_status: {status}. allowed={sorted(allowed)}")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def ensure_valid_worker_robot_auth_status(status: str) -> None:
|
|
45
|
+
ensure_valid_robot_auth_status(status)
|
|
46
|
+
if status == RobotAuthStatus.LOGIN_ERROR.value:
|
|
47
|
+
raise ValueError("auth_status login_error is not allowed for this endpoint")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def ensure_valid_worker_robot_status(status: str) -> None:
|
|
51
|
+
ensure_valid_robot_status(status)
|
|
52
|
+
if status == RobotStatus.CHECKPOINT.value:
|
|
53
|
+
raise ValueError("status checkpoint is not allowed for this endpoint")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def ensure_valid_metadata(metadata: Dict[str, Any]) -> None:
|
|
57
|
+
if not isinstance(metadata, dict):
|
|
58
|
+
raise ValueError("metadata must be a dict")
|
|
59
|
+
|
|
60
|
+
for key in metadata.keys():
|
|
61
|
+
if not isinstance(key, str):
|
|
62
|
+
raise ValueError("metadata keys must be strings")
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
import json
|
|
66
|
+
json.dumps(metadata)
|
|
67
|
+
except Exception as e:
|
|
68
|
+
raise ValueError(f"metadata must be JSON-serializable: {e}") from e
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass
|
|
72
|
+
class Robot:
|
|
73
|
+
id: str
|
|
74
|
+
username: str
|
|
75
|
+
platform: str
|
|
76
|
+
status: str
|
|
77
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
78
|
+
project_id: Optional[str] = None
|
|
79
|
+
primary_environment: Optional[str] = None
|
|
80
|
+
created_at: Optional[str] = None
|
|
81
|
+
|
|
82
|
+
@dataclass
|
|
83
|
+
class RobotSecrets:
|
|
84
|
+
password: str
|
|
85
|
+
two_fa_secret: str
|
|
86
|
+
|
|
87
|
+
@dataclass
|
|
88
|
+
class RobotActivity:
|
|
89
|
+
id: str
|
|
90
|
+
activity_type: str
|
|
91
|
+
status: str
|
|
92
|
+
message: str
|
|
93
|
+
|
|
94
|
+
@dataclass
|
|
95
|
+
class AcquireNeedLoginRequest:
|
|
96
|
+
limit: int = 20
|
|
97
|
+
lock_minutes: int = 30
|
|
98
|
+
|
|
99
|
+
@dataclass
|
|
100
|
+
class AcquireUnhardenedRequest:
|
|
101
|
+
limit: int = 20
|
|
102
|
+
lock_minutes: int = 30
|
|
103
|
+
min_age_days: int = 0
|
|
104
|
+
|
|
105
|
+
@dataclass
|
|
106
|
+
class UpdateAuthStatusRequest:
|
|
107
|
+
auth_status: str
|
|
108
|
+
|
|
109
|
+
@dataclass
|
|
110
|
+
class UpdateSecurityHardenedRequest:
|
|
111
|
+
security_hardened: bool
|
|
112
|
+
|
|
113
|
+
@dataclass
|
|
114
|
+
class StandardResponse:
|
|
115
|
+
status: str
|
|
116
|
+
code: int
|
|
117
|
+
message: str
|
|
118
|
+
data: Any = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
from typing import Optional, List, Tuple
|
|
3
|
-
from .entities import Robot, RobotSecrets
|
|
3
|
+
from .entities import Robot, RobotSecrets, RobotStatus, RobotAuthStatus
|
|
4
4
|
|
|
5
5
|
class RobotRepository(ABC):
|
|
6
6
|
@abstractmethod
|
|
@@ -8,7 +8,7 @@ class RobotRepository(ABC):
|
|
|
8
8
|
pass
|
|
9
9
|
|
|
10
10
|
@abstractmethod
|
|
11
|
-
def update_status(self, robot_id: str, status: str) -> None:
|
|
11
|
+
def update_status(self, robot_id: str, status: str | RobotStatus) -> None:
|
|
12
12
|
pass
|
|
13
13
|
|
|
14
14
|
@abstractmethod
|
|
@@ -32,20 +32,24 @@ class RobotRepository(ABC):
|
|
|
32
32
|
pass
|
|
33
33
|
|
|
34
34
|
@abstractmethod
|
|
35
|
-
def update_auth_status(self, robot_id: str, auth_status: str) -> None:
|
|
35
|
+
def update_auth_status(self, robot_id: str, auth_status: str | RobotAuthStatus) -> None:
|
|
36
36
|
pass
|
|
37
37
|
|
|
38
38
|
@abstractmethod
|
|
39
39
|
def update_security_hardened(self, robot_id: str, security_hardened: bool) -> None:
|
|
40
40
|
pass
|
|
41
41
|
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def update_metadata(self, robot_id: str, metadata: dict) -> None:
|
|
44
|
+
pass
|
|
45
|
+
|
|
42
46
|
class AsyncRobotRepository(ABC):
|
|
43
47
|
@abstractmethod
|
|
44
48
|
async def find_by_id(self, robot_id: str) -> Optional[Robot]:
|
|
45
49
|
pass
|
|
46
50
|
|
|
47
51
|
@abstractmethod
|
|
48
|
-
async def update_status(self, robot_id: str, status: str) -> None:
|
|
52
|
+
async def update_status(self, robot_id: str, status: str | RobotStatus) -> None:
|
|
49
53
|
pass
|
|
50
54
|
|
|
51
55
|
@abstractmethod
|
|
@@ -69,9 +73,13 @@ class AsyncRobotRepository(ABC):
|
|
|
69
73
|
pass
|
|
70
74
|
|
|
71
75
|
@abstractmethod
|
|
72
|
-
async def update_auth_status(self, robot_id: str, auth_status: str) -> None:
|
|
76
|
+
async def update_auth_status(self, robot_id: str, auth_status: str | RobotAuthStatus) -> None:
|
|
73
77
|
pass
|
|
74
78
|
|
|
75
79
|
@abstractmethod
|
|
76
80
|
async def update_security_hardened(self, robot_id: str, security_hardened: bool) -> None:
|
|
77
81
|
pass
|
|
82
|
+
|
|
83
|
+
@abstractmethod
|
|
84
|
+
async def update_metadata(self, robot_id: str, metadata: dict) -> None:
|
|
85
|
+
pass
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import httpx
|
|
2
2
|
import os
|
|
3
3
|
from typing import Dict, Any, Optional
|
|
4
|
+
from httpx import RemoteProtocolError
|
|
4
5
|
|
|
5
6
|
def _extract_tokens(payload: Dict[str, Any]) -> tuple[Optional[str], Optional[str]]:
|
|
6
7
|
data = payload.get("data") if isinstance(payload, dict) else None
|
|
@@ -132,7 +133,30 @@ class HTTPClient:
|
|
|
132
133
|
full_path = f"/api/v1/developer{path}"
|
|
133
134
|
|
|
134
135
|
print(f"🚀 Requesting: {self.base_url}{full_path}")
|
|
135
|
-
|
|
136
|
+
last_err: Optional[Exception] = None
|
|
137
|
+
resp = None
|
|
138
|
+
for attempt in range(2):
|
|
139
|
+
try:
|
|
140
|
+
resp = self.client.request(method, full_path, **kwargs)
|
|
141
|
+
break
|
|
142
|
+
except Exception as err:
|
|
143
|
+
msg = str(err)
|
|
144
|
+
is_disconnect = isinstance(err, RemoteProtocolError) or "Server disconnected without sending a response" in msg
|
|
145
|
+
if not is_disconnect or attempt == 1:
|
|
146
|
+
raise
|
|
147
|
+
last_err = err
|
|
148
|
+
self.client.close()
|
|
149
|
+
self.client = httpx.Client(
|
|
150
|
+
base_url=self.base_url,
|
|
151
|
+
auth=RobotAuth(self._get_or_login, self._refresh),
|
|
152
|
+
proxy=self.proxy_url,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
if resp is None:
|
|
156
|
+
if last_err is not None:
|
|
157
|
+
raise last_err
|
|
158
|
+
raise RuntimeError("Request failed without response")
|
|
159
|
+
|
|
136
160
|
resp.raise_for_status()
|
|
137
161
|
try:
|
|
138
162
|
return dict(resp.json())
|
{robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_sdk/infrastructure/robot_api_repository.py
RENAMED
|
@@ -1,7 +1,43 @@
|
|
|
1
1
|
from typing import Optional, List, Tuple, Dict, Any
|
|
2
2
|
from .api_client import HTTPClient, AsyncHTTPClient
|
|
3
3
|
from ..domain.repositories import RobotRepository, AsyncRobotRepository
|
|
4
|
-
from ..domain.entities import
|
|
4
|
+
from ..domain.entities import (
|
|
5
|
+
Robot,
|
|
6
|
+
RobotSecrets,
|
|
7
|
+
RobotStatus,
|
|
8
|
+
RobotAuthStatus,
|
|
9
|
+
normalize_robot_status,
|
|
10
|
+
normalize_robot_auth_status,
|
|
11
|
+
ensure_valid_worker_robot_status,
|
|
12
|
+
ensure_valid_worker_robot_auth_status,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _extract_list_payload(resp: Dict[str, Any]) -> Tuple[List[Dict[str, Any]], int]:
|
|
17
|
+
container = resp.get("data") if isinstance(resp, dict) else None
|
|
18
|
+
if isinstance(container, dict):
|
|
19
|
+
items = container.get("data")
|
|
20
|
+
total = container.get("total", 0)
|
|
21
|
+
else:
|
|
22
|
+
items = container
|
|
23
|
+
total = resp.get("total", 0) if isinstance(resp, dict) else 0
|
|
24
|
+
|
|
25
|
+
if not isinstance(items, list):
|
|
26
|
+
return [], int(total) if isinstance(total, int) else 0
|
|
27
|
+
|
|
28
|
+
mapped = [item for item in items if isinstance(item, dict)]
|
|
29
|
+
return mapped, int(total) if isinstance(total, int) else 0
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _extract_items(resp: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
33
|
+
container = resp.get("data") if isinstance(resp, dict) else None
|
|
34
|
+
if isinstance(container, list):
|
|
35
|
+
return [item for item in container if isinstance(item, dict)]
|
|
36
|
+
if isinstance(container, dict):
|
|
37
|
+
nested = container.get("data")
|
|
38
|
+
if isinstance(nested, list):
|
|
39
|
+
return [item for item in nested if isinstance(item, dict)]
|
|
40
|
+
return []
|
|
5
41
|
|
|
6
42
|
class RobotAPIRepository(RobotRepository):
|
|
7
43
|
def __init__(self, client: HTTPClient):
|
|
@@ -11,8 +47,10 @@ class RobotAPIRepository(RobotRepository):
|
|
|
11
47
|
resp = self.client.request("GET", f"/robots/{robot_id}")
|
|
12
48
|
return Robot(**resp) if resp else None
|
|
13
49
|
|
|
14
|
-
def update_status(self, robot_id: str, status: str) -> None:
|
|
15
|
-
|
|
50
|
+
def update_status(self, robot_id: str, status: str | RobotStatus) -> None:
|
|
51
|
+
normalized_status = normalize_robot_status(status)
|
|
52
|
+
ensure_valid_worker_robot_status(normalized_status)
|
|
53
|
+
self.client.request("PATCH", f"/robots/{robot_id}/status", json={"status": normalized_status})
|
|
16
54
|
|
|
17
55
|
def delete_robot(self, robot_id: str) -> None:
|
|
18
56
|
self.client.request("DELETE", f"/robots/{robot_id}")
|
|
@@ -28,8 +66,7 @@ class RobotAPIRepository(RobotRepository):
|
|
|
28
66
|
if project_id: params["project_id"] = project_id
|
|
29
67
|
|
|
30
68
|
resp = self.client.request("GET", "/robots", params=params)
|
|
31
|
-
data = resp
|
|
32
|
-
total = resp.get("total", 0)
|
|
69
|
+
data, total = _extract_list_payload(resp)
|
|
33
70
|
return [Robot(**r) for r in data], total
|
|
34
71
|
|
|
35
72
|
def acquire_need_login(self, limit: int = 20, lock_minutes: int = 30) -> List[Robot]:
|
|
@@ -38,7 +75,7 @@ class RobotAPIRepository(RobotRepository):
|
|
|
38
75
|
"/robots/login/acquire",
|
|
39
76
|
json={"limit": limit, "lock_minutes": lock_minutes},
|
|
40
77
|
)
|
|
41
|
-
data = resp
|
|
78
|
+
data = _extract_items(resp)
|
|
42
79
|
return [Robot(**r) for r in data]
|
|
43
80
|
|
|
44
81
|
def acquire_unhardened(self, limit: int = 20, lock_minutes: int = 30, min_age_days: int = 0) -> List[Robot]:
|
|
@@ -47,14 +84,16 @@ class RobotAPIRepository(RobotRepository):
|
|
|
47
84
|
"/robots/security-hardened/acquire",
|
|
48
85
|
json={"limit": limit, "lock_minutes": lock_minutes, "min_age_days": min_age_days},
|
|
49
86
|
)
|
|
50
|
-
data = resp
|
|
87
|
+
data = _extract_items(resp)
|
|
51
88
|
return [Robot(**r) for r in data]
|
|
52
89
|
|
|
53
|
-
def update_auth_status(self, robot_id: str, auth_status: str) -> None:
|
|
90
|
+
def update_auth_status(self, robot_id: str, auth_status: str | RobotAuthStatus) -> None:
|
|
91
|
+
normalized_auth_status = normalize_robot_auth_status(auth_status)
|
|
92
|
+
ensure_valid_worker_robot_auth_status(normalized_auth_status)
|
|
54
93
|
self.client.request(
|
|
55
94
|
"PATCH",
|
|
56
95
|
f"/robots/{robot_id}/auth-status",
|
|
57
|
-
json={"auth_status":
|
|
96
|
+
json={"auth_status": normalized_auth_status},
|
|
58
97
|
)
|
|
59
98
|
|
|
60
99
|
def update_security_hardened(self, robot_id: str, security_hardened: bool) -> None:
|
|
@@ -64,6 +103,13 @@ class RobotAPIRepository(RobotRepository):
|
|
|
64
103
|
json={"security_hardened": security_hardened},
|
|
65
104
|
)
|
|
66
105
|
|
|
106
|
+
def update_metadata(self, robot_id: str, metadata: Dict[str, Any]) -> None:
|
|
107
|
+
self.client.request(
|
|
108
|
+
"PATCH",
|
|
109
|
+
f"/robots/{robot_id}",
|
|
110
|
+
json={"metadata": metadata},
|
|
111
|
+
)
|
|
112
|
+
|
|
67
113
|
class AsyncRobotAPIRepository(AsyncRobotRepository):
|
|
68
114
|
def __init__(self, client: AsyncHTTPClient):
|
|
69
115
|
self.client = client
|
|
@@ -72,8 +118,10 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
|
|
|
72
118
|
resp = await self.client.request("GET", f"/robots/{robot_id}")
|
|
73
119
|
return Robot(**resp) if resp else None
|
|
74
120
|
|
|
75
|
-
async def update_status(self, robot_id: str, status: str) -> None:
|
|
76
|
-
|
|
121
|
+
async def update_status(self, robot_id: str, status: str | RobotStatus) -> None:
|
|
122
|
+
normalized_status = normalize_robot_status(status)
|
|
123
|
+
ensure_valid_worker_robot_status(normalized_status)
|
|
124
|
+
await self.client.request("PATCH", f"/robots/{robot_id}/status", json={"status": normalized_status})
|
|
77
125
|
|
|
78
126
|
async def delete_robot(self, robot_id: str) -> None:
|
|
79
127
|
await self.client.request("DELETE", f"/robots/{robot_id}")
|
|
@@ -89,8 +137,7 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
|
|
|
89
137
|
if project_id: params["project_id"] = project_id
|
|
90
138
|
|
|
91
139
|
resp = await self.client.request("GET", "/robots", params=params)
|
|
92
|
-
data = resp
|
|
93
|
-
total = resp.get("total", 0)
|
|
140
|
+
data, total = _extract_list_payload(resp)
|
|
94
141
|
return [Robot(**r) for r in data], total
|
|
95
142
|
|
|
96
143
|
async def acquire_need_login(self, limit: int = 20, lock_minutes: int = 30) -> List[Robot]:
|
|
@@ -99,7 +146,7 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
|
|
|
99
146
|
"/robots/login/acquire",
|
|
100
147
|
json={"limit": limit, "lock_minutes": lock_minutes},
|
|
101
148
|
)
|
|
102
|
-
data = resp
|
|
149
|
+
data = _extract_items(resp)
|
|
103
150
|
return [Robot(**r) for r in data]
|
|
104
151
|
|
|
105
152
|
async def acquire_unhardened(self, limit: int = 20, lock_minutes: int = 30, min_age_days: int = 0) -> List[Robot]:
|
|
@@ -108,14 +155,16 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
|
|
|
108
155
|
"/robots/security-hardened/acquire",
|
|
109
156
|
json={"limit": limit, "lock_minutes": lock_minutes, "min_age_days": min_age_days},
|
|
110
157
|
)
|
|
111
|
-
data = resp
|
|
158
|
+
data = _extract_items(resp)
|
|
112
159
|
return [Robot(**r) for r in data]
|
|
113
160
|
|
|
114
|
-
async def update_auth_status(self, robot_id: str, auth_status: str) -> None:
|
|
161
|
+
async def update_auth_status(self, robot_id: str, auth_status: str | RobotAuthStatus) -> None:
|
|
162
|
+
normalized_auth_status = normalize_robot_auth_status(auth_status)
|
|
163
|
+
ensure_valid_worker_robot_auth_status(normalized_auth_status)
|
|
115
164
|
await self.client.request(
|
|
116
165
|
"PATCH",
|
|
117
166
|
f"/robots/{robot_id}/auth-status",
|
|
118
|
-
json={"auth_status":
|
|
167
|
+
json={"auth_status": normalized_auth_status},
|
|
119
168
|
)
|
|
120
169
|
|
|
121
170
|
async def update_security_hardened(self, robot_id: str, security_hardened: bool) -> None:
|
|
@@ -124,3 +173,10 @@ class AsyncRobotAPIRepository(AsyncRobotRepository):
|
|
|
124
173
|
f"/robots/{robot_id}/security-hardened",
|
|
125
174
|
json={"security_hardened": security_hardened},
|
|
126
175
|
)
|
|
176
|
+
|
|
177
|
+
async def update_metadata(self, robot_id: str, metadata: Dict[str, Any]) -> None:
|
|
178
|
+
await self.client.request(
|
|
179
|
+
"PATCH",
|
|
180
|
+
f"/robots/{robot_id}",
|
|
181
|
+
json={"metadata": metadata},
|
|
182
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: robot-wrapper-sdk
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Robot Platform API SDK
|
|
5
5
|
Author-email: GH Robot Platform Team <team@ghrobot.com>
|
|
6
6
|
License: MIT
|
|
@@ -38,7 +38,7 @@ Or pass values directly when creating the module.
|
|
|
38
38
|
## Quick Start (Sync)
|
|
39
39
|
|
|
40
40
|
```python
|
|
41
|
-
from robot_sdk import RobotPlatformModule
|
|
41
|
+
from robot_sdk import RobotPlatformModule, RobotStatus, RobotAuthStatus
|
|
42
42
|
|
|
43
43
|
sdk = RobotPlatformModule(
|
|
44
44
|
base_url="http://localhost:8085",
|
|
@@ -51,14 +51,14 @@ sdk = RobotPlatformModule(
|
|
|
51
51
|
robot = sdk.get_robot("2047631542552334336")
|
|
52
52
|
print(robot.platform if robot else "not found")
|
|
53
53
|
|
|
54
|
-
# Update lifecycle status
|
|
55
|
-
sdk.update_status("2047631542552334336",
|
|
54
|
+
# Update lifecycle status (prefer enum)
|
|
55
|
+
sdk.update_status("2047631542552334336", RobotStatus.LIVE)
|
|
56
56
|
|
|
57
57
|
# Acquire login tasks
|
|
58
58
|
login_tasks = sdk.acquire_need_login(limit=20, lock_minutes=30)
|
|
59
59
|
|
|
60
|
-
# Update auth status after worker result
|
|
61
|
-
sdk.update_auth_status("2047631542552334336",
|
|
60
|
+
# Update auth status after worker result (prefer enum)
|
|
61
|
+
sdk.update_auth_status("2047631542552334336", RobotAuthStatus.AUTHORIZED)
|
|
62
62
|
# allowed values: authorized | unauthorized | logged_out
|
|
63
63
|
|
|
64
64
|
# Acquire hardening tasks
|
|
@@ -67,6 +67,12 @@ hardening_tasks = sdk.acquire_unhardened(limit=20, lock_minutes=30, min_age_days
|
|
|
67
67
|
# Update hardening status after worker result
|
|
68
68
|
sdk.update_security_hardened("2047631542552334336", True)
|
|
69
69
|
|
|
70
|
+
# Update metadata (partial patch)
|
|
71
|
+
sdk.update_metadata("2047631542552334336", {
|
|
72
|
+
"country_code": "VN",
|
|
73
|
+
"note": "updated by sdk"
|
|
74
|
+
})
|
|
75
|
+
|
|
70
76
|
sdk.close()
|
|
71
77
|
```
|
|
72
78
|
|
|
@@ -74,7 +80,7 @@ sdk.close()
|
|
|
74
80
|
|
|
75
81
|
```python
|
|
76
82
|
import asyncio
|
|
77
|
-
from robot_sdk import AsyncRobotPlatformModule
|
|
83
|
+
from robot_sdk import AsyncRobotPlatformModule, RobotAuthStatus
|
|
78
84
|
|
|
79
85
|
async def main():
|
|
80
86
|
sdk = AsyncRobotPlatformModule(
|
|
@@ -86,8 +92,12 @@ async def main():
|
|
|
86
92
|
robot = await sdk.get_robot("2047631542552334336")
|
|
87
93
|
print(robot.platform if robot else "not found")
|
|
88
94
|
|
|
89
|
-
await sdk.update_auth_status("2047631542552334336",
|
|
95
|
+
await sdk.update_auth_status("2047631542552334336", RobotAuthStatus.AUTHORIZED)
|
|
90
96
|
await sdk.update_security_hardened("2047631542552334336", True)
|
|
97
|
+
await sdk.update_metadata("2047631542552334336", {
|
|
98
|
+
"country_code": "VN",
|
|
99
|
+
"note": "updated by async sdk"
|
|
100
|
+
})
|
|
91
101
|
|
|
92
102
|
await sdk.close()
|
|
93
103
|
|
|
@@ -145,6 +155,7 @@ Update endpoints return:
|
|
|
145
155
|
- `acquire_unhardened(limit=20, lock_minutes=30, min_age_days=0)`
|
|
146
156
|
- `update_auth_status(robot_id, auth_status)`
|
|
147
157
|
- `update_security_hardened(robot_id, security_hardened)`
|
|
158
|
+
- `update_metadata(robot_id, metadata)`
|
|
148
159
|
- `close()`
|
|
149
160
|
|
|
150
161
|
### `AsyncRobotPlatformModule` (async)
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass, field
|
|
2
|
-
from typing import Optional, Any, Dict
|
|
3
|
-
|
|
4
|
-
@dataclass
|
|
5
|
-
class Robot:
|
|
6
|
-
id: str
|
|
7
|
-
username: str
|
|
8
|
-
platform: str
|
|
9
|
-
status: str
|
|
10
|
-
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
11
|
-
project_id: Optional[str] = None
|
|
12
|
-
primary_environment: Optional[str] = None
|
|
13
|
-
created_at: Optional[str] = None
|
|
14
|
-
|
|
15
|
-
@dataclass
|
|
16
|
-
class RobotSecrets:
|
|
17
|
-
password: str
|
|
18
|
-
two_fa_secret: str
|
|
19
|
-
|
|
20
|
-
@dataclass
|
|
21
|
-
class RobotActivity:
|
|
22
|
-
id: str
|
|
23
|
-
activity_type: str
|
|
24
|
-
status: str
|
|
25
|
-
message: str
|
|
26
|
-
|
|
27
|
-
@dataclass
|
|
28
|
-
class AcquireNeedLoginRequest:
|
|
29
|
-
limit: int = 20
|
|
30
|
-
lock_minutes: int = 30
|
|
31
|
-
|
|
32
|
-
@dataclass
|
|
33
|
-
class AcquireUnhardenedRequest:
|
|
34
|
-
limit: int = 20
|
|
35
|
-
lock_minutes: int = 30
|
|
36
|
-
min_age_days: int = 0
|
|
37
|
-
|
|
38
|
-
@dataclass
|
|
39
|
-
class UpdateAuthStatusRequest:
|
|
40
|
-
auth_status: str
|
|
41
|
-
|
|
42
|
-
@dataclass
|
|
43
|
-
class UpdateSecurityHardenedRequest:
|
|
44
|
-
security_hardened: bool
|
|
45
|
-
|
|
46
|
-
@dataclass
|
|
47
|
-
class StandardResponse:
|
|
48
|
-
status: str
|
|
49
|
-
code: int
|
|
50
|
-
message: str
|
|
51
|
-
data: Any = None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_wrapper_sdk.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{robot_wrapper_sdk-0.2.6 → robot_wrapper_sdk-0.2.8}/robot_wrapper_sdk.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|