mlops-python-sdk 1.0.2__tar.gz → 1.0.4__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 (54) hide show
  1. mlops_python_sdk-1.0.4/PKG-INFO +235 -0
  2. mlops_python_sdk-1.0.4/README.md +209 -0
  3. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/connection_config.py +17 -12
  4. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/task/task.py +246 -73
  5. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/pyproject.toml +1 -1
  6. mlops_python_sdk-1.0.2/PKG-INFO +0 -254
  7. mlops_python_sdk-1.0.2/README.md +0 -228
  8. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/__init__.py +0 -0
  9. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/__init__.py +0 -0
  10. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/__init__.py +0 -0
  11. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/storage/__init__.py +0 -0
  12. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/storage/get_storage_presign_download.py +0 -0
  13. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/storage/get_storage_presign_upload.py +0 -0
  14. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/tasks/__init__.py +0 -0
  15. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/tasks/cancel_task.py +0 -0
  16. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/tasks/delete_task.py +0 -0
  17. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/tasks/get_task.py +0 -0
  18. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/tasks/get_task_by_task_id.py +0 -0
  19. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/tasks/get_task_logs.py +0 -0
  20. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/tasks/list_tasks.py +0 -0
  21. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/api/tasks/submit_task.py +0 -0
  22. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/client.py +0 -0
  23. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/errors.py +0 -0
  24. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/__init__.py +0 -0
  25. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/error_response.py +0 -0
  26. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/get_storage_presign_download_response_200.py +0 -0
  27. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/get_storage_presign_upload_response_200.py +0 -0
  28. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/get_task_logs_direction.py +0 -0
  29. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/get_task_logs_log_type.py +0 -0
  30. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/job_spec.py +0 -0
  31. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/job_spec_env.py +0 -0
  32. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/job_spec_master_strategy.py +0 -0
  33. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/log_pagination.py +0 -0
  34. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/message_response.py +0 -0
  35. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task.py +0 -0
  36. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_alloc_tres_type_0.py +0 -0
  37. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_gres_detail_type_0_item.py +0 -0
  38. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_job_resources_type_0.py +0 -0
  39. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_list_response.py +0 -0
  40. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_log_entry.py +0 -0
  41. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_log_entry_log_type.py +0 -0
  42. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_logs_response.py +0 -0
  43. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_resources_type_0.py +0 -0
  44. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_status.py +0 -0
  45. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_submit_request.py +0 -0
  46. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_submit_request_environment_type_0.py +0 -0
  47. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_submit_response.py +0 -0
  48. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_tres_type_0.py +0 -0
  49. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/models/task_tres_used_type_0.py +0 -0
  50. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/py.typed +0 -0
  51. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/api/client/types.py +0 -0
  52. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/exceptions.py +0 -0
  53. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/task/__init__.py +0 -0
  54. {mlops_python_sdk-1.0.2 → mlops_python_sdk-1.0.4}/mlops/task/client.py +0 -0
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.3
2
+ Name: mlops-python-sdk
3
+ Version: 1.0.4
4
+ Summary: MLOps Python SDK for XCloud Service API
5
+ License: MIT
6
+ Author: mlops
7
+ Author-email: mlops@example.com
8
+ Requires-Python: >=3.9,<4.0
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Requires-Dist: attrs (>=23.2.0)
17
+ Requires-Dist: httpx (>=0.27.0,<1.0.0)
18
+ Requires-Dist: packaging (>=24.1)
19
+ Requires-Dist: python-dateutil (>=2.8.2)
20
+ Requires-Dist: typing-extensions (>=4.1.0)
21
+ Project-URL: Bug Tracker, https://github.com/xcloud-service/xservice/issues
22
+ Project-URL: Homepage, https://mlops.cloud/
23
+ Project-URL: Repository, https://github.com/xcloud-service/xservice
24
+ Description-Content-Type: text/markdown
25
+
26
+ # SDK
27
+
28
+ Software Development Kits for integrating with the XCloud Service API.
29
+
30
+ > [!NOTE] SDK Support
31
+ > SDKs provide type-safe, high-level interfaces for interacting with the platform API. They handle authentication, error handling, and request retries automatically.
32
+
33
+
34
+ ## Installation
35
+
36
+ The Python SDK installation.
37
+
38
+ ```bash
39
+ pip install mlops-python-sdk
40
+ ```
41
+
42
+ ### Configuration
43
+
44
+ The SDK reads configuration from environment variables by default:
45
+
46
+ - `MLOPS_API_KEY`: API key (required)
47
+ - `MLOPS_DOMAIN`: API domain, e.g. `localhost:8090` or `https://example.com`
48
+ - `MLOPS_API_PATH`: API path prefix (default: `/api/v1`)
49
+ - `MLOPS_DEBUG`: `true|false` (default: `false`)
50
+
51
+ Or configure in code:
52
+
53
+ ```python
54
+ from mlops import ConnectionConfig, Task
55
+
56
+ config = ConnectionConfig(
57
+ api_key="xck_...",
58
+ domain="https://example.com",
59
+ api_path="/api/v1",
60
+ debug=False,
61
+ )
62
+ task = Task(config=config)
63
+ ```
64
+
65
+ ## SDK Usage
66
+
67
+ ### Initialize client
68
+
69
+ ```python
70
+ from mlops import Task
71
+
72
+ task = Task() # uses environment variables by default
73
+ ```
74
+
75
+ ### Submit a GPU task
76
+
77
+ ```python
78
+ from mlops import Task
79
+
80
+ task = Task()
81
+ resp = task.submit(
82
+ name="gpu-task-from-sdk",
83
+ cluster_name="slurm-cn",
84
+ team_id=1,
85
+ image="/mnt/minio/images/01ai-registry.cn-shanghai.cr.aliyuncs.com+public+llamafactory+0.9.3.sqsh",
86
+ entry_command="llamafactory-cli train /workspace/config/test_lora.yaml",
87
+ resources={
88
+ "partition": "gpu",
89
+ "nodes": 2,
90
+ "ntasks": 2,
91
+ "cpus_per_task": 2,
92
+ "memory": "4G",
93
+ "time": "01:00:00",
94
+ "gres": "gpu:nvidia_a10:1",
95
+ "qos": "qos_xcloud",
96
+ },
97
+ file_path="/path/to/xservice.zip", # optional: .zip/.tar.gz/.tgz
98
+ )
99
+ print(resp.job_id)
100
+ ```
101
+
102
+ ### Submit a CPU task
103
+
104
+ ```python
105
+ from mlops import Task
106
+
107
+ task = Task()
108
+ resp = task.submit(
109
+ name="cpu-task-from-sdk",
110
+ cluster_name="slurm-cn",
111
+ team_id=1,
112
+ image="docker://01ai-registry.cn-shanghai.cr.aliyuncs.com/01-ai/xcs/v2/alpine:3.23.0",
113
+ entry_command="echo hello",
114
+ resources={
115
+ "partition": "cpu",
116
+ "nodes": 1,
117
+ "ntasks": 1,
118
+ "cpus_per_task": 1,
119
+ "memory": "1G",
120
+ "time": "01:00:00",
121
+ "qos": "qos_xcloud",
122
+ },
123
+ )
124
+ print(resp.job_id)
125
+ ```
126
+
127
+ ### List tasks
128
+
129
+ ```python
130
+ from mlops import Task
131
+ from mlops.api.client.models.task_status import TaskStatus
132
+
133
+ task = Task()
134
+ resp = task.list(status=TaskStatus.COMPLETED, cluster_name="slurm-cn", page=1, page_size=20)
135
+ print(len(resp.tasks or []))
136
+ ```
137
+
138
+ ### Get task details
139
+
140
+ ```python
141
+ from mlops import Task
142
+
143
+ task = Task()
144
+ task_info = task.get(task_id=12345, cluster_name="slurm-cn")
145
+ print(task_info)
146
+ ```
147
+
148
+ ### Cancel a task
149
+
150
+ ```python
151
+ from mlops import Task
152
+
153
+ task = Task()
154
+ task.cancel(task_id=12345, cluster_name="slurm-cn")
155
+ ```
156
+
157
+ ### Delete a task
158
+
159
+ ```python
160
+ from mlops import Task
161
+
162
+ task = Task()
163
+ task.delete(task_id=12345, cluster_name="slurm-cn")
164
+ ```
165
+
166
+ **Task Management Methods:**
167
+
168
+ - `submit()` - Submit a new task with container image and entry command
169
+ - `get()` - Get task details by task ID
170
+ - `list()` - List tasks with optional filters (status, cluster_name, team_id, user_id)
171
+ - `cancel()` - Cancel a running task
172
+ - `delete()` - Delete a task record
173
+
174
+ **Task Status Values:**
175
+
176
+ ```python
177
+ from mlops.api.client.models.task_status import TaskStatus
178
+
179
+ TaskStatus.PENDING # Task is pending
180
+ TaskStatus.QUEUED # Task is queued
181
+ TaskStatus.RUNNING # Task is running
182
+ TaskStatus.COMPLETED # Task completed successfully
183
+ TaskStatus.SUCCEEDED # Task succeeded
184
+ TaskStatus.FAILED # Task failed
185
+ TaskStatus.CANCELLED # Task was cancelled
186
+ TaskStatus.CREATED # Task was created
187
+ ```
188
+
189
+ **Error Handling:**
190
+
191
+ ```python
192
+ from mlops.exceptions import (
193
+ APIException,
194
+ AuthenticationException,
195
+ NotFoundException,
196
+ RateLimitException,
197
+ TimeoutException,
198
+ InvalidArgumentException,
199
+ NotEnoughSpaceException
200
+ )
201
+ from mlops import Task
202
+
203
+ task = Task()
204
+
205
+ try:
206
+ result = task.submit(
207
+ name="test",
208
+ cluster_name="slurm-cn",
209
+ image="docker://alpine:3.23.0",
210
+ entry_command="echo hello",
211
+ )
212
+ except AuthenticationException as e:
213
+ print(f"Authentication failed: {e}")
214
+ except NotFoundException as e:
215
+ print(f"Resource not found: {e}")
216
+ except APIException as e:
217
+ print(f"API error: {e}")
218
+ ```
219
+
220
+ > [!TIP] Error Handling
221
+ > SDKs automatically parse typed responses and raise structured exceptions.
222
+
223
+ ## Features
224
+
225
+ - Type-safe API clients
226
+ - Automatic authentication
227
+ - Error handling
228
+ - Typed response parsing (generated models)
229
+ - Unexpected-status guard (optional)
230
+
231
+ ## Resources
232
+
233
+ - [Python SDK Documentation](https://github.com/xcloud-service/xservice/tree/main/client/python-sdk)
234
+ - [API Reference](https://xcloud-service.com/docs/api)
235
+
@@ -0,0 +1,209 @@
1
+ # SDK
2
+
3
+ Software Development Kits for integrating with the XCloud Service API.
4
+
5
+ > [!NOTE] SDK Support
6
+ > SDKs provide type-safe, high-level interfaces for interacting with the platform API. They handle authentication, error handling, and request retries automatically.
7
+
8
+
9
+ ## Installation
10
+
11
+ The Python SDK installation.
12
+
13
+ ```bash
14
+ pip install mlops-python-sdk
15
+ ```
16
+
17
+ ### Configuration
18
+
19
+ The SDK reads configuration from environment variables by default:
20
+
21
+ - `MLOPS_API_KEY`: API key (required)
22
+ - `MLOPS_DOMAIN`: API domain, e.g. `localhost:8090` or `https://example.com`
23
+ - `MLOPS_API_PATH`: API path prefix (default: `/api/v1`)
24
+ - `MLOPS_DEBUG`: `true|false` (default: `false`)
25
+
26
+ Or configure in code:
27
+
28
+ ```python
29
+ from mlops import ConnectionConfig, Task
30
+
31
+ config = ConnectionConfig(
32
+ api_key="xck_...",
33
+ domain="https://example.com",
34
+ api_path="/api/v1",
35
+ debug=False,
36
+ )
37
+ task = Task(config=config)
38
+ ```
39
+
40
+ ## SDK Usage
41
+
42
+ ### Initialize client
43
+
44
+ ```python
45
+ from mlops import Task
46
+
47
+ task = Task() # uses environment variables by default
48
+ ```
49
+
50
+ ### Submit a GPU task
51
+
52
+ ```python
53
+ from mlops import Task
54
+
55
+ task = Task()
56
+ resp = task.submit(
57
+ name="gpu-task-from-sdk",
58
+ cluster_name="slurm-cn",
59
+ team_id=1,
60
+ image="/mnt/minio/images/01ai-registry.cn-shanghai.cr.aliyuncs.com+public+llamafactory+0.9.3.sqsh",
61
+ entry_command="llamafactory-cli train /workspace/config/test_lora.yaml",
62
+ resources={
63
+ "partition": "gpu",
64
+ "nodes": 2,
65
+ "ntasks": 2,
66
+ "cpus_per_task": 2,
67
+ "memory": "4G",
68
+ "time": "01:00:00",
69
+ "gres": "gpu:nvidia_a10:1",
70
+ "qos": "qos_xcloud",
71
+ },
72
+ file_path="/path/to/xservice.zip", # optional: .zip/.tar.gz/.tgz
73
+ )
74
+ print(resp.job_id)
75
+ ```
76
+
77
+ ### Submit a CPU task
78
+
79
+ ```python
80
+ from mlops import Task
81
+
82
+ task = Task()
83
+ resp = task.submit(
84
+ name="cpu-task-from-sdk",
85
+ cluster_name="slurm-cn",
86
+ team_id=1,
87
+ image="docker://01ai-registry.cn-shanghai.cr.aliyuncs.com/01-ai/xcs/v2/alpine:3.23.0",
88
+ entry_command="echo hello",
89
+ resources={
90
+ "partition": "cpu",
91
+ "nodes": 1,
92
+ "ntasks": 1,
93
+ "cpus_per_task": 1,
94
+ "memory": "1G",
95
+ "time": "01:00:00",
96
+ "qos": "qos_xcloud",
97
+ },
98
+ )
99
+ print(resp.job_id)
100
+ ```
101
+
102
+ ### List tasks
103
+
104
+ ```python
105
+ from mlops import Task
106
+ from mlops.api.client.models.task_status import TaskStatus
107
+
108
+ task = Task()
109
+ resp = task.list(status=TaskStatus.COMPLETED, cluster_name="slurm-cn", page=1, page_size=20)
110
+ print(len(resp.tasks or []))
111
+ ```
112
+
113
+ ### Get task details
114
+
115
+ ```python
116
+ from mlops import Task
117
+
118
+ task = Task()
119
+ task_info = task.get(task_id=12345, cluster_name="slurm-cn")
120
+ print(task_info)
121
+ ```
122
+
123
+ ### Cancel a task
124
+
125
+ ```python
126
+ from mlops import Task
127
+
128
+ task = Task()
129
+ task.cancel(task_id=12345, cluster_name="slurm-cn")
130
+ ```
131
+
132
+ ### Delete a task
133
+
134
+ ```python
135
+ from mlops import Task
136
+
137
+ task = Task()
138
+ task.delete(task_id=12345, cluster_name="slurm-cn")
139
+ ```
140
+
141
+ **Task Management Methods:**
142
+
143
+ - `submit()` - Submit a new task with container image and entry command
144
+ - `get()` - Get task details by task ID
145
+ - `list()` - List tasks with optional filters (status, cluster_name, team_id, user_id)
146
+ - `cancel()` - Cancel a running task
147
+ - `delete()` - Delete a task record
148
+
149
+ **Task Status Values:**
150
+
151
+ ```python
152
+ from mlops.api.client.models.task_status import TaskStatus
153
+
154
+ TaskStatus.PENDING # Task is pending
155
+ TaskStatus.QUEUED # Task is queued
156
+ TaskStatus.RUNNING # Task is running
157
+ TaskStatus.COMPLETED # Task completed successfully
158
+ TaskStatus.SUCCEEDED # Task succeeded
159
+ TaskStatus.FAILED # Task failed
160
+ TaskStatus.CANCELLED # Task was cancelled
161
+ TaskStatus.CREATED # Task was created
162
+ ```
163
+
164
+ **Error Handling:**
165
+
166
+ ```python
167
+ from mlops.exceptions import (
168
+ APIException,
169
+ AuthenticationException,
170
+ NotFoundException,
171
+ RateLimitException,
172
+ TimeoutException,
173
+ InvalidArgumentException,
174
+ NotEnoughSpaceException
175
+ )
176
+ from mlops import Task
177
+
178
+ task = Task()
179
+
180
+ try:
181
+ result = task.submit(
182
+ name="test",
183
+ cluster_name="slurm-cn",
184
+ image="docker://alpine:3.23.0",
185
+ entry_command="echo hello",
186
+ )
187
+ except AuthenticationException as e:
188
+ print(f"Authentication failed: {e}")
189
+ except NotFoundException as e:
190
+ print(f"Resource not found: {e}")
191
+ except APIException as e:
192
+ print(f"API error: {e}")
193
+ ```
194
+
195
+ > [!TIP] Error Handling
196
+ > SDKs automatically parse typed responses and raise structured exceptions.
197
+
198
+ ## Features
199
+
200
+ - Type-safe API clients
201
+ - Automatic authentication
202
+ - Error handling
203
+ - Typed response parsing (generated models)
204
+ - Unexpected-status guard (optional)
205
+
206
+ ## Resources
207
+
208
+ - [Python SDK Documentation](https://github.com/xcloud-service/xservice/tree/main/client/python-sdk)
209
+ - [API Reference](https://xcloud-service.com/docs/api)
@@ -66,17 +66,7 @@ class ConnectionConfig:
66
66
  self.api_path = "/" + self.api_path
67
67
 
68
68
  # Build API URL
69
- if self.debug:
70
- base_url = "http://localhost:8090"
71
- else:
72
- # If domain already includes protocol, use it as-is
73
- # Otherwise, default to http:// for backward compatibility
74
- if self.domain.startswith(("http://", "https://")):
75
- base_url = self.domain
76
- else:
77
- base_url = f"http://{self.domain}"
78
-
79
- self.api_url = f"{base_url}{self.api_path}"
69
+ self.build_api_url()
80
70
 
81
71
  @staticmethod
82
72
  def _get_request_timeout(
@@ -89,7 +79,22 @@ class ConnectionConfig:
89
79
  return request_timeout
90
80
  else:
91
81
  return default_timeout
92
-
82
+
83
+ def build_api_url(self) -> None:
84
+ if self.debug:
85
+ base_url = "http://localhost:8090"
86
+ else:
87
+ # If domain already includes protocol, use it as-is
88
+ # Otherwise, default to http:// for backward compatibility
89
+ if self.domain.startswith(("http://", "https://")):
90
+ base_url = self.domain
91
+ elif self.domain.startswith("localhost") or self.domain.startswith("127.0.0.1"):
92
+ base_url = f"http://{self.domain}"
93
+ else:
94
+ base_url = f"https://{self.domain}"
95
+
96
+ self.api_url = f"{base_url}{self.api_path}"
97
+
93
98
  def get_request_timeout(self, request_timeout: Optional[float] = None):
94
99
  return self._get_request_timeout(self.request_timeout, request_timeout)
95
100