gmicloud 0.1.0__tar.gz → 0.1.2__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 (37) hide show
  1. gmicloud-0.1.2/PKG-INFO +212 -0
  2. gmicloud-0.1.2/README.md +200 -0
  3. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/__init__.py +4 -4
  4. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_client/_artifact_client.py +6 -8
  5. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_client/_http_client.py +0 -16
  6. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_client/_task_client.py +2 -2
  7. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_enums.py +2 -0
  8. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_manager/_artifact_manager.py +7 -9
  9. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_manager/_task_manager.py +0 -2
  10. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_models.py +20 -6
  11. gmicloud-0.1.2/gmicloud/client.py +122 -0
  12. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/tests/test_artifacts.py +1 -1
  13. gmicloud-0.1.2/gmicloud/utils/uninstall_packages.py +39 -0
  14. gmicloud-0.1.2/gmicloud.egg-info/PKG-INFO +212 -0
  15. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud.egg-info/SOURCES.txt +2 -3
  16. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud.egg-info/top_level.txt +0 -1
  17. {gmicloud-0.1.0 → gmicloud-0.1.2}/pyproject.toml +1 -5
  18. gmicloud-0.1.0/PKG-INFO +0 -208
  19. gmicloud-0.1.0/README.md +0 -191
  20. gmicloud-0.1.0/examples/example.py +0 -145
  21. gmicloud-0.1.0/gmicloud/client.py +0 -51
  22. gmicloud-0.1.0/gmicloud.egg-info/PKG-INFO +0 -208
  23. gmicloud-0.1.0/setup.py +0 -28
  24. {gmicloud-0.1.0 → gmicloud-0.1.2}/examples/__init__.py +0 -0
  25. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/__init__.py +0 -0
  26. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_client/__init__.py +0 -0
  27. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_client/_decorator.py +0 -0
  28. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_client/_file_upload_client.py +0 -0
  29. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_client/_iam_client.py +0 -0
  30. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_config.py +0 -0
  31. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_constants.py +0 -0
  32. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_exceptions.py +0 -0
  33. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/_internal/_manager/__init__.py +0 -0
  34. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/tests/__init__.py +0 -0
  35. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud/tests/test_tasks.py +0 -0
  36. {gmicloud-0.1.0 → gmicloud-0.1.2}/gmicloud.egg-info/dependency_links.txt +0 -0
  37. {gmicloud-0.1.0 → gmicloud-0.1.2}/setup.cfg +0 -0
@@ -0,0 +1,212 @@
1
+ Metadata-Version: 2.2
2
+ Name: gmicloud
3
+ Version: 0.1.2
4
+ Summary: GMI Cloud Python SDK
5
+ Author-email: GMI <gmi@gmitec.net>
6
+ License: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.6
11
+ Description-Content-Type: text/markdown
12
+
13
+ # GMICloud SDK
14
+
15
+ ## Overview
16
+
17
+ The GMI Inference Engine SDK provides a Python interface for deploying and managing machine learning models in
18
+ production environments. It allows users to create model artifacts, schedule tasks for serving models, and call
19
+ inference APIs easily.
20
+
21
+ This SDK streamlines the process of utilizing GMI Cloud capabilities such as deploying models with Kubernetes-based Ray
22
+ services, managing resources automatically, and accessing model inference endpoints. With minimal setup, developers can
23
+ focus on building ML solutions instead of infrastructure.
24
+
25
+ ## Features
26
+
27
+ - Artifact Management: Easily create, update, and manage ML model artifacts.
28
+ - Task Management: Quickly create, schedule, and manage deployment tasks for model inference.
29
+ - Usage Data Retrieval : Fetch and analyze usage data to optimize resource allocation.
30
+
31
+ ## Installation
32
+
33
+ To install the SDK, use pip:
34
+
35
+ ```bash
36
+ pip install gmicloud
37
+ ```
38
+
39
+ ## Setup
40
+
41
+ You must configure authentication credentials for accessing the GMI Cloud API. There are two ways to configure the SDK:
42
+
43
+ ### Option 1: Using Environment Variables
44
+
45
+ Set the following environment variables:
46
+
47
+ ```shell
48
+ export GMI_CLOUD_CLIENT_ID=<YOUR_CLIENT_ID>
49
+ export GMI_CLOUD_EMAIL=<YOUR_EMAIL>
50
+ export GMI_CLOUD_PASSWORD=<YOUR_PASSWORD>
51
+ ```
52
+
53
+ ### Option 2: Passing Credentials as Parameters
54
+
55
+ Pass `client_id`, `email`, and `password` directly to the Client object when initializing it in your script:
56
+
57
+ ```python
58
+ from gmicloud import Client
59
+
60
+ client = Client(client_id="<YOUR_CLIENT_ID>", email="<YOUR_EMAIL>", password="<YOUR_PASSWORD>")
61
+ ```
62
+
63
+ ## Quick Start
64
+
65
+ ### 1. Create a Task from an Artifact Template
66
+
67
+ This is the simplest example to deploy an existing artifact template:
68
+
69
+ ```python
70
+ from datetime import datetime
71
+ from gmicloud import Client, TaskScheduling, OneOffScheduling
72
+ from examples.completion import call_chat_completion
73
+
74
+ # Initialize the client
75
+ client = Client()
76
+
77
+ # Schedule and start a task from an artifact template
78
+ task = client.create_task_from_artifact_template(
79
+ "qwen_2.5_14b_instruct_template_001",
80
+ TaskScheduling(
81
+ scheduling_oneoff=OneOffScheduling(
82
+ trigger_timestamp=int(datetime.now().timestamp()) + 10, # Delay by 10 seconds
83
+ min_replicas=1,
84
+ max_replicas=10,
85
+ )
86
+ )
87
+ )
88
+
89
+ # Make a chat completion request via the task endpoint
90
+ response = call_chat_completion(client, task.task_id)
91
+ print(response)
92
+ ```
93
+
94
+ ### 2. Step-by-Step Example: Create Artifact, Task, and Query the Endpoint
95
+
96
+ #### (a) Create an Artifact from a Template
97
+
98
+ First, you’ll retrieve all templates and create an artifact based on the desired template (e.g., "Llama3.1 8B"):
99
+
100
+ ```python
101
+ def create_artifact_from_template(client):
102
+ artifact_manager = client.artifact_manager
103
+
104
+ # List all available templates
105
+ templates = artifact_manager.get_artifact_templates()
106
+ for template in templates:
107
+ if template.artifact_template_id == "qwen_2.5_14b_instruct_template_001":
108
+ return artifact_manager.create_artifact_from_template(
109
+ artifact_template_id=template.artifact_template_id
110
+ )
111
+ return None
112
+ ```
113
+
114
+ #### (b) Create a Task from the Artifact
115
+
116
+ Wait until the artifact becomes "ready" and then deploy it using task scheduling:
117
+
118
+ ```python
119
+ def create_task_and_start(client, artifact_id):
120
+ artifact_manager = client.artifact_manager
121
+
122
+ # Wait until the artifact is ready
123
+ while True:
124
+ artifact = artifact_manager.get_artifact(artifact_id)
125
+ if artifact.build_status == "SUCCESS":
126
+ break
127
+ print("Waiting for artifact to be ready...")
128
+ time.sleep(2)
129
+
130
+ # Configure and start the task
131
+ task_manager = client.task_manager
132
+ task = task_manager.create_task(Task(
133
+ config=TaskConfig(
134
+ ray_task_config=RayTaskConfig(
135
+ ray_version="2.40.0-py310-gpu",
136
+ file_path="serve",
137
+ artifact_id=artifact_id,
138
+ deployment_name="app",
139
+ replica_resource=ReplicaResource(
140
+ cpu=10,
141
+ ram_gb=100,
142
+ gpu=1,
143
+ ),
144
+ ),
145
+ task_scheduling=TaskScheduling(
146
+ scheduling_oneoff=OneOffScheduling(
147
+ trigger_timestamp=int(datetime.now().timestamp()) + 10,
148
+ min_replicas=1,
149
+ max_replicas=10,
150
+ )
151
+ ),
152
+ ),
153
+ ))
154
+
155
+ task_manager.start_task(task.task_id)
156
+ return task.task_id
157
+ ```
158
+
159
+ ### (c) Query the Model Endpoint
160
+
161
+ Once the task is running, use the endpoint for inference:
162
+
163
+ ```python
164
+ from examples.completion import call_chat_completion
165
+
166
+ client = Client()
167
+ artifact_id = create_artifact_from_template(client)
168
+ task_id = create_task_and_start(client, artifact_id)
169
+
170
+ response = call_chat_completion(client, task_id)
171
+ print(response)
172
+ ```
173
+
174
+ ## API Reference
175
+
176
+ ### Client
177
+
178
+ Represents the entry point to interact with GMI Cloud APIs.
179
+ Client(
180
+ client_id: Optional[str] = "",
181
+ email: Optional[str] = "",
182
+ password: Optional[str] = ""
183
+ )
184
+
185
+ ### Artifact Management
186
+
187
+ * get_artifact_templates(): Fetch a list of available artifact templates.
188
+ * create_artifact_from_template(template_id: str): Create a model artifact from a given template.
189
+ * get_artifact(artifact_id: str): Get details of a specific artifact.
190
+
191
+ ### Task Management
192
+
193
+ * create_task_from_artifact_template(template_id: str, scheduling: TaskScheduling): Create and schedule a task using an
194
+ artifact template.
195
+ * start_task(task_id: str): Start a task.
196
+ * get_task(task_id: str): Retrieve the status and details of a specific task.
197
+
198
+ ## Notes & Troubleshooting
199
+
200
+ Ensure Credentials are Correct: Double-check your environment variables or parameters passed into the Client object.
201
+ Artifact Status: It may take a few minutes for an artifact or task to transition to the "running" state.
202
+ Inference Endpoint Readiness: Use the task endpoint only after the task status changes to "running".
203
+ Default OpenAI Key: By default, the OpenAI API base URL is derived from the endpoint provided by GMI.
204
+
205
+ ## Contributing
206
+
207
+ We welcome contributions to enhance the SDK. Please follow these steps:
208
+
209
+ 1. Fork the repository.
210
+ 2. Create a new branch for your feature or bugfix.
211
+ 3. Commit changes with clear messages.
212
+ 4. Submit a pull request for review.
@@ -0,0 +1,200 @@
1
+ # GMICloud SDK
2
+
3
+ ## Overview
4
+
5
+ The GMI Inference Engine SDK provides a Python interface for deploying and managing machine learning models in
6
+ production environments. It allows users to create model artifacts, schedule tasks for serving models, and call
7
+ inference APIs easily.
8
+
9
+ This SDK streamlines the process of utilizing GMI Cloud capabilities such as deploying models with Kubernetes-based Ray
10
+ services, managing resources automatically, and accessing model inference endpoints. With minimal setup, developers can
11
+ focus on building ML solutions instead of infrastructure.
12
+
13
+ ## Features
14
+
15
+ - Artifact Management: Easily create, update, and manage ML model artifacts.
16
+ - Task Management: Quickly create, schedule, and manage deployment tasks for model inference.
17
+ - Usage Data Retrieval : Fetch and analyze usage data to optimize resource allocation.
18
+
19
+ ## Installation
20
+
21
+ To install the SDK, use pip:
22
+
23
+ ```bash
24
+ pip install gmicloud
25
+ ```
26
+
27
+ ## Setup
28
+
29
+ You must configure authentication credentials for accessing the GMI Cloud API. There are two ways to configure the SDK:
30
+
31
+ ### Option 1: Using Environment Variables
32
+
33
+ Set the following environment variables:
34
+
35
+ ```shell
36
+ export GMI_CLOUD_CLIENT_ID=<YOUR_CLIENT_ID>
37
+ export GMI_CLOUD_EMAIL=<YOUR_EMAIL>
38
+ export GMI_CLOUD_PASSWORD=<YOUR_PASSWORD>
39
+ ```
40
+
41
+ ### Option 2: Passing Credentials as Parameters
42
+
43
+ Pass `client_id`, `email`, and `password` directly to the Client object when initializing it in your script:
44
+
45
+ ```python
46
+ from gmicloud import Client
47
+
48
+ client = Client(client_id="<YOUR_CLIENT_ID>", email="<YOUR_EMAIL>", password="<YOUR_PASSWORD>")
49
+ ```
50
+
51
+ ## Quick Start
52
+
53
+ ### 1. Create a Task from an Artifact Template
54
+
55
+ This is the simplest example to deploy an existing artifact template:
56
+
57
+ ```python
58
+ from datetime import datetime
59
+ from gmicloud import Client, TaskScheduling, OneOffScheduling
60
+ from examples.completion import call_chat_completion
61
+
62
+ # Initialize the client
63
+ client = Client()
64
+
65
+ # Schedule and start a task from an artifact template
66
+ task = client.create_task_from_artifact_template(
67
+ "qwen_2.5_14b_instruct_template_001",
68
+ TaskScheduling(
69
+ scheduling_oneoff=OneOffScheduling(
70
+ trigger_timestamp=int(datetime.now().timestamp()) + 10, # Delay by 10 seconds
71
+ min_replicas=1,
72
+ max_replicas=10,
73
+ )
74
+ )
75
+ )
76
+
77
+ # Make a chat completion request via the task endpoint
78
+ response = call_chat_completion(client, task.task_id)
79
+ print(response)
80
+ ```
81
+
82
+ ### 2. Step-by-Step Example: Create Artifact, Task, and Query the Endpoint
83
+
84
+ #### (a) Create an Artifact from a Template
85
+
86
+ First, you’ll retrieve all templates and create an artifact based on the desired template (e.g., "Llama3.1 8B"):
87
+
88
+ ```python
89
+ def create_artifact_from_template(client):
90
+ artifact_manager = client.artifact_manager
91
+
92
+ # List all available templates
93
+ templates = artifact_manager.get_artifact_templates()
94
+ for template in templates:
95
+ if template.artifact_template_id == "qwen_2.5_14b_instruct_template_001":
96
+ return artifact_manager.create_artifact_from_template(
97
+ artifact_template_id=template.artifact_template_id
98
+ )
99
+ return None
100
+ ```
101
+
102
+ #### (b) Create a Task from the Artifact
103
+
104
+ Wait until the artifact becomes "ready" and then deploy it using task scheduling:
105
+
106
+ ```python
107
+ def create_task_and_start(client, artifact_id):
108
+ artifact_manager = client.artifact_manager
109
+
110
+ # Wait until the artifact is ready
111
+ while True:
112
+ artifact = artifact_manager.get_artifact(artifact_id)
113
+ if artifact.build_status == "SUCCESS":
114
+ break
115
+ print("Waiting for artifact to be ready...")
116
+ time.sleep(2)
117
+
118
+ # Configure and start the task
119
+ task_manager = client.task_manager
120
+ task = task_manager.create_task(Task(
121
+ config=TaskConfig(
122
+ ray_task_config=RayTaskConfig(
123
+ ray_version="2.40.0-py310-gpu",
124
+ file_path="serve",
125
+ artifact_id=artifact_id,
126
+ deployment_name="app",
127
+ replica_resource=ReplicaResource(
128
+ cpu=10,
129
+ ram_gb=100,
130
+ gpu=1,
131
+ ),
132
+ ),
133
+ task_scheduling=TaskScheduling(
134
+ scheduling_oneoff=OneOffScheduling(
135
+ trigger_timestamp=int(datetime.now().timestamp()) + 10,
136
+ min_replicas=1,
137
+ max_replicas=10,
138
+ )
139
+ ),
140
+ ),
141
+ ))
142
+
143
+ task_manager.start_task(task.task_id)
144
+ return task.task_id
145
+ ```
146
+
147
+ ### (c) Query the Model Endpoint
148
+
149
+ Once the task is running, use the endpoint for inference:
150
+
151
+ ```python
152
+ from examples.completion import call_chat_completion
153
+
154
+ client = Client()
155
+ artifact_id = create_artifact_from_template(client)
156
+ task_id = create_task_and_start(client, artifact_id)
157
+
158
+ response = call_chat_completion(client, task_id)
159
+ print(response)
160
+ ```
161
+
162
+ ## API Reference
163
+
164
+ ### Client
165
+
166
+ Represents the entry point to interact with GMI Cloud APIs.
167
+ Client(
168
+ client_id: Optional[str] = "",
169
+ email: Optional[str] = "",
170
+ password: Optional[str] = ""
171
+ )
172
+
173
+ ### Artifact Management
174
+
175
+ * get_artifact_templates(): Fetch a list of available artifact templates.
176
+ * create_artifact_from_template(template_id: str): Create a model artifact from a given template.
177
+ * get_artifact(artifact_id: str): Get details of a specific artifact.
178
+
179
+ ### Task Management
180
+
181
+ * create_task_from_artifact_template(template_id: str, scheduling: TaskScheduling): Create and schedule a task using an
182
+ artifact template.
183
+ * start_task(task_id: str): Start a task.
184
+ * get_task(task_id: str): Retrieve the status and details of a specific task.
185
+
186
+ ## Notes & Troubleshooting
187
+
188
+ Ensure Credentials are Correct: Double-check your environment variables or parameters passed into the Client object.
189
+ Artifact Status: It may take a few minutes for an artifact or task to transition to the "running" state.
190
+ Inference Endpoint Readiness: Use the task endpoint only after the task status changes to "running".
191
+ Default OpenAI Key: By default, the OpenAI API base URL is derived from the endpoint provided by GMI.
192
+
193
+ ## Contributing
194
+
195
+ We welcome contributions to enhance the SDK. Please follow these steps:
196
+
197
+ 1. Fork the repository.
198
+ 2. Create a new branch for your feature or bugfix.
199
+ 3. Commit changes with clear messages.
200
+ 4. Submit a pull request for review.
@@ -5,14 +5,14 @@ from ._internal._models import (
5
5
  Task,
6
6
  TaskOwner,
7
7
  TaskConfig,
8
- TaskInfo,
8
+ EndpointInfo,
9
9
  RayTaskConfig,
10
10
  TaskScheduling,
11
11
  ReplicaResource,
12
12
  OneOffScheduling,
13
13
  DailyScheduling,
14
14
  DailyTrigger,
15
- ArtifactTemplate
15
+ ArtifactTemplate,
16
16
  )
17
17
  from ._internal._enums import (
18
18
  BuildStatus,
@@ -28,7 +28,7 @@ __all__ = [
28
28
  "Task",
29
29
  "TaskOwner",
30
30
  "TaskConfig",
31
- "TaskInfo",
31
+ "EndpointInfo",
32
32
  "RayTaskConfig",
33
33
  "TaskScheduling",
34
34
  "ReplicaResource",
@@ -37,5 +37,5 @@ __all__ = [
37
37
  "DailyTrigger",
38
38
  "ArtifactTemplate",
39
39
  "BuildStatus",
40
- "TaskEndpointStatus"
40
+ "TaskEndpointStatus",
41
41
  ]
@@ -42,11 +42,10 @@ class ArtifactClient:
42
42
  return Artifact.model_validate(result)
43
43
 
44
44
  @handle_refresh_token
45
- def get_all_artifacts(self, user_id: str) -> List[Artifact]:
45
+ def get_all_artifacts(self) -> List[Artifact]:
46
46
  """
47
- Fetches all artifacts for a given user ID.
47
+ Fetches all artifacts.
48
48
 
49
- :param user_id: The ID of the user whose artifacts are being fetched.
50
49
  :return: A list of Artifact objects.
51
50
  :rtype: List[Artifact]
52
51
  """
@@ -54,7 +53,7 @@ class ArtifactClient:
54
53
  ACCESS_TOKEN_HEADER: self.iam_client.get_access_token(),
55
54
  CLIENT_ID_HEADER: self.iam_client.get_client_id()
56
55
  }
57
- result = self.client.get("/get_all_artifacts", custom_headers, {"user_id": user_id})
56
+ result = self.client.get("/get_all_artifacts", custom_headers)
58
57
  if not result:
59
58
  return []
60
59
  return [Artifact.model_validate(item) for item in result]
@@ -77,12 +76,11 @@ class ArtifactClient:
77
76
  return CreateArtifactResponse.model_validate(result)
78
77
 
79
78
  @handle_refresh_token
80
- def create_artifact_from_template(self,
81
- request: CreateArtifactFromTemplateRequest) -> CreateArtifactFromTemplateResponse:
79
+ def create_artifact_from_template(self, artifact_template_id: str) -> CreateArtifactFromTemplateResponse:
82
80
  """
83
81
  Creates a new artifact in the service.
84
82
 
85
- :param request: The request object containing artifact details.
83
+ :param artifact_template_id: The ID of the artifact template to use.
86
84
  :return: The response object containing the created artifact details.
87
85
  :rtype: CreateArtifactFromTemplateResponse
88
86
  """
@@ -91,7 +89,7 @@ class ArtifactClient:
91
89
  CLIENT_ID_HEADER: self.iam_client.get_client_id()
92
90
  }
93
91
  result = self.client.post("/create_artifact_from_template", custom_headers,
94
- request.model_dump())
92
+ {"artifact_template_id": artifact_template_id})
95
93
 
96
94
  return CreateArtifactFromTemplateResponse.model_validate(result)
97
95
 
@@ -39,7 +39,6 @@ class HTTPClient:
39
39
  :return: The JSON response parsed as a Python dictionary.
40
40
  :raises APIError: If the request fails or the response is invalid.
41
41
  """
42
- print("data=", data)
43
42
  url = self._prepare_url(endpoint)
44
43
  headers = {
45
44
  ACCEPT_HEADER: JSON_CONTENT_TYPE,
@@ -52,21 +51,7 @@ class HTTPClient:
52
51
 
53
52
  response = None
54
53
  try:
55
- # if method == HTTP_METHOD_POST:
56
- # response = requests.post(url, json=data, headers=headers)
57
- # elif method == HTTP_METHOD_GET:
58
- # response = requests.get(url, params=params, headers=headers)
59
- # elif method == HTTP_METHOD_PATCH:
60
- # response = requests.patch(url, data=data, headers=headers)
61
- # elif method == HTTP_METHOD_DELETE:
62
- # response = requests.delete(url, params=params, headers=headers)
63
- # else:
64
- # raise APIError(f"Unsupported HTTP method: {method}")
65
54
  response = requests.request(method, url, params=params, json=data, headers=headers)
66
- # response = method_map[method](url, json=data if method != HTTP_METHOD_GET else None,
67
- # params=params, headers=headers)
68
-
69
- print("=============", response.text)
70
55
  if response.status_code == 401:
71
56
  raise UnauthorizedError("Access token expired or invalid.")
72
57
  elif response.status_code != 200 and response.status_code != 201:
@@ -75,7 +60,6 @@ class HTTPClient:
75
60
  else:
76
61
  error_message = response.json().get('message', 'Unknown error')
77
62
  raise APIError(f"HTTP Request failed: {error_message}")
78
-
79
63
  # Raise for HTTP errors
80
64
  response.raise_for_status()
81
65
 
@@ -39,7 +39,7 @@ class TaskClient:
39
39
  return Task.model_validate(result)
40
40
 
41
41
  @handle_refresh_token
42
- def get_all_tasks(self, user_id: str) -> GetAllTasksResponse:
42
+ def get_all_tasks(self) -> GetAllTasksResponse:
43
43
  """
44
44
  Retrieves all tasks from the task service.
45
45
 
@@ -50,7 +50,7 @@ class TaskClient:
50
50
  ACCESS_TOKEN_HEADER: self.iam_client.get_access_token(),
51
51
  CLIENT_ID_HEADER: self.iam_client.get_client_id()
52
52
  }
53
- result = self.client.get("/get_tasks", custom_headers, {"user_id": user_id})
53
+ result = self.client.get("/get_tasks", custom_headers)
54
54
  if not result:
55
55
  return GetAllTasksResponse(tasks=[])
56
56
 
@@ -14,6 +14,7 @@ class BuildStatus(str, Enum):
14
14
 
15
15
 
16
16
  class TaskEndpointStatus(str, Enum):
17
+ UNKNOWN = ""
17
18
  PENDING = "pending"
18
19
  DEPLOYING = "deploying"
19
20
  SCALING = "scaling"
@@ -21,3 +22,4 @@ class TaskEndpointStatus(str, Enum):
21
22
  ARCHIVED = "archived"
22
23
  READY = "ready"
23
24
  UNREADY = "unready"
25
+ NEW = "new"
@@ -43,7 +43,7 @@ class ArtifactManager:
43
43
  :return: A list of Artifact objects associated with the user.
44
44
  :rtype: List[Artifact]
45
45
  """
46
- return self.artifact_client.get_all_artifacts(self.iam_client.get_user_id())
46
+ return self.artifact_client.get_all_artifacts()
47
47
 
48
48
  def create_artifact(
49
49
  self,
@@ -63,27 +63,25 @@ class ArtifactManager:
63
63
  if not artifact_name or not artifact_name.strip():
64
64
  raise ValueError("Artifact name is required and cannot be empty.")
65
65
 
66
- req = CreateArtifactRequest(user_id=self.iam_client.get_user_id(), artifact_name=artifact_name,
66
+ req = CreateArtifactRequest(artifact_name=artifact_name,
67
67
  artifact_description=description,
68
68
  artifact_tags=tags, )
69
69
 
70
70
  return self.artifact_client.create_artifact(req)
71
71
 
72
- def create_artifact_from_template(self, artifact_template_id: str) -> CreateArtifactFromTemplateResponse:
72
+ def create_artifact_from_template(self, artifact_template_id: str) -> str:
73
73
  """
74
74
  Create a new artifact for a user using a template.
75
75
 
76
76
  :param artifact_template_id: The ID of the template to use for the artifact.
77
- :return: A `CreateArtifactResponse` object containing information about the created artifact.
78
- :rtype: CreateArtifactResponse
77
+ :return: The `artifact_id` of the created artifact.
78
+ :rtype: str
79
+ :raises ValueError: If `artifact_template_id` is None or empty.
79
80
  """
80
81
  if not artifact_template_id or not artifact_template_id.strip():
81
82
  raise ValueError("Artifact template ID is required and cannot be empty.")
82
83
 
83
- req = CreateArtifactFromTemplateRequest(user_id=self.iam_client.get_user_id(),
84
- artifact_template_id=artifact_template_id)
85
-
86
- return self.artifact_client.create_artifact_from_template(req)
84
+ return self.artifact_client.create_artifact_from_template(artifact_template_id).artifact_id
87
85
 
88
86
  def rebuild_artifact(self, artifact_id: str) -> RebuildArtifactResponse:
89
87
  """
@@ -106,7 +106,6 @@ class TaskManager:
106
106
  self._validate_file_path(config_file_path)
107
107
 
108
108
  task = self._read_file_and_parse_task(config_file_path)
109
- print("================", task)
110
109
  task.task_id = task_id
111
110
  task.config.ray_task_config.artifact_id = artifact_id
112
111
 
@@ -213,7 +212,6 @@ class TaskManager:
213
212
  file_data = file.read()
214
213
 
215
214
  try:
216
- print("!!!!!!!!!!!1", file_data)
217
215
  task = Task.model_validate_json(file_data) # Ensure Task has a static method for model validation.
218
216
  except Exception as e:
219
217
  raise ValueError(f"Failed to parse Task from file: {file_path}. Error: {str(e)}")
@@ -66,7 +66,6 @@ class CreateArtifactRequest(BaseModel):
66
66
  """
67
67
  Request object to create a new artifact.
68
68
  """
69
- user_id: str # The user ID creating the artifact.
70
69
  artifact_name: str # The name of the artifact to create.
71
70
  artifact_description: Optional[str] = "" # Description of the artifact.
72
71
  artifact_tags: Optional[List[str]] = None # Tags for the artifact, separated by commas.
@@ -146,6 +145,20 @@ class ArtifactTemplate(BaseModel):
146
145
  artifact_description: Optional[str] = "" # Description of the artifact template.
147
146
  artifact_name: Optional[str] = "" # Name of the artifact template.
148
147
  artifact_tags: Optional[List[str]] = None # Tags associated with the artifact template.
148
+ ray: Optional["RayTemplate"] = None # Template for Ray-based artifacts.
149
+ resources: Optional["ResourcesTemplate"] = None # Resource allocation template.
150
+
151
+
152
+ class RayTemplate(BaseModel):
153
+ deployment_name: Optional[str] = "" # Name of the deployment.
154
+ file_path: Optional[str] = "" # Path to the task file in storage.
155
+ version: Optional[str] = "" # Version of Ray used.
156
+
157
+
158
+ class ResourcesTemplate(BaseModel):
159
+ cpu: Optional[int] = 0 # Number of CPU cores allocated.
160
+ memory: Optional[int] = 0 # Amount of RAM (in GB) allocated.
161
+ gpu: Optional[int] = 0 # Number of GPUs allocated.
149
162
 
150
163
 
151
164
  class CreateArtifactFromTemplateRequest(BaseModel):
@@ -203,7 +216,7 @@ class RayTaskConfig(BaseModel):
203
216
  file_path: Optional[str] = "" # Path to the task file in storage.
204
217
  deployment_name: Optional[str] = "" # Name of the deployment.
205
218
  replica_resource: Optional[ReplicaResource] = None # Resources allocated for task replicas.
206
- volume_mounts: Optional[VolumeMount] = None # Configuration for mounted volumes.
219
+ volume_mounts: Optional[List[VolumeMount]] = None # Configuration for mounted volumes.
207
220
 
208
221
 
209
222
  class OneOffScheduling(BaseModel):
@@ -252,12 +265,12 @@ class TaskConfig(BaseModel):
252
265
  last_update_timestamp: Optional[int] = 0 # Timestamp when the task was last updated.
253
266
 
254
267
 
255
- class TaskInfo(BaseModel):
268
+ class EndpointInfo(BaseModel):
256
269
  """
257
- Additional information about a task.
270
+ Additional information about the task endpoint.
258
271
  """
259
272
  endpoint_status: Optional[TaskEndpointStatus] = None # Current status of the task (e.g., running, stopped).
260
- endpoint: Optional[str] = "" # API endpoint exposed by the task, if applicable.
273
+ endpoint_url: Optional[str] = "" # URL for accessing the task endpoint.
261
274
 
262
275
 
263
276
  class UserPreference(BaseModel):
@@ -275,7 +288,8 @@ class Task(BaseModel):
275
288
  task_id: Optional[str] = None # Unique identifier for the task.
276
289
  owner: Optional[TaskOwner] = None # Ownership information of the task.
277
290
  config: Optional[TaskConfig] = None # Configuration data for the task.
278
- info: Optional[TaskInfo] = None # Additional information about the task.
291
+ endpoint_info: Optional[EndpointInfo] = None # Additional information about the task endpoint.
292
+ cluster_endpoints: Optional[List[EndpointInfo]] = None # Endpoints for the task cluster.
279
293
  task_status: Optional[str] = "" # Status of the task.
280
294
  readiness_status: Optional[str] = "" # Readiness status of the task.
281
295
  user_preference: Optional[UserPreference] = None # User preference for the task.