orb-cloud-client 1.2.1__tar.gz → 1.3.0__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.
- {orb_cloud_client-1.2.1/orb_cloud_client.egg-info → orb_cloud_client-1.3.0}/PKG-INFO +3 -2
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client/client.py +18 -6
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client/example.py +69 -42
- orb_cloud_client-1.3.0/orb_cloud_client/models/__init__.py +3 -0
- orb_cloud_client-1.3.0/orb_cloud_client/models/config.py +36 -0
- orb_cloud_client-1.3.0/orb_cloud_client/models/db.py +26 -0
- orb_cloud_client-1.2.1/orb_cloud_client/models.py → orb_cloud_client-1.3.0/orb_cloud_client/models/generic.py +14 -102
- orb_cloud_client-1.3.0/orb_cloud_client/models/server.py +46 -0
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0/orb_cloud_client.egg-info}/PKG-INFO +3 -2
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client.egg-info/SOURCES.txt +6 -2
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client.egg-info/requires.txt +1 -0
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/pyproject.toml +3 -2
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/LICENSE +0 -0
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/MANIFEST.in +0 -0
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/README.md +0 -0
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client/__init__.py +0 -0
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client/example_async.py +0 -0
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client.egg-info/dependency_links.txt +0 -0
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client.egg-info/entry_points.txt +0 -0
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client.egg-info/top_level.txt +0 -0
- {orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/setup.cfg +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: orb-cloud-client
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Python client library for Orb Cloud API
|
|
5
5
|
Author-email: Orb Networks <support@orb.net>
|
|
6
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Project-URL: Documentation, https://api.orb.net/docs
|
|
8
8
|
Project-URL: Homepage, https://github.com/orbforge/orb-cloud
|
|
9
9
|
Project-URL: Repository, https://github.com/orbforge/orb-cloud
|
|
@@ -21,6 +21,7 @@ License-File: LICENSE
|
|
|
21
21
|
Requires-Dist: build>=1.2.2.post1
|
|
22
22
|
Requires-Dist: httpx>=0.24.0
|
|
23
23
|
Requires-Dist: pydantic>=2.0.0
|
|
24
|
+
Requires-Dist: twine>=6.1.0
|
|
24
25
|
Provides-Extra: dev
|
|
25
26
|
Requires-Dist: build; extra == "dev"
|
|
26
27
|
Requires-Dist: pytest; extra == "dev"
|
|
@@ -5,11 +5,7 @@ Simple HTTP client for Orb Cloud API.
|
|
|
5
5
|
import httpx
|
|
6
6
|
from typing import Dict, Any, Optional, List
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
from .models import Device, TempDatasetsRequest, Organization
|
|
10
|
-
except ImportError:
|
|
11
|
-
# Handle direct execution
|
|
12
|
-
from models import Device, TempDatasetsRequest, Organization
|
|
8
|
+
from models.generic import Device, TempDatasetsRequest, Organization
|
|
13
9
|
|
|
14
10
|
class OrbCloudClientBase(object):
|
|
15
11
|
def __init__(self, base_url: str = "https://panel.orb.net", token: Optional[str] = None):
|
|
@@ -28,6 +24,11 @@ class OrbCloudClientBase(object):
|
|
|
28
24
|
response.raise_for_status()
|
|
29
25
|
return response.json()
|
|
30
26
|
|
|
27
|
+
def _trigger_speedtest(self, response: httpx.Response) -> Dict[str, Any]:
|
|
28
|
+
"""Process the response for triggering a speedtest."""
|
|
29
|
+
response.raise_for_status()
|
|
30
|
+
return response.json()
|
|
31
|
+
|
|
31
32
|
def _get_organizations(self, response: httpx.Response) -> List[Organization]:
|
|
32
33
|
"""Get list of organizations accessible with the provided token."""
|
|
33
34
|
response.raise_for_status()
|
|
@@ -65,6 +66,12 @@ class OrbCloudClient(OrbCloudClientBase):
|
|
|
65
66
|
response = self.client.get("/api/v2/organizations")
|
|
66
67
|
return self._get_organizations(response)
|
|
67
68
|
|
|
69
|
+
def trigger_speedtest(self, device_id: str, test_type: str) -> Dict[str, Any]:
|
|
70
|
+
"""Trigger a content or top speedtest"""
|
|
71
|
+
response = self.client.post(f"/api/v2/device/{device_id}/trigger-speedtest/{test_type}")
|
|
72
|
+
return self._trigger_speedtest(response)
|
|
73
|
+
|
|
74
|
+
|
|
68
75
|
def request(self, method: str, endpoint: str, **kwargs) -> httpx.Response:
|
|
69
76
|
"""Make a raw HTTP request for any other endpoints."""
|
|
70
77
|
return self.client.request(method, endpoint, **kwargs)
|
|
@@ -102,6 +109,11 @@ class OrbCloudClientAsync(OrbCloudClientBase):
|
|
|
102
109
|
response = await self.client.get("/api/v2/organizations")
|
|
103
110
|
return self._get_organizations(response)
|
|
104
111
|
|
|
112
|
+
async def trigger_speedtest(self, device_id: str, test_type: str) -> Dict[str, Any]:
|
|
113
|
+
"""Trigger a content or top speedtest"""
|
|
114
|
+
response = await self.client.post("f/api/v2/device/{orbID}/trigger-speedtest/{testType}")
|
|
115
|
+
return self._trigger_speedtest(response)
|
|
116
|
+
|
|
105
117
|
async def request(self, method: str, endpoint: str, **kwargs) -> httpx.Response:
|
|
106
118
|
"""Make a raw async HTTP request for any other endpoints."""
|
|
107
|
-
return await self.client.request(method, endpoint, **kwargs)
|
|
119
|
+
return await self.client.request(method, endpoint, **kwargs)
|
|
@@ -17,26 +17,26 @@ from typing import Optional, List
|
|
|
17
17
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
18
18
|
|
|
19
19
|
from client import OrbCloudClient
|
|
20
|
-
from models import TempDatasetsRequest, Datasets, DataPush, Device
|
|
20
|
+
from models.generic import TempDatasetsRequest, Datasets, DataPush, Device
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def get_and_display_devices(client: OrbCloudClient, organization_id: str) -> List[Device]:
|
|
24
24
|
"""Get and display all devices for the organization."""
|
|
25
25
|
print(f"Getting devices for organization: {organization_id}")
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
try:
|
|
28
28
|
devices = client.get_organization_devices(organization_id)
|
|
29
29
|
print(f"Found {len(devices)} devices:\n")
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
for i, device in enumerate(devices, 1):
|
|
32
32
|
connection_status = "Connected" if device.is_connected.value == 1 else "Disconnected"
|
|
33
33
|
print(f"{i:2}. {device.name}")
|
|
34
34
|
print(f" orb_id: {device.orb_id}")
|
|
35
35
|
print(f" status: {connection_status}")
|
|
36
36
|
print()
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
return devices
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
except Exception as e:
|
|
41
41
|
print(f"Error getting devices: {e}")
|
|
42
42
|
return []
|
|
@@ -47,53 +47,69 @@ def select_device(devices: List[Device]) -> Optional[Device]:
|
|
|
47
47
|
if not devices:
|
|
48
48
|
print("No devices available to select from.")
|
|
49
49
|
return None
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
while True:
|
|
52
52
|
try:
|
|
53
53
|
choice = input(f"Select a device (1-{len(devices)}) or 'q' to quit: ").strip()
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
if choice.lower() == 'q':
|
|
56
56
|
print("Exiting...")
|
|
57
57
|
return None
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
device_index = int(choice) - 1
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
if 0 <= device_index < len(devices):
|
|
62
62
|
selected_device = devices[device_index]
|
|
63
63
|
print(f"Selected: {selected_device.name}")
|
|
64
64
|
return selected_device
|
|
65
65
|
else:
|
|
66
66
|
print(f"Please enter a number between 1 and {len(devices)}")
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
except ValueError:
|
|
69
69
|
print("Please enter a valid number or 'q' to quit")
|
|
70
70
|
except KeyboardInterrupt:
|
|
71
71
|
print("\nExiting...")
|
|
72
72
|
return None
|
|
73
73
|
|
|
74
|
+
def select_device_action() -> Optional[str]:
|
|
75
|
+
"""Determine the device action to perform"""
|
|
76
|
+
while True:
|
|
77
|
+
print("1) Enable temp datasets push")
|
|
78
|
+
print("2) Perform a content speed test")
|
|
79
|
+
print("3) Perform a top speed test")
|
|
80
|
+
action = input("Choose an action (1,2,3): ").strip()
|
|
81
|
+
match action:
|
|
82
|
+
case "1":
|
|
83
|
+
return "temp-dataset"
|
|
84
|
+
case "2":
|
|
85
|
+
return "speedtest-content"
|
|
86
|
+
case "3":
|
|
87
|
+
return "speedtest-top"
|
|
88
|
+
case _:
|
|
89
|
+
pass
|
|
74
90
|
|
|
75
91
|
def get_push_url() -> Optional[str]:
|
|
76
92
|
"""Get the push URL from the user."""
|
|
77
93
|
while True:
|
|
78
94
|
try:
|
|
79
95
|
url = input("\nEnter the URL to push data to (or 'q' to quit): ").strip()
|
|
80
|
-
|
|
96
|
+
|
|
81
97
|
if url.lower() == 'q':
|
|
82
98
|
print("Exiting...")
|
|
83
99
|
return None
|
|
84
|
-
|
|
100
|
+
|
|
85
101
|
if not url:
|
|
86
102
|
print("Please enter a valid URL")
|
|
87
103
|
continue
|
|
88
|
-
|
|
104
|
+
|
|
89
105
|
# Basic URL validation
|
|
90
106
|
if not (url.startswith('http://') or url.startswith('https://')):
|
|
91
107
|
print("URL should start with http:// or https://")
|
|
92
108
|
continue
|
|
93
|
-
|
|
109
|
+
|
|
94
110
|
print(f"Will push data to: {url}")
|
|
95
111
|
return url
|
|
96
|
-
|
|
112
|
+
|
|
97
113
|
except KeyboardInterrupt:
|
|
98
114
|
print("\nExiting...")
|
|
99
115
|
return None
|
|
@@ -102,7 +118,7 @@ def get_push_url() -> Optional[str]:
|
|
|
102
118
|
def configure_temp_datasets(client: OrbCloudClient, device_id: str, push_url: str) -> bool:
|
|
103
119
|
"""Configure temporary datasets for the specified device."""
|
|
104
120
|
print(f"Configuring temporary datasets for device: {device_id}")
|
|
105
|
-
|
|
121
|
+
|
|
106
122
|
# Create the temporary datasets configuration
|
|
107
123
|
temp_config = TempDatasetsRequest(
|
|
108
124
|
duration="5m", # Run for 5 minutes
|
|
@@ -118,12 +134,12 @@ def configure_temp_datasets(client: OrbCloudClient, device_id: str, push_url: st
|
|
|
118
134
|
)
|
|
119
135
|
)
|
|
120
136
|
)
|
|
121
|
-
|
|
137
|
+
|
|
122
138
|
try:
|
|
123
139
|
result = client.configure_temporary_datasets(device_id, temp_config)
|
|
124
140
|
print(f"Temporary datasets configured successfully: {result}")
|
|
125
141
|
return True
|
|
126
|
-
|
|
142
|
+
|
|
127
143
|
except Exception as e:
|
|
128
144
|
print(f"Error configuring temporary datasets: {e}")
|
|
129
145
|
return False
|
|
@@ -134,50 +150,61 @@ def main():
|
|
|
134
150
|
# Get configuration from environment variables
|
|
135
151
|
api_token = os.getenv("ORB_API_TOKEN")
|
|
136
152
|
organization_id = os.getenv("ORB_ORGANIZATION_ID")
|
|
137
|
-
|
|
153
|
+
|
|
138
154
|
if not api_token:
|
|
139
155
|
print("Error: Please set ORB_API_TOKEN environment variable")
|
|
140
156
|
sys.exit(1)
|
|
141
|
-
|
|
157
|
+
|
|
142
158
|
if not organization_id:
|
|
143
159
|
print("Error: Please set ORB_ORGANIZATION_ID environment variable")
|
|
144
160
|
sys.exit(1)
|
|
145
|
-
|
|
161
|
+
|
|
146
162
|
print("Orb Cloud API Client Example")
|
|
147
163
|
print("=" * 30)
|
|
148
|
-
|
|
164
|
+
|
|
149
165
|
# Create the client
|
|
150
166
|
with OrbCloudClient(token=api_token) as client:
|
|
151
167
|
# Step 1: Get and display all devices
|
|
152
168
|
devices = get_and_display_devices(client, organization_id)
|
|
153
|
-
|
|
169
|
+
|
|
154
170
|
if not devices:
|
|
155
171
|
print("No devices found. Exiting.")
|
|
156
172
|
sys.exit(1)
|
|
157
|
-
|
|
173
|
+
|
|
158
174
|
# Step 2: Let user select a device
|
|
159
175
|
selected_device = select_device(devices)
|
|
160
|
-
|
|
176
|
+
|
|
161
177
|
if not selected_device:
|
|
162
178
|
sys.exit(0)
|
|
163
|
-
|
|
164
|
-
# Step 3: Get the push URL from user
|
|
165
|
-
push_url = get_push_url()
|
|
166
|
-
|
|
167
|
-
if not push_url:
|
|
168
|
-
sys.exit(0)
|
|
169
|
-
|
|
170
|
-
# Step 4: Configure temporary datasets for the selected device
|
|
171
|
-
success = configure_temp_datasets(client, selected_device.orb_id, push_url)
|
|
172
|
-
|
|
173
|
-
if success:
|
|
174
|
-
print("\nExample completed successfully!")
|
|
175
|
-
print(f"Device '{selected_device.name}' is now configured to collect temporary datasets.")
|
|
176
|
-
print(f"Data will be pushed to: {push_url}")
|
|
177
|
-
else:
|
|
178
|
-
print("\nExample failed to configure temporary datasets.")
|
|
179
|
-
sys.exit(1)
|
|
180
179
|
|
|
180
|
+
# Step 3: Determine the action to perform
|
|
181
|
+
action = select_device_action()
|
|
182
|
+
|
|
183
|
+
if action == "temp-dataset":
|
|
184
|
+
# Step 4a: Get the push URL from user
|
|
185
|
+
push_url = get_push_url()
|
|
186
|
+
|
|
187
|
+
if not push_url:
|
|
188
|
+
sys.exit(0)
|
|
189
|
+
|
|
190
|
+
# Step 5: Configure temporary datasets for the selected device
|
|
191
|
+
success = configure_temp_datasets(client, selected_device.orb_id, push_url)
|
|
192
|
+
|
|
193
|
+
if success:
|
|
194
|
+
print("\nExample completed successfully!")
|
|
195
|
+
print(f"Device '{selected_device.name}' is now configured to collect temporary datasets.")
|
|
196
|
+
print(f"Data will be pushed to: {push_url}")
|
|
197
|
+
else:
|
|
198
|
+
print("\nExample failed to configure temporary datasets.")
|
|
199
|
+
sys.exit(1)
|
|
200
|
+
elif "speedtest" in action:
|
|
201
|
+
# Step 4b: Trigger the selected speedtest on the device
|
|
202
|
+
test_type = action.split('-')[1]
|
|
203
|
+
try:
|
|
204
|
+
result = client.trigger_speedtest(selected_device.orb_id, test_type)
|
|
205
|
+
print(f"Triggered {test_type} speed test on device {selected_device.orb_id}")
|
|
206
|
+
except Exception as e:
|
|
207
|
+
print(f"Error triggering speed test: {e}")
|
|
181
208
|
|
|
182
209
|
if __name__ == "__main__":
|
|
183
210
|
main()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# generated by datamodel-codegen:
|
|
2
|
+
# filename: openapi.yaml
|
|
3
|
+
# timestamp: 2025-11-11T08:49:27+00:00
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DataAPI(BaseModel):
|
|
13
|
+
api_key: Optional[str] = None
|
|
14
|
+
buffer: Optional[int] = None
|
|
15
|
+
datasets: Optional[List[str]] = None
|
|
16
|
+
enabled: Optional[bool] = None
|
|
17
|
+
identifiable: Optional[bool] = None
|
|
18
|
+
port: Optional[int] = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class DataPush(BaseModel):
|
|
22
|
+
buffer_kb: Optional[int] = None
|
|
23
|
+
datasets: Optional[List[str]] = None
|
|
24
|
+
enabled: Optional[bool] = None
|
|
25
|
+
format: Optional[str] = None
|
|
26
|
+
identifiable: Optional[bool] = None
|
|
27
|
+
interval_ms: Optional[int] = None
|
|
28
|
+
url: Optional[str] = None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Datasets(BaseModel):
|
|
32
|
+
api: Optional[DataAPI] = None
|
|
33
|
+
cloud_push: Optional[DataPush] = None
|
|
34
|
+
datasets: Optional[List[str]] = None
|
|
35
|
+
enabled: Optional[bool] = None
|
|
36
|
+
push: Optional[DataPush] = None
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# generated by datamodel-codegen:
|
|
2
|
+
# filename: openapi.yaml
|
|
3
|
+
# timestamp: 2025-11-11T08:49:27+00:00
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AccountConfigEntitlements(BaseModel):
|
|
13
|
+
entitlements: Optional[List[str]] = None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AccountPlanLimits(BaseModel):
|
|
17
|
+
deployment_tokens: Optional[int] = None
|
|
18
|
+
devices: Optional[int] = None
|
|
19
|
+
users: Optional[int] = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AccountPlan(BaseModel):
|
|
23
|
+
config: Optional[AccountConfigEntitlements] = None
|
|
24
|
+
features: Optional[List[str]] = None
|
|
25
|
+
limits: Optional[AccountPlanLimits] = None
|
|
26
|
+
name: Optional[str] = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
#
|
|
1
|
+
# 20251111 This file is here for historic reasons, and backward compatibility.
|
|
2
|
+
# this can safely be removed in the future if needed. Make sure to validate the
|
|
3
|
+
# imports in other files before doing so.
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -9,6 +9,10 @@ from typing import Dict, List, Optional
|
|
|
9
9
|
|
|
10
10
|
from pydantic import BaseModel, Field
|
|
11
11
|
|
|
12
|
+
from .server import OrganizationDeviceResponse, DatasetsRequest, OrganizationsResponse as Organization
|
|
13
|
+
from .db import AccountPlan, AccountPlanLimits, AccountConfigEntitlements # noqa
|
|
14
|
+
from .config import Datasets, DataPush, DataAPI # noqa
|
|
15
|
+
|
|
12
16
|
|
|
13
17
|
class IsConnected(Enum):
|
|
14
18
|
integer_0 = 0
|
|
@@ -78,56 +82,8 @@ class OrbScore(BaseModel):
|
|
|
78
82
|
)
|
|
79
83
|
|
|
80
84
|
|
|
81
|
-
class
|
|
82
|
-
|
|
83
|
-
..., description='Whether data push is enabled', examples=[True]
|
|
84
|
-
)
|
|
85
|
-
identifiable: Optional[bool] = Field(
|
|
86
|
-
None, description='Whether data should be identifiable', examples=[True]
|
|
87
|
-
)
|
|
88
|
-
datasets: Optional[List[str]] = Field(
|
|
89
|
-
None,
|
|
90
|
-
description='List of datasets to push',
|
|
91
|
-
examples=[['responsiveness_1s', 'speed_results']],
|
|
92
|
-
)
|
|
93
|
-
url: Optional[str] = Field(
|
|
94
|
-
None,
|
|
95
|
-
description='URL to push data to',
|
|
96
|
-
examples=['https://api.example.com/data'],
|
|
97
|
-
)
|
|
98
|
-
format: Optional[str] = Field(
|
|
99
|
-
None, description='Data format for pushing', examples=['json']
|
|
100
|
-
)
|
|
101
|
-
buffer_kb: Optional[int] = Field(
|
|
102
|
-
None, description='Buffer size in KB', examples=[64]
|
|
103
|
-
)
|
|
104
|
-
interval_ms: Optional[int] = Field(
|
|
105
|
-
None, description='Push interval in milliseconds', examples=[5000]
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
class DataAPI(BaseModel):
|
|
110
|
-
enabled: bool = Field(
|
|
111
|
-
..., description='Whether data API is enabled', examples=[True]
|
|
112
|
-
)
|
|
113
|
-
identifiable: Optional[bool] = Field(
|
|
114
|
-
None, description='Whether data should be identifiable', examples=[True]
|
|
115
|
-
)
|
|
116
|
-
datasets: Optional[List[str]] = Field(
|
|
117
|
-
None,
|
|
118
|
-
description='List of datasets to expose via API',
|
|
119
|
-
examples=[['responsiveness_1s', 'speed_results']],
|
|
120
|
-
)
|
|
121
|
-
api_key: Optional[str] = Field(
|
|
122
|
-
None,
|
|
123
|
-
description='API key for accessing the data API',
|
|
124
|
-
examples=['your-api-key-here'],
|
|
125
|
-
)
|
|
126
|
-
port: Optional[int] = Field(
|
|
127
|
-
None, description='Port for the data API', examples=[8080]
|
|
128
|
-
)
|
|
129
|
-
buffer: Optional[int] = Field(None, description='Buffer size', examples=[1000])
|
|
130
|
-
|
|
85
|
+
class TriggerSpeedtestRequest(BaseModel):
|
|
86
|
+
pass
|
|
131
87
|
|
|
132
88
|
class Error(BaseModel):
|
|
133
89
|
message: str = Field(
|
|
@@ -137,43 +93,11 @@ class Error(BaseModel):
|
|
|
137
93
|
None, description='Error code', examples=['INVALID_ORG_ID']
|
|
138
94
|
)
|
|
139
95
|
|
|
140
|
-
|
|
141
|
-
class AccountConfigEntitlements(BaseModel):
|
|
142
|
-
entitlements: Optional[List[str]] = None
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
class AccountPlanLimits(BaseModel):
|
|
146
|
-
deployment_tokens: Optional[int] = None
|
|
147
|
-
devices: Optional[int] = None
|
|
148
|
-
users: Optional[int] = None
|
|
149
|
-
|
|
150
|
-
|
|
151
96
|
class SummaryTags(BaseModel):
|
|
152
97
|
geoip: Optional[GeoIPInfo] = None
|
|
153
98
|
device_info: Optional[DeviceInfo] = None
|
|
154
99
|
network_interface: Optional[NetworkInterface] = None
|
|
155
100
|
|
|
156
|
-
|
|
157
|
-
class Datasets(BaseModel):
|
|
158
|
-
enabled: bool = Field(
|
|
159
|
-
..., description='Whether datasets are enabled', examples=[True]
|
|
160
|
-
)
|
|
161
|
-
datasets: Optional[List[str]] = Field(
|
|
162
|
-
None,
|
|
163
|
-
description='List of datasets to collect',
|
|
164
|
-
examples=[['responsiveness_1s', 'speed_results']],
|
|
165
|
-
)
|
|
166
|
-
cloud_push: Optional[DataPush] = None
|
|
167
|
-
push: Optional[DataPush] = None
|
|
168
|
-
api: Optional[DataAPI] = None
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
class AccountPlan(BaseModel):
|
|
172
|
-
config: Optional[AccountConfigEntitlements] = None
|
|
173
|
-
features: Optional[List[str]] = None
|
|
174
|
-
limits: Optional[AccountPlanLimits] = None
|
|
175
|
-
|
|
176
|
-
|
|
177
101
|
class DeviceSummary(BaseModel):
|
|
178
102
|
tags: Optional[SummaryTags] = None
|
|
179
103
|
version: Optional[str] = Field(
|
|
@@ -187,23 +111,12 @@ class DeviceSummary(BaseModel):
|
|
|
187
111
|
None, description='Array of Orb scores for different time windows'
|
|
188
112
|
)
|
|
189
113
|
|
|
114
|
+
class TempDatasetsRequest(DatasetsRequest):
|
|
115
|
+
duration: str = Field(
|
|
116
|
+
..., description='Duration for temporary dataset configuration', examples=['1h']
|
|
117
|
+
)
|
|
190
118
|
|
|
191
|
-
class
|
|
192
|
-
duration: str = Field(
|
|
193
|
-
..., description='Duration for temporary dataset configuration', examples=['1h']
|
|
194
|
-
)
|
|
195
|
-
datasets_config: Datasets
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
class Organization(BaseModel):
|
|
199
|
-
customer_id: Optional[str] = None
|
|
200
|
-
name: Optional[str] = None
|
|
201
|
-
organization_id: Optional[str] = None
|
|
202
|
-
plan: Optional[AccountPlan] = None
|
|
203
|
-
subscription_id: Optional[str] = None
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
class Device(BaseModel):
|
|
119
|
+
class Device(OrganizationDeviceResponse):
|
|
207
120
|
orb_id: str = Field(
|
|
208
121
|
...,
|
|
209
122
|
description='Unique Orb device identifier',
|
|
@@ -241,5 +154,4 @@ class Device(BaseModel):
|
|
|
241
154
|
],
|
|
242
155
|
)
|
|
243
156
|
|
|
244
|
-
|
|
245
157
|
OrbScore.model_rebuild()
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# generated by datamodel-codegen:
|
|
2
|
+
# filename: openapi.yaml
|
|
3
|
+
# timestamp: 2025-11-11T08:49:27+00:00
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Any, Dict, Optional
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
from . import config as config_1
|
|
12
|
+
from . import db
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class OrganizationDeviceResponse(BaseModel):
|
|
16
|
+
can_notify: Optional[bool] = None
|
|
17
|
+
config: Optional[Dict[str, Any]] = Field(
|
|
18
|
+
None, description='device configuration, if available'
|
|
19
|
+
)
|
|
20
|
+
configuration_id: Optional[str] = Field(
|
|
21
|
+
None, description='device configuration ID, if available'
|
|
22
|
+
)
|
|
23
|
+
is_connected: Optional[int] = None
|
|
24
|
+
is_connected_updated_at: Optional[str] = None
|
|
25
|
+
name: Optional[str] = None
|
|
26
|
+
orb_id: Optional[str] = None
|
|
27
|
+
summary: Optional[Dict[str, Any]] = Field(
|
|
28
|
+
None, description='last received summary from the device'
|
|
29
|
+
)
|
|
30
|
+
tags: Optional[Dict[str, Any]] = Field(
|
|
31
|
+
None, description='list of tags associated with the device'
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class DatasetsRequest(BaseModel):
|
|
36
|
+
datasets_config: Optional[config_1.Datasets] = None
|
|
37
|
+
duration: Optional[str] = None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class OrganizationsResponse(BaseModel):
|
|
41
|
+
customer_id: Optional[str] = None
|
|
42
|
+
name: Optional[str] = None
|
|
43
|
+
organization_id: Optional[str] = None
|
|
44
|
+
plan: Optional[db.AccountPlan] = None
|
|
45
|
+
subscription_id: Optional[str] = None
|
|
46
|
+
usage: Optional[db.AccountPlanLimits] = None
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: orb-cloud-client
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Python client library for Orb Cloud API
|
|
5
5
|
Author-email: Orb Networks <support@orb.net>
|
|
6
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Project-URL: Documentation, https://api.orb.net/docs
|
|
8
8
|
Project-URL: Homepage, https://github.com/orbforge/orb-cloud
|
|
9
9
|
Project-URL: Repository, https://github.com/orbforge/orb-cloud
|
|
@@ -21,6 +21,7 @@ License-File: LICENSE
|
|
|
21
21
|
Requires-Dist: build>=1.2.2.post1
|
|
22
22
|
Requires-Dist: httpx>=0.24.0
|
|
23
23
|
Requires-Dist: pydantic>=2.0.0
|
|
24
|
+
Requires-Dist: twine>=6.1.0
|
|
24
25
|
Provides-Extra: dev
|
|
25
26
|
Requires-Dist: build; extra == "dev"
|
|
26
27
|
Requires-Dist: pytest; extra == "dev"
|
|
@@ -6,10 +6,14 @@ orb_cloud_client/__init__.py
|
|
|
6
6
|
orb_cloud_client/client.py
|
|
7
7
|
orb_cloud_client/example.py
|
|
8
8
|
orb_cloud_client/example_async.py
|
|
9
|
-
orb_cloud_client/models.py
|
|
10
9
|
orb_cloud_client.egg-info/PKG-INFO
|
|
11
10
|
orb_cloud_client.egg-info/SOURCES.txt
|
|
12
11
|
orb_cloud_client.egg-info/dependency_links.txt
|
|
13
12
|
orb_cloud_client.egg-info/entry_points.txt
|
|
14
13
|
orb_cloud_client.egg-info/requires.txt
|
|
15
|
-
orb_cloud_client.egg-info/top_level.txt
|
|
14
|
+
orb_cloud_client.egg-info/top_level.txt
|
|
15
|
+
orb_cloud_client/models/__init__.py
|
|
16
|
+
orb_cloud_client/models/config.py
|
|
17
|
+
orb_cloud_client/models/db.py
|
|
18
|
+
orb_cloud_client/models/generic.py
|
|
19
|
+
orb_cloud_client/models/server.py
|
|
@@ -20,13 +20,14 @@ dependencies = [
|
|
|
20
20
|
"build>=1.2.2.post1",
|
|
21
21
|
"httpx>=0.24.0",
|
|
22
22
|
"pydantic>=2.0.0",
|
|
23
|
+
"twine>=6.1.0",
|
|
23
24
|
]
|
|
24
25
|
description = "Python client library for Orb Cloud API"
|
|
25
|
-
license =
|
|
26
|
+
license = "MIT"
|
|
26
27
|
name = "orb-cloud-client"
|
|
27
28
|
readme = "README.md"
|
|
28
29
|
requires-python = ">=3.8"
|
|
29
|
-
version = "1.
|
|
30
|
+
version = "1.3.0"
|
|
30
31
|
|
|
31
32
|
[project.optional-dependencies]
|
|
32
33
|
dev = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{orb_cloud_client-1.2.1 → orb_cloud_client-1.3.0}/orb_cloud_client.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|